C :使用全局鼠标钩的窗口重新位置

c++: window re-position with global mouse hook

本文关键字:新位置 位置 窗口 全局 鼠标      更新时间:2023-10-16

我正在尝试开发桌面分隔线之类的应用程序。我使用了全局鼠标钩(低级鼠标钩),因为当将窗口拖动到特定位置后,左键向上时,窗口位于特定位置并调整大小。首先,当左键向上时,我尝试将窗口重新位置到桌面屏幕的左角。我使用setWindowpos方法重新定位和调整大小,它不正常。当我释放左键时,窗口位于特定位置,但立即返回原始位置。在调试应用程序时,它很好地进入了屏幕的左角。我不知道为什么会发生这种情况。以下是我的代码。

LRESULT CALLBACK LowLevelMouseProc(int code, WPARAM wParam, LPARAM lParam)
{
if ( code != HC_ACTION )
    return CallNextHookEx(hMouseHook, code, wParam, lParam);
switch (wParam)
{
    case WM_LBUTTONDOWN:
    {
        TRACE("Downn");
        // To get window handle from current mouse position
        ::GetCursorPos(&mouse_pos);
        hCurrentWnd = ::WindowFromPoint(mouse_pos);
        LButton_Down = true;
        Window_Drag = false;    // Initialize Window_Drag variable
        Mouse_Drag = false;
        while (hCurrentWnd != 0)
        {
            style = ::GetWindowLong(hCurrentWnd, GWL_STYLE);
            const int x = style & (WS_POPUP | WS_CHILD);
            if ((x == WS_OVERLAPPED) || (x == WS_POPUP)) break;
            // we also want to manipulate mdi childs that
            // aren't maximized
            if ((!(style & WS_MAXIMIZE)) && (::GetWindowLong(hCurrentWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)) break;
            hCurrentWnd = ::GetParent(hCurrentWnd);
        }
        if (IgnoreWindow())
        {
            return CallNextHookEx(hMouseHook, code, wParam, lParam);
        }
        // check if the alt key is pressed while a mouse button is pressed
        // and switch to the appropriate mode
        switch (wParam)
        {
            case WM_LBUTTONDOWN:
                LButton_Down = true;
                break;
            default:
                return CallNextHookEx(hMouseHook, code, wParam, lParam);
        }
        if (hCurrentWnd == 0)
        {
            return CallNextHookEx(hMouseHook, code, wParam, lParam);
        }
        HWND parent = ::GetParent(hCurrentWnd);
        // remember the window size and position 
        ::GetWindowRect(hCurrentWnd, &rDown);
        if ( ( parent ) && ( ( style & WS_POPUP ) == 0 ) )
        {
            ::ScreenToClient(parent, (POINT*)&rDown.left);
            ::ScreenToClient(parent, (POINT*)&rDown.right);
        }
        // we're getting serious - capture the mouse
        SetCapture(hCurrentWnd);
        return CallNextHookEx(hMouseHook, code, wParam, lParam);
    }
    case WM_MOUSEMOVE:
    {
        TRACE("Moven");
        if ( !LButton_Down )
        {
            return CallNextHookEx(hMouseHook, code, wParam, lParam);
        }
        else {
            Mouse_Drag = true;
            TRACE("Mouse Drag - Truen");
            ::GetWindowRect(hCurrentWnd, &rCurWdrag);
            if ((rDown.left == rCurWdrag.left) && (rDown.top == rCurWdrag.top))
            {
                Window_Drag = false;
                TRACE("Window Drag - Falsen");
            }
            else {
                Window_Drag = true;
                TRACE("Window Drag - Truen");
            }
        }
        return CallNextHookEx( hMouseHook, code, wParam, lParam) ;
    }
    case WM_LBUTTONUP:
    {
        TRACE("Upn");
        LButton_Down = false;
        if ( Window_Drag && Mouse_Drag )
        {
            Window_Drag = false;
            Mouse_Drag = false;
            ::SetWindowPos(hCurrentWnd, 0, 0, 0, 500, 500, SWP_ASYNCWINDOWPOS);
            TRACE("Window Drag - Falsen");
            TRACE("Mouse Drag - Falsen");
        }
        else
        {
            Window_Drag = false;
            Mouse_Drag = false;
            TRACE("Window Drag 1 - Falsen");
            TRACE("Mouse Drag 1 - Falsen");
        }
        ReleaseCapture();
        return CallNextHookEx(NULL, code, wParam, lParam);
    }
    default:
    {
        LButton_Down = false;
        Window_Drag = false;
        Mouse_Drag = false;
        return CallNextHookEx(hMouseHook, code, wParam, lParam);
    }
}

}

这是全局鼠标钩的一部分安装的

BOOL CMFCApplication4Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);         // Set big icon
SetIcon(m_hIcon, FALSE);        // Set small icon
// TODO: Add extra initialization here
LButton_Down = false;
Mouse_Drag = false;
Window_Drag = false;
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)LowLevelMouseProc, NULL, (DWORD)NULL);

return TRUE;  // return TRUE  unless you set the focus to a control
}

我该怎么办?

拖动窗口时,系统将消息发送到窗口。发布左鼠标按钮后,我将WM__EXITSIZEMOVE消息发送到捕获左鼠标UP事件的窗口。完成此MSG的过程后,我使用SetWindowPos方法重新定位窗口,并且效果很好。仅此而已。