2

I am trying to make a borderless window in Qt5.6.0, with aero-snap functionality. Everything works, except when I maximize the window : it is too big.

My screen resolution is 2560x1440, so the window should be sized 2560x1400 (40 Pixels for the Taskbar), but in the WM_SIZE message, the new size is 2576x1416. So the window is exactly 8 pixels too big in every direction. This also means that the window is not aligned in the top-left corner, it is exactly 8 pixels off-screen in both directions.

I can't find a solution for this problem, everything I have tried doesn't work and causes bugs.

The only thing that fixes this is to remove the WS_CAPTION and WS_THICKFRAME styles, but then I lose the areo snap functionality.

I somehow have to tell Qt or DWM to make the window 16 pixels smaller and move it 8 pixels right, and bottom. Does anybody have an idea on how to do that?

4

3 回答 3

0

其他帖子已经回答了这个问题,但我只想补充一点,使用它可能是一个好主意,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});
    }
}
于 2018-07-03T14:55:52.943 回答
0

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

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;
于 2016-04-08T11:10:24.150 回答
0

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

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

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

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

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

于 2016-04-05T19:31:39.357 回答