仿win7窗体自动顶部最大化左侧右侧半屏效果(改写nativeEvent,使用AdjustWindowRectEx)

#include "HMainWindow.h"

#include 
#ifdef Q_OS_WIN
#include 
#include 

#ifndef GET_X_LPARAM
#define GET_X_LPARAM(lParam)    ((int)(short)LOWORD(lParam))
#endif
#ifndef GET_Y_LPARAM
#define GET_Y_LPARAM(lParam)    ((int)(short)HIWORD(lParam))
#endif

#endif
HMainWindow::HMainWindow(QWidget *parent) : QMainWindow(parent)
{
    setObjectName("HFramer");
    setWindowTitle("HFramer");
    setWidgetBorderless(this);
}


void HMainWindow::setWidgetBorderless(const QWidget *widget)
{
    setWindowFlags( Qt::WindowMinimizeButtonHint | Qt::FramelessWindowHint);
#ifdef Q_OS_WIN
    HWND hwnd = reinterpret_cast(widget->winId());
    DWORD style = GetWindowLong(hwnd, GWL_STYLE);
    SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
#endif
}

bool HMainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
#ifdef Q_OS_WIN
    if (eventType != "windows_generic_MSG")
        return false;

    MSG* msg = static_cast(message);
    QWidget* widget = QWidget::find(reinterpret_cast(msg->hwnd));
    if (!widget)
        return false;

    switch (msg->message) {

    case WM_NCCALCSIZE: {
        *result = 0;
        return true;
    }

    case WM_NCHITTEST: {
        const LONG borderWidth = 9;
        RECT winrect;
        GetWindowRect(msg->hwnd, &winrect);
        long x = GET_X_LPARAM(msg->lParam);
        long y = GET_Y_LPARAM(msg->lParam);

        // bottom right
        if (x < winrect.right && x >= winrect.right - borderWidth &&
                y < winrect.bottom && y >= winrect.bottom - borderWidth)
        {
            *result = HTBOTTOMRIGHT;
            return true;
        }

        return false;
    }

    case WM_GETMINMAXINFO: {
        if (::IsZoomed(msg->hwnd)) {

            RECT frame = { 0, 0, 0, 0 };
            AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, FALSE, 0);
            frame.left = abs(frame.left);
            frame.top = abs(frame.bottom);
            widget->setContentsMargins(frame.left, frame.top, frame.right, frame.bottom);
        }
        else {
            widget->setContentsMargins(0, 0, 0, 0);
        }

        *result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
        return true;
    }
        break;

    default:
        break;
    }

#endif

    return QMainWindow::nativeEvent(eventType, message, result);
}

这样可以实现系统的虚框,重新写nativeEvent方法

参考:

https://www.yuque.com/docs/share/27502714-1bf9-46f4-b4e9-ffd652449b2e

你可能感兴趣的:(QT,QT-窗口,C++)