Skip to content

在多个显示器之间切换时,界面错位并失效 #10

Description

@wavexiang

在多个显示器之间切换时,界面错位并失效,编译环境VS2015/2017都试过
显示器【1】正常
image
拖动到显示器【2】错位并失效
image

Activity

  1. simonezhang commented on May 20, 2020

    @simonezhang

    same problem

  2. LeeGaning commented on Jul 28, 2020

    @LeeGaning

    Qt 5.12.9 + Mingw,same problem

  3. LeeGaning commented on Jul 30, 2020

    @LeeGaning

    简单处理了下,跨屏幕移动时resize下,有概率失败。
    另外副屏幕通过最大化时,再最小化时恢复一定白屏(原因屏幕识别错误)。

     .../FramelessHelper/Kernels/NativeWindowHelper.cpp | 30 ++++++++++++++--------
     1 file changed, 19 insertions(+), 11 deletions(-)
    
    diff --git a/ThirdParty/FramelessHelper/Kernels/NativeWindowHelper.cpp b/ThirdParty/FramelessHelper/Kernels/NativeWindowHelper.cpp
    index 0c2cefa..b75da1f 100644
    --- a/ThirdParty/FramelessHelper/Kernels/NativeWindowHelper.cpp
    +++ b/ThirdParty/FramelessHelper/Kernels/NativeWindowHelper.cpp
    @@ -110,7 +110,13 @@ bool NativeWindowHelper::nativeEventFilter(void *msg, long *result)
             LPMINMAXINFO lpMinMaxInfo = reinterpret_cast<LPMINMAXINFO>(lParam);
     
             QRect g = d->availableGeometry();
    +        static QRect old_g = g;
             QMargins m = d->maximizedMargins();
    +        if(g != old_g) {
    +            //fix:screen swtich window size change bug
    +            old_g = g;
    +            d->window->resize(d->window->size());
    +        }
     
             lpMinMaxInfo->ptMaxPosition.x = - m.left();
             lpMinMaxInfo->ptMaxPosition.y =  - m.top();
    @@ -329,15 +335,17 @@ QMargins NativeWindowHelperPrivate::maximizedMargins() const
     
     QRect NativeWindowHelperPrivate::availableGeometry() const
     {
    -    MONITORINFO mi{0};
    -    mi.cbSize = sizeof(MONITORINFO);
    -
    -    auto hWnd = reinterpret_cast<HWND>(window->winId());
    -    auto hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
    -    if (!hMonitor || !GetMonitorInfoW(hMonitor, &mi)) {
    -        Q_ASSERT(NULL != hMonitor);
    -        return window->screen()->availableGeometry();
    -    }
    -
    -    return QRect(mi.rcWork.left, mi.rcWork.top, mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top);
    +    //fix:restore form max window,get wrong geometry size(multi screens)
    +    return window->screen()->availableGeometry();
    +
    +//    MONITORINFO mi{0};
    +//    mi.cbSize = sizeof(MONITORINFO);
    +
    +//    auto hWnd = reinterpret_cast<HWND>(window->winId());
    +//    auto hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
    +//    if (!hMonitor || !GetMonitorInfoW(hMonitor, &mi)) {
    +//        Q_ASSERT(NULL != hMonitor);
    +//        return window->screen()->availableGeometry();
    +//    }
    +//    return QRect(mi.rcWork.left, mi.rcWork.top, mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top);
     }
  4. wuxinmao2008 commented on Sep 11, 2020

    @wuxinmao2008

    已遇到同样的问题。从一个屏幕到另一个屏幕的拖动过程中,绘制的区域变小了(水平方向上大约1016个像素,垂直方向上大约3040个像素)。还不知道如何修改

  5. liyangfamily commented on Sep 28, 2020

    @liyangfamily

    同样遇到相同的问题,不知道如何修改

  6. liyangfamily commented on Sep 30, 2020

    @liyangfamily

    我尝试在nativeEventFilter函数中处理WM_MOVE消息,执行如下代码SetWindowPos(msg->hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); RedrawWindow(msg->hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
    即可解决多个显示器之间切换问题,但是程序还是会有其他问题。
    这个方法我在VS调试诊断中看到,使用这个方法CPU性能前后都是在25左右。
    感觉是歪门邪道,但是目前确实解决了我的问题,大家可以参考一下。

  7. winsoft666 commented on Oct 20, 2020

    @winsoft666

    我尝试在nativeEventFilter函数中处理WM_MOVE消息,执行如下代码SetWindowPos(msg->hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); RedrawWindow(msg->hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
    即可解决多个显示器之间切换问题,但是程序还是会有其他问题。
    这个方法我在VS调试诊断中看到,使用这个方法CPU性能前后都是在25左右。
    感觉是歪门邪道,但是目前确实解决了我的问题,大家可以参考一下。

    HOOK本就不是正道

  8. feipeng8848 commented on Feb 4, 2021

    @feipeng8848

    在多个显示器之间切换时,界面错位并失效,编译环境VS2015/2017都试过
    显示器【1】正常
    image
    拖动到显示器【2】错位并失效
    image

    按钮其实并没有失效,只是坐标没变。我在做无边框的时候用的也是nativeEventFilter拦截系统消息,出现了完全一样的问题。

  9. feipeng8848 commented on Feb 4, 2021

    @feipeng8848

    我尝试在nativeEventFilter函数中处理WM_MOVE消息,执行如下代码SetWindowPos(msg->hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); RedrawWindow(msg->hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
    即可解决多个显示器之间切换问题,但是程序还是会有其他问题。
    这个方法我在VS调试诊断中看到,使用这个方法CPU性能前后都是在25左右。
    感觉是歪门邪道,但是目前确实解决了我的问题,大家可以参考一下。

    HOOK本就不是正道

    感觉不涉及到什么正道不正道的问题,用win32开发无边框也是拦截消息的做法(msdn 的文档 https://docs.microsoft.com/en-us/windows/win32/dwm/customframe ) 更觉得这是windows系统做的不好

  10. Will-Zhu-27 commented on Aug 10, 2021

    @Will-Zhu-27

    我尝试在nativeEventFilter函数中处理WM_MOVE消息,执行如下代码SetWindowPos(msg->hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); RedrawWindow(msg->hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
    即可解决多个显示器之间切换问题,但是程序还是会有其他问题。
    这个方法我在VS调试诊断中看到,使用这个方法CPU性能前后都是在25左右。
    感觉是歪门邪道,但是目前确实解决了我的问题,大家可以参考一下。

    确实解决了,还可以精简下只设置SetWindowPos就行。

    RECT rcClient;
    GetWindowRect(msg->hwnd, &rcClient);
    SetWindowPos(msg->hwnd, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_FRAMECHANGED);
    
  11. lowbees commented on Oct 19, 2021

    @lowbees

    在构造函数添加以下代码就可以了,好像是屏幕变化的时候Qt又给窗口加上了边框导致的

    connect(window, &QWindow::screenChanged, this, [=]
    {
        auto hWnd = reinterpret_cast<HWND>(window->winId());
        SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
    });
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions