Окно без полей с Aero Snap слишком велико в развернутом состоянии

Я пытаюсь сделать окно без границ в Qt5.6.0, с функциональностью aero-snap.
Все работает, кроме случаев, когда я максимизирую окно: оно слишком большое.

Мое разрешение экрана 2560x1440поэтому окно должно быть размером 2560x1400 (40 пикселей для панели задач), но в WM_SIZE сообщение, новый размер 2576x1416,
Таким образом, окно ровно на 8 пикселей больше во всех направлениях.
Это также означает, что окно не выровнено в верхнем левом углу, оно находится на расстоянии 8 пикселей вне экрана в обоих направлениях.

Я не могу найти решение этой проблемы, все, что я пробовал, не работает и вызывает ошибки.

Единственное, что исправляет это, это удалить WS_CAPTION а также WS_THICKFRAME стили, но потом я теряю функциональность арео оснастки

Я как-то должен сказать Qt или DWM, чтобы сделать окно на 16 пикселей меньше и переместить его на 8 пикселей вправо и вниз. У кого-нибудь есть идея, как это сделать?

2

Решение

Я как-то должен сказать Qt или DWM, чтобы сделать окно на 16 пикселей меньше
и переместите его на 8 пикселей вправо и вниз. У кого-нибудь есть идея
как это сделать?

DWM это менеджер окон рабочего стола? Тогда платформа Windows.

Если речь идет о Qt 5.6 и вы, скорее всего, говорите о виджете с установленным атрибутом Qt :: CustomizeWindowHint, то в Qt есть известная ошибка, которая еще не исправлена:

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

Я наткнулся на эту ошибку пару раз, и обходной путь, предложенный Bitok по ссылке выше у меня сработало.

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;
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});
}
}
0
По вопросам рекламы [email protected]