检测鼠标悬停在按钮上?
Detect Mouse Hover Over Button?
我有一个自己绘制的按钮,当鼠标悬停在它上面时,我想突出显示它。这是简化的代码,似乎不起作用:
case WM_DRAWITEM:
LPDRAWITEMSTRUCT pDraw = (LPDRAWITEMSTRUCT)lParam;
if(pDraw->itemState == ODS_HOTLIGHT) DrawButton(pDraw->hDC, HIcolor);
else DrawButton(pDraw->hDC, normcolor);
return 0;
DrawButton
是绘制按钮的自定义函数。这个函数的第二个参数是按钮的原色。该函数可以轻松绘制按钮。检测“项目状态”的问题。
我也尝试过使用 if(pDraw->itemState & ODS_HOTLIGHT)
。那也不行。
显然,我遗漏了一些东西。在我的搜索中,我遇到了很多答案。但是,其中 none 是在 C++ 中。
如 ODS_HOTLIGHT
值的 the description 所述:
ODS_HOTLIGHT: The item is being hot-tracked, that is, the item will be highlighted when the mouse is on the item.
因此,我想您需要先使用 TrackMouseEvent
功能才能收到此消息。
ODS_HOTLIGHT
不能被按钮使用。参见 What states are possible in a DRAWITEMSTRUCT structure?。
您可以使用 subclassing, and then use TrackMouseEvent
to get the event in SUBCLASSPROC
.
LRESULT CALLBACK Subclassproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if (uMsg == WM_MOUSEMOVE)
{
TRACKMOUSEEVENT ev = {};
ev.cbSize = sizeof(TRACKMOUSEEVENT);
ev.dwFlags = TME_HOVER | TME_LEAVE;
ev.hwndTrack = hWnd;
ev.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&ev);
}
else if (uMsg == WM_MOUSEHOVER)
{
RECT rc = {};
GetClientRect(hWnd, &rc);
HDC hdc = GetDC(hWnd);
SetDCBrushColor(hdc, RGB(255, 0, 0));
SelectObject(hdc, GetStockObject(DC_BRUSH));
RoundRect(hdc, rc.left, rc.top,
rc.right, rc.bottom, 0, 0);
}
else if (uMsg == WM_MOUSELEAVE)
{
RECT rc = {};
GetClientRect(hWnd, &rc);
HDC hdc = GetDC(hWnd);
SetDCBrushColor(hdc, RGB(0, 255, 0));
SelectObject(hdc, GetStockObject(DC_BRUSH));
RoundRect(hdc, rc.left, rc.top,
rc.right, rc.bottom, 0, 0);
TRACKMOUSEEVENT ev = {};
ev.cbSize = sizeof(TRACKMOUSEEVENT);
ev.dwFlags = TME_HOVER | TME_LEAVE | TME_CANCEL;
ev.hwndTrack = hWnd;
ev.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&ev);
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
...
HWND hButton = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE |
BS_OWNERDRAW, 10, 10, 60, 30, hWnd,
(HMENU)10001, hInst, NULL);
SetWindowSubclass(hButton, Subclassproc, 101, 0);
我有一个自己绘制的按钮,当鼠标悬停在它上面时,我想突出显示它。这是简化的代码,似乎不起作用:
case WM_DRAWITEM:
LPDRAWITEMSTRUCT pDraw = (LPDRAWITEMSTRUCT)lParam;
if(pDraw->itemState == ODS_HOTLIGHT) DrawButton(pDraw->hDC, HIcolor);
else DrawButton(pDraw->hDC, normcolor);
return 0;
DrawButton
是绘制按钮的自定义函数。这个函数的第二个参数是按钮的原色。该函数可以轻松绘制按钮。检测“项目状态”的问题。
我也尝试过使用 if(pDraw->itemState & ODS_HOTLIGHT)
。那也不行。
显然,我遗漏了一些东西。在我的搜索中,我遇到了很多答案。但是,其中 none 是在 C++ 中。
如 ODS_HOTLIGHT
值的 the description 所述:
ODS_HOTLIGHT: The item is being hot-tracked, that is, the item will be highlighted when the mouse is on the item.
因此,我想您需要先使用 TrackMouseEvent
功能才能收到此消息。
ODS_HOTLIGHT
不能被按钮使用。参见 What states are possible in a DRAWITEMSTRUCT structure?。
您可以使用 subclassing, and then use TrackMouseEvent
to get the event in SUBCLASSPROC
.
LRESULT CALLBACK Subclassproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if (uMsg == WM_MOUSEMOVE)
{
TRACKMOUSEEVENT ev = {};
ev.cbSize = sizeof(TRACKMOUSEEVENT);
ev.dwFlags = TME_HOVER | TME_LEAVE;
ev.hwndTrack = hWnd;
ev.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&ev);
}
else if (uMsg == WM_MOUSEHOVER)
{
RECT rc = {};
GetClientRect(hWnd, &rc);
HDC hdc = GetDC(hWnd);
SetDCBrushColor(hdc, RGB(255, 0, 0));
SelectObject(hdc, GetStockObject(DC_BRUSH));
RoundRect(hdc, rc.left, rc.top,
rc.right, rc.bottom, 0, 0);
}
else if (uMsg == WM_MOUSELEAVE)
{
RECT rc = {};
GetClientRect(hWnd, &rc);
HDC hdc = GetDC(hWnd);
SetDCBrushColor(hdc, RGB(0, 255, 0));
SelectObject(hdc, GetStockObject(DC_BRUSH));
RoundRect(hdc, rc.left, rc.top,
rc.right, rc.bottom, 0, 0);
TRACKMOUSEEVENT ev = {};
ev.cbSize = sizeof(TRACKMOUSEEVENT);
ev.dwFlags = TME_HOVER | TME_LEAVE | TME_CANCEL;
ev.hwndTrack = hWnd;
ev.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&ev);
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
...
HWND hButton = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE |
BS_OWNERDRAW, 10, 10, 60, 30, hWnd,
(HMENU)10001, hInst, NULL);
SetWindowSubclass(hButton, Subclassproc, 101, 0);