5

我試圖檢測鼠標輸入/離開消息CM_MOUSEENTERCM_MOUSELEAVE但它沒有捕捉到它。我在這裏做錯了什麼?鼠標輸入/離開消息不起作用?

type 
    TMyControl = class(TCustomControl) 
    private 
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; 
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; 
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST; 
    end; 

procedure TMyControl.CMMouseEnter(var Message: TMessage); 
begin 
    //Handle mouse entering 
    //Breakpoint never reached, procedure never called 
end; 

procedure TMyControl.CMMouseLeave(var Message: TMessage); 
begin 
    //Handle mouse leaving 
    //Breakpoint never reached, procedure never called 
end; 

procedure TMyControl.WMNCHitTest(var Message: TWMNCHitTest); 
var 
    Ch: Bool; 
begin 
    if csDesigning in ComponentState then 
    Message.Result := HTCLIENT 
    else begin 
    Ch:= False; 

    //Do checks and pass `Ch:= True;` if something changed... 

    if Ch then Invalidate; 
    end; 
end; 
+1

我的第一個評論是不使用斷點來監測這些東西。切換到調試器時,UI交互總是搞砸了。使用類似Codesite的東西將消息發送到另一個窗口,並確保在監視時不要改變焦點。 – mj2008

回答

7

我想通了,我的問題:我還使用WM_NCHITTEST,我在那裏不及格inherited;。我添加了這個,現在它工作正常。

+0

無論如何'Wm_NCHitTest'似乎是錯誤的地方。這是操作系統發送的消息,當它想知道某個點代表某個控件的哪一部分時。它甚至不意味着鼠標當前*在*那一點上。這與檢查是否有任何變化有關?也許你想'wm_MouseMove'?或者只要有事情發生變化就致電'Invalidate',所以你以後根本沒有檢查。 –

+0

這是我自己的內部檢查,它大約有30行代碼正在檢查位置以查看它是否位於有效位置 - 正是它意味着要執行的操作。我認爲這部分是無關緊要的,所以我排除了它,並用評論取而代之。 –

+0

如果你正在做的事情不是決定分配給Message.Result的值是什麼,那麼你是在錯誤的消息處理程序中執行它。另外,請注意,通過您在答案中描述的更改,只有在沒有任何更改時纔會向操作系統返回有效值。你應該考慮在函數的頂部無條件調用'inherited'。然後,您可以在檢查「ComponentState」後取消特殊分配,然後退出。 –