次のコードスニペットは奇妙に見えるかもしれませんが、別のアプリケーションとの複雑な相互作用の問題を再現するための非常に簡単な方法です。
サンプルアプリケーションには2つのフォームがあり、どちらのフォームもFormClosingイベントとFormClosedイベントを登録し、そこでDebug.WriteLineを実行するだけです。
Main関数は次のことを行います。
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form2 form2 = new Form2();
form2.Show();
Application.Run(new Form1());
}
Form2を閉じると、期待どおりにイベントを受け取ります。Form1を閉じると、アプリケーションが終了し、Form2も閉じられます。ただし、Form2のイベントは発生しません。
Form2のWndProcを上書きしました。Form2を閉じると、
15.10.2012 10:25:04 WndProc - WM_CLOSE
15.10.2012 10:25:04 OnClosing
15.10.2012 10:25:04 Form2_FormClosing
15.10.2012 10:25:04 OnClosed
15.10.2012 10:25:04 Form2_FormClosed
...
15.10.2012 10:25:04 WndProc - WM_DESTROY
...
15.10.2012 10:25:04 WndProc - WM_NCDESTROY
Form1を閉じると、Form2はWM_CLOSEを受け取りません。ただし、WM_DESTROYとWM_NCDESTROYは受信されます。
編集:この奇妙な動作を取得する別の方法は次のとおりです。プロジェクトには3つのフォームがあり、Form1とForm2にはそれぞれ次のフォームを開くためのボタンがあります。form2のボタンクリックイベントで、次の手順を実行します。
Form3 frm3 = new Form3();
frm3.Parent = null;
frm3.Show(null);
ここでも、上記のようにイベントハンドラーを登録します。form2を閉じると、アプリケーションは実行されたままになります(form1は引き続き表示されます)が、form3も閉じられ、WM_CLOSEイベントは受信されません。フォームの親と所有者の両方をすでにnullに設定していることに注意してください。
その奇妙な行動の理由は何ですか?