Winapi检测按钮悬停
问题描述:
我有一个C++项目,我在其中使用Winapi开发一个带有按钮的窗口,并且我想在它被徘徊时更改按钮的文本。例如,在徘徊时将“点击我”更改为“立即点击我!”。我试过搜索,但我还没有找到任何好的方法来做到这一点。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);
}
答
假设你正在使用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);
}
答
您可以检查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
{}
}
谢谢你的回答,但你知道我该如何实现NMBCHOTITEM?据我所知,我需要包含commctrl.h,但它给了windows.h许多isues – MrDick