Winapi 检测按钮悬停

MrD*_*ick 4 c++ mouse winapi button hover

我有一个 C++ 项目,在其中使用 Winapi 开发一个带有按钮的窗口,我想在按钮悬停时更改按钮的文本。例如,悬停时将“单击我”更改为“立即单击我!”。我尝试过搜索,但没有找到任何好的方法来做到这一点。

我注意到,当用户悬停时,WM_NOTIFY会收到消息,但我不知道如何确保鼠标悬停已调用该消息。我发现我可以用来TrackMouseEvent检测悬停,但它仅限于一段时间,并且我想在每次用户悬停按钮时执行一个操作。

这是我创建按钮的方法:

HWND Button = CreateWindow("BUTTON", "Click me",
        WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_NOTIFY,
        20, 240, 120, 20,
        hwnd, (HMENU)101, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

这是我的窗口程序:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch (msg)
    {
    case WM_NOTIFY:
    {
        //??? Here is where I get a message everytime I hover the button, But I don't know any proper way to see if it has been executed by the button.
    }
    case WM_CREATE: //On Window Create
    {
        //...
    }
    case WM_COMMAND: //Command execution
    {
        //...
        break;
    }
    case WM_DESTROY: //Form Destroyed
    {
        PostQuitMessage(0);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)

tam*_*bre 6

假设您使用的是通用控件,则存在消息BCN_HOTITEMCHANGE的通知代码WM_NOTIFY。该消息包括NMBCHOTITEM结构,其中包括有关鼠标是否正在进入或离开悬停区域的信息。

这是一个例子:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_NOTIFY:
        {
            LPNMHDR header = *reinterpret_cast<LPNMHDR>(lParam);

            switch (header->code)
            {
                case BCN_HOTITEMCHANGE:
                {
                    NMBCHOTITEM* hot_item = reinterpret_cast<NMBCHOTITEM*>(lParam);

                    // Handle to the button
                    HWND button_handle = header->hwndFrom;

                    // ID of the button, if you're using resources
                    UINT_PTR button_id = header->idFrom;

                    // You can check if the mouse is entering or leaving the hover area
                    bool entering = hot_item->dwFlags & HICF_ENTERING;

                    return 0;
                }
            }

            return 0;
        }
    }

    return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)