下面的代碼片段可能看起來很奇怪,但它是一個非常簡單的方法來重現與其他應用程序的複雜交互問題。消失FormClosing/FormClosed事件
示例應用程序有兩種形式,兩種形式都註冊FormClosing和FormClosed事件,只是在那裏做一個Debug.WriteLine。
的主要功能作用:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form2 form2 = new Form2();
form2.Show();
Application.Run(new Form1());
}
當我關閉窗體2,我收到了事件的預期。當我關閉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。
編輯: 獲得這種奇怪行爲的不同方式如下: 該項目有三種形式,Form1和Form2每個都有一個用於打開下一個表單的按鈕。在form2的按鈕單擊事件中,執行:
Form3 frm3 = new Form3();
frm3.Parent = null;
frm3.Show(null);
再次,如上所述註冊事件處理程序。當關閉form2時,應用程序保持運行狀態(仍然顯示form1),而且form3被關閉,並且沒有收到WM_CLOSE事件。請注意,我已經將表單的Parent和Owner都設置爲null。
這種奇怪行爲的原因是什麼?
感謝這個偉大的解釋。現在我明白了爲什麼在這個例子中沒有得到消息。 –
但我們首先發現問題的環境要複雜得多。 ThirdParty定義了一個C++接口。我們在混合模式(非託管/託管)dll中實現它。當ThirdParty調用StartUp方法時,我們創建一個通信窗口(並將桌面設置爲其所有者)。 當ThirdParty關閉我們的系統加載窗口時,我們的窗口也消失 - 沒有事件。但是我們的系統保持加載狀態(即它們不卸載應用程序域)。現在我們必須找出哪些其他方式來關閉窗口而不會收到事件。 –
你可以在你的Form2上重載'WndProc',並通過調用'Close()'方法來處理'WM_DESTROY'消息。它將處理形式和資源。 –