C++ Qt/Windows,可调整大小的无框窗口

C++ Qt/Windows,可调整大小的无框窗口,c++,qt,winapi,C++,Qt,Winapi,我需要创建一个支持调整大小的无框架Qt Windows应用程序 如果我使用 setWindowFlags(Qt::FramelessWindowHint); 然后,我只能从右下角调整大小(就像使用“大小”夹点一样,我想QMainWindow不知怎的包含了它?) 有没有什么简单的方法可以让它像普通窗口一样从四面八方调整大小?可能是某个特定于平台(Windows)的东西?根据(与此无关的错误报告)中的代码,使用WM\u NCHITTEST解决了这个问题 h .cpp bool主窗口::native

我需要创建一个支持调整大小的无框架Qt Windows应用程序

如果我使用

setWindowFlags(Qt::FramelessWindowHint);
然后,我只能从右下角调整大小(就像使用“大小”夹点一样,我想QMainWindow不知怎的包含了它?)


有没有什么简单的方法可以让它像普通窗口一样从四面八方调整大小?可能是某个特定于平台(Windows)的东西?

根据(与此无关的错误报告)中的代码,使用WM\u NCHITTEST解决了这个问题

h

.cpp

bool主窗口::nativeEvent(常量QByteArray和事件类型、void*消息、long*结果)
{
MSG*MSG=static_cast(消息);
如果(消息->消息==WM\u NCHITTEST)
{
如果(isMaximized())
{
返回false;
}
*结果=0;
常量长边框宽度=8;
RECT-winrect;
GetWindowRect(重新解释转换(winId()),&winrect);
//必须短,才能正确使用多个监视器(负坐标)
短x=msg->lParam&0x0000FFFF;
短y=(msg->lParam&0xFFFF0000)>>16;
bool resizeWidth=最小宽度()!=最大宽度();
bool resizeHeight=最小高度()!=最大高度();
如果(调整宽度)
{
//左边框
如果(x>=winrect.left&&x=winrect.right-borderWidth)
{
*结果=右;
}
}
如果(调整高度)
{
//底边
如果(y=winrect.bottom-borderWidth)
{
*结果=HTBOTTOM;
}
//上边框
如果(y>=winrect.top&&y=winrect.left&&x=winrect.bottom-borderWidth)
{
*结果=HTBOTTOMLEFT;
}
//右下角
如果(x=winrect.right-borderWidth&&
y=winrect.bottom-borderWidth)
{
*结果=右下角;
}
//左上角
如果(x>=winrect.left&&x=winrect.top&&y=winrect.right-borderWidth&&
y>=winrect.top&&y

来自的实现没有很好地工作:有时在调整大小的过程中窗口会被移动(即使在没有拖动的第一个版本中)

您可以处理并返回例如HTLEFT when X_cursor-X_window看到这是特定于Windows的解决方案。
class MainWindow : public QMainWindow
{
    Q_OBJECT
......
protected:
    bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;
};
bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    MSG* msg = static_cast<MSG*>(message);

    if (msg->message == WM_NCHITTEST)
    {
        if (isMaximized())
        {
            return false;
        }

        *result = 0;
        const LONG borderWidth = 8;
        RECT winrect;
        GetWindowRect(reinterpret_cast<HWND>(winId()), &winrect);

        // must be short to correctly work with multiple monitors (negative coordinates)
        short x = msg->lParam & 0x0000FFFF;
        short y = (msg->lParam & 0xFFFF0000) >> 16;

        bool resizeWidth = minimumWidth() != maximumWidth();
        bool resizeHeight = minimumHeight() != maximumHeight();
        if (resizeWidth)
        {
            //left border
            if (x >= winrect.left && x < winrect.left + borderWidth)
            {
                *result = HTLEFT;
            }
            //right border
            if (x < winrect.right && x >= winrect.right - borderWidth)
            {
                *result = HTRIGHT;
            }
        }
        if (resizeHeight)
        {
            //bottom border
            if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
            {
                *result = HTBOTTOM;
            }
            //top border
            if (y >= winrect.top && y < winrect.top + borderWidth)
            {
                *result = HTTOP;
            }
        }
        if (resizeWidth && resizeHeight)
        {
            //bottom left corner
            if (x >= winrect.left && x < winrect.left + borderWidth &&
                y < winrect.bottom && y >= winrect.bottom - borderWidth)
            {
                *result = HTBOTTOMLEFT;
            }
            //bottom right corner
            if (x < winrect.right && x >= winrect.right - borderWidth &&
                y < winrect.bottom && y >= winrect.bottom - borderWidth)
            {
                *result = HTBOTTOMRIGHT;
            }
            //top left corner
            if (x >= winrect.left && x < winrect.left + borderWidth &&
                y >= winrect.top && y < winrect.top + borderWidth)
            {
                *result = HTTOPLEFT;
            }
            //top right corner
            if (x < winrect.right && x >= winrect.right - borderWidth &&
                y >= winrect.top && y < winrect.top + borderWidth)
            {
                *result = HTTOPRIGHT;
            }
        }

        if (*result != 0)
            return true;

        QWidget *action = QApplication::widgetAt(QCursor::pos());
        if (action == this){
            *result = HTCAPTION;
            return true;
        }
    }

    return false;
}