問題描述:在最近的windows程序中,由於實現了winform程序點擊窗口的關閉按鈕,不直接退出程序,而是將程序最小化到托盤中,這樣當程序沒有退出之前,直接關機會導致關機不能正常進行。
問題原因:操作系統會在用戶點擊關機后,發送一個關閉的消息到當前運行的應用程序,這個消息的ID號問0x11,這樣當應用程序接受到消息后就會關閉自身,然后操作系統就可正常關閉了。但是我們在實現了上面的功能后,會在FormClosing事件中添加一段代碼,
e.Cancel = true; //最小化到托盤 NormalToMinimized();
這樣我們雖然實現了功能,但是在接受到操作系統發送來的關閉窗口的消息的時候,就不能關閉程序了。
解決方案:1.在應用程序的主窗口添加一個私有的標識,用來標識,關閉窗口的事件是由用戶點擊引起的還是由操作系統發送的小心引起的。
2.在應用程序主窗口中添加對系統消息的處理,這個處理的過程需要重寫窗口的窗口過程,也就是窗口處理操作系統消息的方法。
protected override void WndProc(ref Message m) { if (m.Msg == 0x11) { //自定義的事件觸發標識,為true時表示窗口的關閉事件是由操作系統的關機操作引起的。 isExitAppFalg = true; } base.WndProc(ref m); }
3.修改FormClosing事件的處理過程,添加一個判斷就可以了
if (!isExitAppFalg) { e.Cancel = true; //最小化到托盤 NormalToMinimized(); }
這樣就把實現功能所帶了的副作用給解決了。
補充:根據網友們的指正,我這里確實畫蛇添足了。 FormClosingEventArgs 這個類里面有一個CloseReason枚舉,枚舉的各個值
0:無法判斷
1:操作系統關閉窗口
2:多文檔頁面的父窗口在關閉
3:用戶關閉,點擊關閉按鈕或者按下alt+F4
4:任務管理器正在關閉應用程序
5:此窗口的歸屬窗口正在關閉
6 :應用程序的exit被調用
在FormClosing事件中只要判斷一下窗口是由哪一種原因關閉的就可以了;