2012-09-12 31 views
2

我有一個簡單的窗體沒有邊框和幾個標籤控件(沒有什麼需要點擊)。我需要能夠允許用戶通過點擊任意位置來移動表單,所以我發現this的問題,並使用下面的代碼。Winforms - WM_NCHITEST消息點擊控制

private const int WM_NCHITTEST = 0x84; 
    private const int HTCLIENT = 0x1; 
    private const int HTCAPTION = 0x2; 

    protected override void WndProc(ref Message m) 
    { 
     switch (m.Msg) { 
      case WM_NCHITTEST: 
       base.WndProc(ref m); 

       if ((int)m.Result == HTCLIENT) { 
        m.Result = (IntPtr)HTCAPTION; 
        return; 
       } else { 
        return; 
       } 
       break; 
     } 
     base.WndProc(ref m);    
    } 

這工作得很好...對一個點。如果我點擊窗體本身的任何地方(背景),WM_NCHITTESTHTCLIENT,所以我可以按預期移動窗體。但是,如果我點擊某個標籤控件本身,則該消息有所不同,我不能說出它是什麼。

我發現this article關於WM_NCHITTEST的各種可能的值,但它們都不是我所需要的。

我意識到我可以禁用我所有的標籤控件,這將允許我點擊「打開」它們,就好像它是表單本身,但我想知道是否有更好的/不同的方式來做到這一點。

感謝您的幫助!

+0

爲什麼你不能告訴消息是什麼(IE做錯了還是隻返回你不期望的東西)? http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx記錄你可以期待的值 - 你還有其他東西嗎? –

+0

@RobP。好問題!我以爲我會進入調試模式,並嘗試查看當我點擊一個控件時的消息是什麼 - 但不幸的是,當我將鼠標懸停在窗體上時,斷點不斷被擊中。然後,我必須在visual studio中運行f5,然後將鼠標移回窗體等。我在m.Result上嘗試了debug.writeline,但它不斷打印1而沒有其他東西,不管事件實際上是什麼。 – Mansfield

+0

調試windows消息可能會非常棘手。 Spy ++是必備的工具。 http://msdn.microsoft.com/en-us/library/aa264396(v=VS.60).aspx – dkackman

回答

3

您正在覆蓋表格的WndProc,但是當光標位於標籤上時,WM_NCHITTEST消息將發送到標籤。

您可以創建自己的標籤控件,該控件源自Label並覆蓋其WndProc。對於WM_NCHITTEST,應始終返回HTTRANSPARENT。喜歡的東西:

private const int HTTRANSPARENT = -1; 

protected override void WndProc(ref Message m) 
{ 
    switch (m.Msg) 
    { 
     case WM_NCHITTEST: 
      m.Result = (IntPtr)HTTRANSPARENT; 
      return; 
    } 
    base.WndProc(ref m); 
} 

還要注意,在你的WndProc一個小bug。如果消息是WM_NCHITTEST,但該區域不是HTCLIENT,則可以調用基類兩次。

+0

我已經修復了代碼中的錯誤(或者至少我認爲我有錯誤)。我會用自定義標籤試試你的想法,並回復給你。 – Mansfield

+0

如何將-1表示爲十六進制?我嘗試了'0x - 1',但那似乎沒有工作...(無效數字)我也試過只是'-1',它沒有給出任何錯誤,但似乎不匹配'WM_NCHITTEST'。 – Mansfield

+0

我已經更新了我的答案。 – arx