注意:这不是Scrolling the Window Under the Mouse的副本,因为我无法容忍鼠标滚轮进入光标下的任意窗口。另外,我实际上想要专注于这个特定的窗口,因为我也想要按键去那里,但只有当鼠标在窗口上时。另一个问题是对于想要鼠标滚轮输入的人来到鼠标悬停窗口,不关心焦点,并且可以容忍消息循环处理的每个窗口或控件的这种行为。
有更优雅的方法吗?我在简单的c中写了一个win32应用程序。有一个主窗口,其中包含一个子窗口。我想要的是让子窗口在鼠标光标位于该窗口的客户区域时抓取焦点,以便子窗口可以在此期间处理鼠标滚轮移动。但是一旦光标离开客户区,我希望孩子放弃焦点,并停止处理鼠标滚轮。下面的Windows过程中的代码完成了这项工作,但看起来很笨拙。当鼠标穿过子窗口边界(我假设是非客户区域)时,它会抓取焦点,并在鼠标进入客户区时立即发出WM_NCMOUSELEAVE。然后它再次抓住焦点,并保持它直到鼠标再次穿过窗口边界。理想情况下,当鼠标进入客户区时,我只想抓住一次焦点,并保持焦点直到鼠标离开客户区。有什么想法吗?
LRESULT CALLBACK DisplayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_NCHITTEST:
// Set focus to self when mouse enters display window
// client area.
// must have focus so that can see mouse wheel
// TrackMouseEvent() will generate WM_NCMOUSELEAVE when mouse exits
// Reason for checking focus first is so that won't have multiple
// calls to TrackMouseEvent()
if ((GetFocus() != hWndDisplay)) {
SetFocus(hWndDisplay);
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE | TME_NONCLIENT;
tme.hwndTrack = hWndDisplay;
TrackMouseEvent(&tme);
}
break;
case WM_NCMOUSELEAVE:
SetFocus(NULL); // give up focus
break;
case WM_MOUSEWHEEL:
debugInt = (short) HIWORD(wParam); // wheel movement in high word
debugInt = debugInt / WHEEL_DELTA;
debugInt = (short) LOWORD(lParam); // mouse x coord
debugInt = (short) HIWORD(lParam); // mouse y coord
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}