在写Qt窗口时,假如对窗口设置了 Qt::FramelessWindowHint 或者 Qt::CustomizeWindowHint 标志,会发现窗口在副屏上最大化会遮住任务栏。

假如自己实现最大化来解决这个问题,虽然能够解决,但窗口状态就需要自己维护

// 最大化窗口 将窗口大小设置为屏幕可用区域大小

this->setGeometry(QApplication::desktop()->availableGeometry());

在Windows中通过拦截窗口消息的方式可以更优雅的解决这个问题

在窗口类中重写 nativeEvent 函数来处理窗口消息:WM_GETMINMAXINFO 来自微软官方文档解释:

WM_GETMINMAXINFO 当窗口的大小或位置即将更改时,发送到窗口。 应用程序可以使用此消息替代窗口的默认最大化大小和位置,或者默认的最小或最大跟踪大小。 [https://learn.microsoft.com/zh-cn/windows/win32/winmsg/wm-getminmaxinfo?redirectedfrom=MSDN]

当窗口接收到最大化消息时会往窗口发送WM_GETMINMAXINFO消息,假如不处理此消息,窗口大小默认就是屏幕大小,那么我们可以拦截此消息去设置窗口大小

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)

{

#ifdef Q_OS_WIN

MSG* msg = (MSG*)message;

if (msg->message == WM_GETMINMAXINFO) {

const auto flags = this->windowFlags();

if (((flags & Qt::FramelessWindowHint) == Qt::FramelessWindowHint) || ((flags & Qt::CustomizeWindowHint) == Qt::CustomizeWindowHint)) {

MINMAXINFO* mmi = (MINMAXINFO*)(msg->lParam);

// 窗口所在屏幕的可用区域(去除任务栏的可用区域)

const auto availableGeometry = QApplication::desktop()->availableGeometry(this->window());

// 设置最大化的窗口大小

mmi->ptMaxSize.y = availableGeometry.height();

mmi->ptMaxSize.x = availableGeometry.width();

return true;

}

}

#endif // Q_OS_WIN

return MainWindow::parent_type::nativeEvent(eventType, message, result);

}

下面附上窗口类的完整示例:

mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

using parent_type = QMainWindow;

MainWindow(QWidget *parent = nullptr);

~MainWindow();

protected:

bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;

private:

Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include

#include

#ifdef Q_OS_WIN

#include

#endif // Q_OS_WIN

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)

{

ui->setupUi(this);

this->setWindowFlags(Qt::CustomizeWindowHint);

// 最大化按钮

connect(ui->pushButton, &QPushButton::clicked, this, [this]() {

if (this->isMaximized()) this->showNormal();

else this->showMaximized();

});

}

MainWindow::~MainWindow()

{

delete ui;

}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)

{

#ifdef Q_OS_WIN

MSG* msg = (MSG*)message;

if(msg->message == WM_GETMINMAXINFO) {

const auto flags = this->windowFlags();

if(((flags & Qt::FramelessWindowHint) == Qt::FramelessWindowHint) || ((flags & Qt::CustomizeWindowHint) == Qt::CustomizeWindowHint)) {

MINMAXINFO* mmi = (MINMAXINFO*)(msg->lParam);

const auto availableGeometry = QApplication::desktop()->availableGeometry(this->window());

mmi->ptMaxSize.y = availableGeometry.height();

mmi->ptMaxSize.x = availableGeometry.width();

return true;

}

}

#endif // Q_OS_WIN

return MainWindow::parent_type::nativeEvent(eventType, message, result);

}

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: