Я использую WinAPI, чтобы получить некоторые специфичные для платформы функции, такие как Aero snap, поэтому становится сложно понять, почему именно возникает эта проблема.
В моем окне установлены следующие стили и атрибуты:
Код: Выделить всё
setFlags(Qt::Window | Qt::FramelessWindowHint);
SetWindowLongPtr((HWND)winId(), GWL_STYLE, WS_POPUPWINDOW | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPCHILDREN);
Код: Выделить всё
WS_CAPTION
Я подумал, что, возможно, смогу сделать что-нибудь с максимальным размером в NativeEvent, поэтому попробовал следующее:
Код: Выделить всё
bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
{
if (auto* msg = static_cast(message); msg->message == WM_NCCALCSIZE)
{
NCCALCSIZE_PARAMS& params = *reinterpret_cast(msg->lParam);
if (params.rgrc[0].top != 0)
{
--params.rgrc[0].top;
}
*result = WVR_REDRAW;
return true; //this removes the native border and title
}
else if (msg->message == WM_GETMINMAXINFO)
{
if (IsMaximized((HWND)winId()))
{
MINMAXINFO* mmi = (MINMAXINFO*)msg->lParam;
auto g = screen()->availableGeometry();
mmi->ptMaxTrackSize.x = g.width() * devicePixelRatio();
mmi->ptMaxTrackSize.y = g.height() * devicePixelRatio();
*result = 0;
return true;
}
}
return QQuickWindow::nativeEvent(eventType, message, result);
}
Я могу сделать что-то подобное, но я бы мне нравится сохранять состояние QWindow::Maximized, которое сбрасывается, когда я вызываю setGeometry.
Код: Выделить всё
bool FramelessWindow::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::WindowStateChange && QWindow::visibility() == QWindow::Maximized)
{
setGeometry(screen()->availableGeometry()); //the window is no longer maximized
return true;
}
return QQuickWindow::eventFilter(watched, event);
}
Я также пытался добавить поля в развернутом состоянии, но создание макета вызывает уродливое мерцание при изменении размера, поскольку экземпляр моего окна создается в QML. И я не могу использовать setLayout и попытаться добавить поля в код C++, потому что мой класс унаследовал QQuickWindow.
Я что-то упустил?
UPD:
Теперь я обнаружил, что эта проблема в основном связана с безфреймовостью WinAPI+, а не с Qt, так что не только у пользователей Qt возникают "расширения окон" за пределами экрана при максимизации".
Это немного помогает, по крайней мере, теперь я могу протестировать уже существующие решения WinAPI, но проблема в том, что они не работают должным образом.
Я пробовал изменить NCCALCSIZE_PARAMS при обработке сообщения WM_NCCALCSIZE:
Вот что я получил в rgrc[0]:< /p>

Что я пробовал по коду melak47:
Код: Выделить всё
void adjustMaximized(HWND hwnd, RECT& rect)
{
auto monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
if (!monitor)
{
return;
}
MONITORINFO monitor_info{};
monitor_info.cbSize = sizeof(monitor_info);
if (!::GetMonitorInfoW(monitor, &monitor_info))
{
return;
}
rect = monitor_info.rcWork;
}
bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
{
if (auto* msg = static_cast(message); msg->message == WM_NCCALCSIZE)
{
NCCALCSIZE_PARAMS& params = *reinterpret_cast(msg->lParam);
if (params.rgrc[0].top != 0)
{
--params.rgrc[0].top;
}
if (IsMaximized(hwnd_))
{
adjustMaximized(hwnd_, params.rgrc[0]);
}
return true;
}
...
}
Подробнее здесь: https://stackoverflow.com/questions/782 ... legeometry