Winapi检测按钮悬停
Posted
技术标签:
【中文标题】Winapi检测按钮悬停【英文标题】:Winapi detect button hovering 【发布时间】: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);
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于Winapi检测按钮悬停的主要内容,如果未能解决你的问题,请参考以下文章