2010-02-17 122 views
3

在我的Win32應用程序中,當我按住鼠標左鍵並快速移動鼠標指針時,我沒有收到WM_MOUSELEAVE消息。但是,如果我按住鼠標左鍵,從窗口內部開始並緩慢移動到窗口邊緣,它將生成一個WM_MOUSELEAVE。當鼠標左鍵被按住時WM_MOUSELEAVE沒有被生成

如果我沒有按住鼠標左鍵,每次無論鼠標指針離開窗口有多快,我都會收到WM_MOUSELEAVE消息。

有什麼區別?我能做些什麼來正確處理這兩種情況?

編輯:如果我離開單擊並按住,移出窗口,然後釋放鼠標左鍵我得到WM_MOUSELEAVE消息。但是太晚了。

+2

你在什麼時候調用TrackMouseEvent?可能是因爲你有延遲,並且你正在設法在'TrackMouseEvent'被調用之前離開窗口? – 2010-02-17 18:46:04

+0

當客戶端區域內有鼠標移動時,我會執行TrackMouseEvent。 – djcouchycouch 2010-02-17 19:37:39

回答

4

WM_MOUSELEAVE是這樣,你可以檢測到鼠標離開你的窗口,當你有捕獲。當你被捕獲時,你有責任檢測你自己(如果你在乎)。

因此,SetCaptureTrackMouseEvent在同一時間沒有任何意義,你可以使用一個或另一個。

現在,如果在捕獲時看到WM_MOUSELEAVE消息會更方便,在消息泵中執行該操作相對簡單。

您只需在消息泵中的GetMessage()DispatchMessage()調用之間添加類似這樣的代碼即可。

GetMessage(pmsg, ...); 

    ..... 

    if ((IS_WITHIN(pmsg->message, WM_MOUSEFIRST, WM_MOUSELAST) || 
     IS_WITHIN(pmsg->message, WM_NCMOUSEMOVE, WM_NCMBUTTONDBLCLK)) && 
     MyMouseLeaveDetection(pmsg, g_hwndNotifyMouseLeave)) 
    { 
    MSG msg = *pmsg; 
    msg.message = WM_MOUSELEAVE; 
    msg.hwnd = g_hwndNotifyMouseLeave; // window that want's 
    msg.lParam = 0xFFFFFFFF; 
    g_hwndNotifyMouseLeave = NULL; 

    DispatchMessage (&msg); 
    } 

..... 
TranslateMessage(pmsg); 
DispatchMessage(pmsg); 
-1

由於等待WM_MOUSELEAVE是不可靠的,我發現的最佳解決方案是在WM_MOUSEMOVE期間直接查看鼠標位置。我將鼠標位置與客戶區域進行比較,如果位置在外面,則我將其作爲鼠標離開。

當鼠標位於客戶區和ReleaseCapture離開時,我也確保調用SetCapture。

+0

請記住,僅當用戶在窗口內按下鼠標按鈕時,SetCapture *才起作用。你是否試圖一起使用SetCapture和TrackMouseEvent?這可以解釋你所看到的...... – Shog9 2010-02-17 20:50:12

+0

這不是一個答案!這是一個黑客。答案是最多的一個。 – CodeAngry 2014-02-13 10:16:47

5

在Windows 7上,我試圖製作一個自繪按鈕。爲了更準確地獲得更多的mouseenter/mouseleave事件,我將這個按鈕分類了下來。當我這樣做的時候,當我得到一個WM_MOUSEMOVE時,我使用了TrackMouseEvent,因爲只有當鼠標移動到按鈕上時纔會發佈。如果尚未設置,我會設置一個布爾值來指定鼠標懸停在按鈕上,並調用TrackMouseEvent,以便只要鼠標離開,我就可以取消設置布爾值。但是,像你一樣,當我按住鼠標左鍵並按住所有者繪製的按鈕,然後將鼠標拖出時,我沒有收到WM_MOUSELEAVE。在按鈕外釋放鼠標後,我突然收到WM_MOUSELEAVE消息 - 太遲了。

我確定此行爲的原因是默認按鈕proc的WM_LBUTTONDOWN處理調用SetCapture,並在稍後發佈。 SetCapture的用法是打破我們對WM_MOUSELEAVE事件的接受。但是,作爲調用SetCapture的副作用,即使控件不在鼠標下面,我們也會獲取WM_MOUSEMOVE事件。因此,我的解決方法是複製WM_MOUSEMOVE處理程序中WM_MOUSELEAVE的邏輯,以取消設置指示鼠標位於按鈕上方的布爾值,如果我得到的按鈕區域外的mousemove事件。如果在WM_LBUTTONDOWN內部沒有實際使用SetCapture作爲默認按鈕過程,那麼我們已經得到了我們的WM_MOUSELEAVE消息,並且代碼仍然可以工作......所以這種解決方法在兩種情況下都能正常工作。

你的問題聽起來像它可能與我的相同,所以希望這可以幫助你。

相關問題