Delphiで、×ボタンやその他の終了を区別する方法

178 views
Skip to first unread message

久世

unread,
Jul 25, 2020, 1:02:47 AM7/25/20
to radstu...@googlegroups.com

皆さん

久世です。

いつもお世話になっております。
ソフトの終了には、いくつか種類があると思います。
1.右上の×ボタンによる終了
2.アプリ内部で実装されている Closeのコマンドによる終了
3.タスクバーのアプリを右クリックをして、「閉じる」による終了
4.タスクバーのアプリを右クリックをして、「すべてを閉じる」による終了
5.タイトルバーを右クリックをして、「閉じる」による終了
6.Windows終了時に、アプリが閉じられるときの終了

これらの終了は、分けれることができないかという質問になります。
2に関しては、自ら終了しているので除外できます。
WM_SYSCOMMANDメッセージのCmdType=SC_CLOSEでは、分けることが
出来ないようです。
WM_CLOSEを組み合わせると分けることができるでしょうか?

アプリを1こずつ終了するときの処理と、複数まとめて終了されるときの処理に分類できないかと考えているのですが、

上記の例でいうと
1こずつ終了するグループ:1、2、3、5
複数個終了するグループ :4、6
現在の終了が、単独終了か否かを知りたいと思っています。
何かお知恵を貸していただけないでしょうか?

Tarou Takagi, Imageom

unread,
Jul 25, 2020, 6:38:22 PM7/25/20
to radstu...@googlegroups.com
皆さま

 こんにちは、イマジオムの高木です。 いつもお世話になっております。

久世さん:
> ソフトの終了には、いくつか種類があると思います。
> 1.右上の×ボタンによる終了
> 2.アプリ内部で実装されている Closeのコマンドによる終了
> 3.タスクバーのアプリを右クリックをして、「閉じる」による終了
> 4.タスクバーのアプリを右クリックをして、「すべてを閉じる」による終了
> 5.タイトルバーを右クリックをして、「閉じる」による終了
> 6.Windows終了時に、アプリが閉じられるときの終了
>
> これらの終了は、分けれることができないかという質問になります。
>
> アプリを1こずつ終了するときの処理と、複数まとめて終了される
> ときの処理に分類できないかと考えているのですが、
>
> 上記の例でいうと
> 1こずつ終了するグループ:1、2、3、5
> 複数個終了するグループ :4、6
> 現在の終了が、単独終了か否かを知りたいと思っています。

 Application.MainForm.OnCloseQuery イベント時点で区別できていれば
いいでしょうか?

 完全な回答ではないのですが、少なくとも6は、WM_QUERYENDSESSION
メッセージを見張ることで、他と区別することができます。

type TMainForm=
class(TForm)
constructor Create(AOwner:TComponent); override;
private
EndSession:Boolean; {<======= 6であることを示すフラグ }
protected
procedure WMQueryEndSession(var Msg:TWMQueryEndSession);
message WM_QUERYENDSESSION;
end;

constructor TMainForm.Create;
begin
inherited Create(AOwner);
EndSession:=False;
end;

procedure TMainForm.WMQueryEndSession;
begin
EndSession:=True;
inherited;
end;

 もし4・6と、それ以外を区別したいということでしたら、あとは
4を知る方法がわかればよいということになりますね。 なぜ終了
方法を区別なさりたいのかお知らせくだされば、もう少し的確なことが
言えると思います。

――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
携帯電話:090-8177-5709
電子メール:tarou_...@imageom.co.jp
ウェブサイト:http://www.imageom.co.jp/

Tarou Takagi, Imageom

unread,
Jul 26, 2020, 5:44:21 AM7/26/20
to radstu...@googlegroups.com
皆さま

 先ほど間違えて、久世さん個人に下記回答を送ってしまいました。
久世さんからの回答で全文引用していただきましたが、念のため
MLに投稿しておきます。 トラフィックを増やしてしまって
申しわけございません。

(以下、再送)
――――――――――――――――――――――――――――――――――――
 こんにちは、イマジオムの高木です。 いつもお世話になっております。
ちょっと話題が件名とずれてしまうかもしれませんが……

久世さん:
> まずは、なぜグループ分けをしたいかについてですが、自作アプリを
> 複数個同時起動し使用している場合、作業をいったん終了後再度
> その状態を復帰したいと思った場合、アプリの終了時に、現状を把握し、
> その状態の情報をファイルに書き出す必要があります。
>
> 例えば、10個アプリが起動しており、ユーザーが、まず1個を手動で
> 終了。その後、残り9個は、Windows終了により自動で終了という
> ケースの場合、次回起動時には、最後の9個の状態を復帰したいと
> いう内容です。

 話題がおもしろくなってきましたね。

 もしお書きのようなことをなさるのでしたら、お作りのアプリ(これを
「メインアプリ」と呼びます)とは別に、状態記録・復元用専用のアプリ
(これを「管理アプリ」と呼びます)を作ってはどうでしょうか?
たとえばこんな方法です。

  1.メインアプリは、起動と同時に管理アプリとの通信を試み、
    通信ができなかったら管理アプリを起動させる。

     #管理アプリに通信用のウィンドウを持たせ、その
      クラス名を決めておきます。 メインアプリからは
      FindWindow と SendMessasage でメッセージ通信を
      試みます。

  2.メインアプリにも受信用のウィンドウを持たせる。
    管理アプリは、メインアプリが起動される(通信が
    試みられる)たびに、メインアプリの受信用ウィンドウの
    ハンドルをリストに追加する(自分を起動してくれた
    メインアプリも忘れずに登録しておく)。

     #受信用ウィンドウのハンドルを、次のいずれかの方法で
      管理アプリに知らせます。
        1.SendMessage で送るメッセージの WParam 引数で
          渡す。
        2.プロセス起動時にコマンドラインパラメータと
          して渡す。

  3.管理アプリはまた、メインアプリの終了(受信用ウィンドウの
    消滅)を定期的に調べ、検知したらそのメインアプリを
    リストから外す。 リストが空になったら自分も終了する。

  4.管理アプリはフォームを表示させず、見えないように作っておく。

 この方法のメリットは、「管理アプリが、すべてのメインアプリの
終了を見届けることができる」ということです。 管理アプリ側では、
個々のメインアプリの動作状況を完全に把握することができますから、
連動起動・連動終了、実行状態の記録・復元など、やりたい放題です。
Reply all
Reply to author
Forward
0 new messages