qt窗口去除标题栏保留阴影

30 篇文章 3 订阅

qt接口

setWindowFlags(Qt::CustomizeWindowHint);

可以单独去掉标题栏,保留边框阴影,但是顶部会多出6个像素的白边,十分难看,又不想窗口无边框的窗口自己实现阴影和拖拽事件,于是google了一下

参考

https://stackoverflow.com/questions/39731497/create-window-without-titlebar-with-resizable-border-and-without-bogus-6px-whit

pro文件添加依赖库

win32: {
LIBS += -lDwmapi -lUxTheme -lUser32
}

main.cpp

#include "mainwindow.h"
#include "customwindow.h"
#include <QApplication>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CustomWindow w;
    a.installNativeEventFilter(&w);//不是installEventFilter
    w.show();
    return a.exec();
}

customWindow.h

#ifndef CUSTOMWINDOW_H
#define CUSTOMWINDOW_H

#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QAbstractNativeEventFilter>
#include <Windows.h>
#include <windowsx.h>

class CustomWindow : public QWidget, public QAbstractNativeEventFilter
{
    Q_OBJECT
public:
    explicit CustomWindow(QWidget *parent = nullptr);

protected:
    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;

signals:

public slots:

protected:
    virtual void paintEvent(QPaintEvent *event) override;

    RECT border_thickness;
};

#endif // CUSTOMWINDOW_H

customWindow.cpp

#include "customwindow.h"
#include <QHBoxLayout>
#include "customtitle.h"
#include "tempwidget.h"
#include <QPixmap>
#include <QtDebug>
#include <QPainter>
#include <QEvent>
#include <Dwmapi.h>

CustomWindow::CustomWindow(QWidget *parent) : QWidget(parent)
{
    setWindowFlags(Qt::CustomizeWindowHint);
    HWND hwnd = (HWND)winId();

    SetRectEmpty(&border_thickness);
    if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_THICKFRAME)
    {
        AdjustWindowRectEx(&border_thickness, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
        border_thickness.left *= -1;
        border_thickness.top *= -1;
    }
    else if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER)
    {
        SetRect(&border_thickness, 1, 1, 1, 1);
    }

    MARGINS margins = { 1, 1, 1, 1 };
    DwmExtendFrameIntoClientArea(hwnd, &margins);
    SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);

}

bool CustomWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result){
//    qDebug()<<"native event filter";
    if (eventType != "windows_generic_MSG")
        return false;

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

    switch (msg->message) {
    case WM_NCCALCSIZE: {
        //*result = 0;
        if (msg->lParam)
        {
            qDebug()<<"border nccalcsize"<<border_thickness.left<<";"
                   <<border_thickness.top<<";"
                   <<border_thickness.right<<";"
                   <<border_thickness.bottom<<";";

            NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)msg->lParam;
//            sz->rgrc[0].left += border_thickness.left;
            sz->rgrc[0].top -= border_thickness.top;
//            sz->rgrc[0].right -= border_thickness.right;
//            sz->rgrc[0].bottom -= border_thickness.bottom;
            return 0;
        }
        return false;
    }

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

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

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

        // top left
        if (x >= winrect.left && x < winrect.left + borderWidth &&
                y >= winrect.top && y < winrect.top + borderWidth)
        {
            *result = HTTOPLEFT;
            return true;
        }

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

        // left
        if (x >= winrect.left && x < winrect.left + borderWidth)
        {
            *result = HTLEFT;
            return true;
        }

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

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

        // top
        if (y >= winrect.top && y < winrect.top + borderWidth)
        {
            *result = HTTOP;
            return true;
        }

        if(y >= winrect.top + borderWidth && y < winrect.top + borderWidth + 30){
            *result = HTCAPTION;
            return true;
        }

        return false;
    }
    default:
        break;
    }

    return false;
}

void CustomWindow::paintEvent(QPaintEvent *event){
    qDebug()<<"Painter";
    QPainter p(this);

    p.fillRect(rect(), QColor(0x3A, 0x78, 0xe6));

    p.setPen(QColor(0xff, 0x63, 0x21));
    p.drawRect(0, 0, width()-1, height()-1);

    QWidget::paintEvent(event);
}

效果

在windows7上就会有点怪怪的了,

无边框,自己实现拉伸,拖拽,阴影的问题就先不研究了

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值