2012-02-25 26 views
2

如何檢測窗體/窗口控件框右上角的關閉(X)按鈕的單擊事件?請注意,我不想了解CloseReason,FormClosing,FormClosed或類似的東西,除非它們是不可避免的。我正好 想要檢測用戶是否單擊了表單的X按鈕。謝謝。在winforms中檢測X按鈕單擊窗口

+1

你爲什麼要?如果您使系統菜單中的「關閉」菜單項與X按鈕的操作方式不同,最終會讓人感到困惑。 – hvd 2012-02-25 16:04:19

+0

任何不使用FormClosing並在其中設置e.Cancel = true的理由? – 2012-02-25 16:06:48

+0

可能的原因:表單可能被其他應用程序關閉,因此用戶必須被告知由X關閉並不會幫助,而是必須關閉該應用程序。 – Alex 2013-03-21 10:13:30

回答

7

如果你真的有很好的理由不使用FormClosing, CloseReason, ...,你可以重寫窗口過程,寫這樣的事:

protected override void WndProc(ref Message m) 
    { 
     const int WM_NCLBUTTONDOWN = 0x00A1; 
     const int HTCLOSE = 20; 

     if (m.Msg == WM_NCLBUTTONDOWN) 
     { 
      switch ((int)m.WParam) 
      { 
       case HTCLOSE: 
        Trace.WriteLine("Close Button clicked"); 
        break; 
      } 
     } 

     base.WndProc(ref m); 
    } 

的細節可以發現herehere

+0

謝謝@Yuriy。請檢查我的後續文章... – priyamtheone 2012-03-18 16:16:24

2

我知道這是舊的線程,但這裏是一個解決方案。

要獲得WM_NCLBUTTONUP工作時,不要打電話給基地的WndProc當你WM_NCLBUTTONDOWN消息:

protected override void WndProc(ref Message m) 
    { 
     const int WM_NCLBUTTONDOWN = 0x00A1; 
     const int WM_NCLBUTTONUP = 0x00A2; 
     const int HTCLOSE = 20; 

     if (m.Msg == WM_NCLBUTTONDOWN) 
     { 
      switch ((int)m.WParam) 
      { 
       case HTCLOSE: 
        // WndProc Form implementation is buggy : 
        // to receive WM_NCLBUTTONUP message, 
        // don't call WndProc. 
        break; 
       default: 
        base.WndProc(ref m); 
        break; 
      } 
     } 
     else 
     { 
      if (m.Msg == WM_NCLBUTTONUP) 
      { 
       switch ((int)m.WParam) 
       { 
        case HTCLOSE: 
         Trace.WriteLine("Close Button clicked"); 
         Close(); // Optional 
         break; 
       } 
      } 

      base.WndProc(ref m); 
     } 
    } 
+0

一個解決方案總是可以接受的,除非緊急,否則時間並不重要。這是我想要的。謝謝。 – priyamtheone 2013-11-05 15:56:33

+0

如果問題沒有太多要求,那麼我還想知道在單擊標題欄左上角時出現的窗口的「系統關閉菜單」中如何檢測到同樣的情況,同時關閉窗口ALT + F4或CTRL + F4(如果是MDI子)? – priyamtheone 2013-11-05 16:00:22