为什么在启用窗口后会获得WM_MOUSELEAVE?

时间:2016-09-24 05:15:26

标签: c winapi

启用禁用的子窗口后,我尝试仅在WM_ENABLE鼠标光标悬停在窗口上时使用TrackMouseEvent()并将TRACKMOUSEEVENT结构的dwFlags设置为{{} {1}}。 TME_LEAVE返回TRUE,但在调用之后我收到TrackMouseEvent()消息。这仅在2个条件下发生。在第一个条件下,将光标移动到子窗口之外,按Enter键禁用窗口,然后将光标移到子窗口上并按Space键。在第二个条件下,将光标移到窗口上,按Enter键将其禁用,然后在按下Space键之前将光标移动1个像素或更多,然后按Space键。如果重新测试第二个条件,但是在按空格键之前没有移动光标,如果在按Enter键后立即按空格键,则鼠标跟踪将正确打开。我已经非常努力地解决了这个问题,但到目前为止我并不幸运。有人可以修复此代码并解释为什么我试图打开鼠标时会取消鼠标跟踪吗?

WM_MOUSELEAVE
编辑:您无法在图片中看到光标,因为我使用了屏幕截图,但它并没有捕获光标。在第一张图片中,光标位于子窗口之外,而在第二张图片中,光标位于子窗口之内

当光标位于子窗口之外时按下ENTER键 enter image description here

先前按下ENTER键并且光标悬停在子窗口上后按下SPACE键 enter image description here

1 个答案:

答案 0 :(得分:0)

我不知道这是文档的缺点还是TrackMouseEvent中的错误,但看起来TrackMouseEvent不希望在WM_ENABLE处理程序中调用。

为避免这种情况,请尝试从WM_ENABLE发布消息并从中调用TrackMouseEvent:

case WM_ENABLE:
    PostMessage(hwnd, WM_USER, wParam, lParam);
    break;
case WM_USER:
    if(wParam) 
    {
        RECT rc;
        if(GetWindowRect(hwnd, &rc))
        {
            POINT pt;
            if(GetCursorPos(&pt))
                if(PtInRect(&rc, pt)) 
                {
                    TRACKMOUSEEVENT tme = { 0 };
                    tme.cbSize    = sizeof(TRACKMOUSEEVENT);
                    tme.dwFlags   = TME_LEAVE;
                    tme.hwndTrack = hwnd;
                    //TrackMouseEvent() posts WM_MOUSELEAVE if conditions 1 and 2 are met, even though I'm trying to turn 
                    //mouse tracking on and the cursor is over the child window. It doesn't make sense
                    //The problems is this piece of code right here /* bMouseTracking = TrackMouseEvent(&tme); */
                    //It should turn tracking on but it doesn't it cancels it even though WS_DISABLED has already been removed
                    //at this point
                    bMouseTracking = TrackMouseEvent(&tme); 
                    InvalidateRect(hwnd, 0, TRUE);
                }
        }
    } else {
        if(bMouseTracking) { 
            ////////If you comment everything from here ...
            TRACKMOUSEEVENT tme = { 0 };
            tme.cbSize    = sizeof(TRACKMOUSEEVENT);
            tme.dwFlags   = TME_LEAVE | TME_CANCEL;
            tme.hwndTrack = hwnd;
            //if(TrackMouseEvent(&tme)) PostMessage(hwnd, WM_MOUSELEAVE, 0, 0); //Commented this line out to do things a bit differently with the same results  
            if(TrackMouseEvent(&tme)) { //If this succeeds it means mouse tracking was canceled
                bMouseTracking = FALSE;
                InvalidateRect(hwnd, 0, TRUE);
            }
            ////////all the way down to here the result is the same
            //If you comment everything in this block out then you have another problem which can be tested with this condition:
            //With window enabled move mouse over window, then press the ENTER key. The color should change 
            //from red to blue but it doesn't. It will change to blue though if you move the mouse 1 or more pixels after you've pressed the ENTER key
        }
    }
    break;