【问题标题】:Borderless window with Aero Snap too large in maximized stateAero Snap 的无边框窗口在最大化状态下太大
【发布时间】:2016-04-04 12:16:41
【问题描述】:

我正在尝试在 Qt5.6.0 中创建一个无边框窗口,并带有 aero-snap 功能。 一切正常,除非我最大化窗口:它太大了。

我的屏幕分辨率为2560x1440,因此窗口的大小应为2560x1400(任务栏为40 像素),但在WM_SIZE 消息中,新大小为2576x1416。 所以窗口在每个方向上都正好大了 8 个像素。 这也意味着窗口没有在左上角对齐,它在两个方向上都离屏幕正好 8 个像素。

我找不到这个问题的解决方案,我尝试过的所有方法都不起作用并导致错误。

解决此问题的唯一方法是删除 WS_CAPTIONWS_THICKFRAME 样式,但随后我失去了区域快照功能。

我必须以某种方式告诉 Qt 或 DWM 将窗口缩小 16 像素并将其向右和底部移动 8 像素。有人知道如何做到这一点吗?

【问题讨论】:

    标签: c++ qt aero borderless aero-snap


    【解决方案1】:

    我必须以某种方式告诉 Qt 或 DWM 将窗口缩小 16 像素 并将其向右和底部移动 8 个像素。有没有人有想法 该怎么做?

    DWM 是桌面窗口管理器吗?那么平台就是Windows。

    只要是关于 Qt 5.6 并且您很可能在谈论设置了 Qt::CustomizeWindowHint 属性的小部件,那么 Qt 中就有一个尚未修复的已知错误:

    https://bugreports.qt.io/browse/QTBUG-4362

    我偶然发现了这个错误几次,BiTOk 在上面的链接中提出的解决方法对我有用。

    【讨论】:

      【解决方案2】:

      我的第一次尝试是将窗口几何设置为可用的几何:

      QRect rect = QApplication::desktop()->availableGeometry();
      setGeometry(rect.left() , rect.top(), rect.right(), rect.bottom());
      

      唯一的问题是窗口的右侧和底部太小了一个像素并且

      setGeometry(rect.left() , rect.top(), rect.right() + 1, rect.bottom() + 1);
      

      给我一​​个错误:

      QWindowsWindow::setGeometry: Unable to set geometry 2560x1400+0+0 on QWidgetWindow/'MainWindowWindow'. Resulting geometry:  2576x1416+-8+-8 (frame: 0, 0, 0, 0, custom margin: 0, 0, 0, 0, minimum size: 45x13, maximum size: 16777215x16777215)
      

      然后我查看了 Visual Studio 2015 的矩形坐标,它们与我实现的无边框窗口大小相同,每个方向都大 8 个像素。

      我可以给窗口的内容设置 8 的边距,这样如果窗口最大化并设置窗口区域,它就不会从屏幕上剪掉:

      setContentsMargins({ 8, 8, 8, 8 });
      
      HRGN WinRgn;
      RECT winrect;
      GetClientRect(hwnd, &winrect);
      WinRgn = CreateRectRgn(8, 8, winrect.right - 8, winrect.bottom - 8);
      SetWindowRgn(hwnd, WinRgn, true);
      

      当窗口恢复后,我们需要重置之前的更改。 结果是:

      case WM_SIZE:
          WINDOWPLACEMENT wp;
          wp.length = sizeof(WINDOWPLACEMENT);
          GetWindowPlacement(hwnd, &wp);
          if (wp.showCmd == SW_MAXIMIZE) {
              setContentsMargins({ 8, 8, 8, 8 });
      
              HRGN WinRgn;
              RECT winrect;
              GetClientRect(hwnd, &winrect);
              WinRgn = CreateRectRgn(8, 8, winrect.right - 8, winrect.bottom - 8);
              SetWindowRgn(hwnd, WinRgn, true);
              UpdateWindow(hwnd);
      
              is_fullscreen = true;
      
          } else {
              if (is_fullscreen) {
                  setContentsMargins({ 0, 0, 0, 0 });
                  SetWindowRgn(hwnd, NULL, true);
      
                  is_fullscreen = false;
              }
          }
          break;
      

      【讨论】:

        【解决方案3】:

        其他帖子已经回答了这个问题,但我想补充一点,使用GetSystemMetrics 而不是硬编码值8 可能是个好主意。

        示例

        #include <Windows.h>
        
        void MyWindow::changeEvent(QEvent* ev) {
          if (ev->type() == QEvent::WindowStateChange) {
            const auto state = windowState();
            if(state & Qt::WindowMaximized) {
              const int x = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
              const int y = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
              setContentsMargins({x, y, x, y});
            }
            else {
              setContentsMargins({0, 0, 0, 0});
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-11-05
          • 1970-01-01
          • 2014-04-05
          • 1970-01-01
          • 1970-01-01
          • 2014-11-08
          • 1970-01-01
          • 1970-01-01
          • 2012-09-30
          相关资源
          最近更新 更多