【问题标题】:Winapi detect button hoveringWinapi检测按钮悬停
【发布时间】:2017-12-14 14:18:14
【问题描述】:

我有一个 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);

这是我的窗口程序:

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);
}

【问题讨论】:

    标签: c++ winapi button hover mouse


    【解决方案1】:

    假设您使用的是the common controls,则WM_NOTIFY 消息的BCN_HOTITEMCHANGE 通知代码。该消息包含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);
    }
    

    【讨论】:

    • 感谢您的回答,但您知道如何实施 NMBCHOTITEM 吗?据我所知,我需要包含 commctrl.h 但它给 windows.h 带来了很多问题
    【解决方案2】:

    您可以查看WM_NOTIFY消息的代码,看看它是否是NM_HOVER消息。

    switch(msg)
    {
    case WM_NOTIFY:
        if(((LPNMHDR)lParam)->code == NM_HOVER)
        {
           // Process the hover message
        }
        else if (...) // any other WM_NOTIFY messages you care about
        {}
    }
    

    【讨论】:

      【解决方案3】:

      您可以简单地使用 SFML 来执行此操作。

      代码:

      RectangleShape button;
      button.setPosition(Vector2f(50, 50));
      button.setSize(Vector2f(100, 40));
      button.setFillColor(Color::Green);
      if(button.getGlobalBounds().contains(static_cast<Vector2f>(Mouse::getPosition(/*your 
      window name*/window)
      {
          button.setFillColor(Color::Red);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-31
        • 1970-01-01
        • 2016-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 2019-09-08
        相关资源
        最近更新 更多