捕获鼠标但未聚焦窗口时捕获键盘事件(Win32)

Capture keyboard events while mouse is captured but window not focused (Win32)

本文关键字:事件 Win32 键盘 窗口 鼠标 聚焦      更新时间:2023-10-16

我正在实现一个可以启动拖动事件的自定义控件。当用户按下鼠标左键时,我通过处理WM_LBUTTONDOWN并调用SetCapture()来启动拖动。这会导致所有鼠标事件,甚至是我控件的客户端区域之外的事件,都被发送到它,完全按照我的意愿。

我还希望能够捕捉按键,这样如果用户按下ESC键(VK_ESCAPE),我就可以取消拖动。由于我的控件没有键盘焦点(我不希望它从有键盘焦点的控件上偷走焦点),我无法收听WM_KEYDOWN。由于其他太复杂而无法解释的原因,我也不希望使用DragDetect()函数。

在拖动过程中,我的控件如何了解ESC键的按下情况?

事实证明这很容易:

// message loop...
switch (msg)
{
    // ...
    case WM_LBUTTONDOWN:
        // do some stuff
        RegisterHotKey(hwnd, 0 /* id */, 0, VK_ESCAPE);
        // do some more stuff
        break;
    // ... 
    case WM_HOTKEY:
        if (VK_ESCAPE == HIWORD(lParam) &&
            IDHOT_SNAPDESKTOP != wParam &&
            IDHOT_SNAPWINDOW != wParam)
            {
            // handle ESC keypress
            UnregisterHotKey(hwnd, 0 /* id */);
            }
        break;
    // ...
}