环境:Desktop Qt 5.4.1 MSVC2013 32bit

需要的库:dwmapi.lib 、user32.lib

需要头文件:<dwmapi.h> 、<windowsx.h>

在要处理的QWidget 构造函数中,添加以下两行:

1
2
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
SetWidgetBorderless(this);

SetWidgetBorderless的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void SetWidgetBorderless(const QWidget *widget)
{
#ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(widget->winId()); const LONG style = ( WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN );
SetWindowLongPtr(hwnd, GWL_STYLE, style); const MARGINS shadow = {1, 1, 1, 1};
DwmExtendFrameIntoClientArea(hwnd, &shadow); SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
#endif
}

这个函数的作用是给无边框窗口加上阴影、Aero Snap以及其他动画特效。

这时窗口还无法手动更改大小,需要更改的话,需要自己实现一个QAbstractNativeEventFilter 类,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class NativeEventFilter : public QAbstractNativeEventFilter
{
public:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE
{
#ifdef Q_OS_WIN
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;
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 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;
} return false;
}
default:
break;
} return false;
#else
return false;
#endif
}
};

然后在窗口创建之前,使用QApplication::installNativeEventFilter 方法把监听器注册给主程序。

要手动移动窗口位置的话,还要重截QWidget::mousePressEvent 方法:

1
2
3
4
5
6
7
8
9
10
void MyWidget::mousePressEvent(QMouseEvent *ev)
{
QWidget::mousePressEvent(ev);
if (!ev->isAccepted()) {
#ifdef Q_OS_WIN
ReleaseCapture();
SendMessage(reinterpret_cast<HWND>(winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
#endif
}

在实际操作时,有时还需要添加最大化和关闭按扭,这时正常调用QWidget::showMaximized()QWidget::close() 等Qt自带方法即可。

最终实现效果大概是这样:

缩放动画、阴影什么的和Windows本地窗口一样。

参考链接:https://github.com/deimos1877/BorderlessWindow

https://blog.yeatse.com/2015/03/01/qt-frameless-window/

让Qt的无边框窗口支持拖拽、Aero Snap、窗口阴影等特性的更多相关文章

  1. winform 窗体设置成无边框、可拖拽、四周圆角

    最近做一个及时通讯系统的登录界面,现在将界面用到的无边框.可拖拽.四周圆角的方法分享如下: 1.无边框的窗体: 把FormBorderStyle的属性设置为none 2.可拖拽:private Poi ...

  2. Qt无边框窗体-最大化时支持拖拽还原

    目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...

  3. Qt——透明无边框Widget的bug

    Experience 最近在封装一些类的时候,打算做一个窗口框架,能实现拖动.缩放.最大最小化.基本样式等功能,可不慎遇见一件无比蛋疼的事情,QWidget最小化后再恢复正常界面,最小化按钮居然仍处于 ...

  4. jQuery插件之路(三)——文件上传(支持拖拽上传)

    好了,这次咱一改往日的作风,就不多说废话了,哈哈.先贴上源代码地址,点击获取.然后直接进入主题啦,当然,如果你觉得我有哪里写的不对或者欠妥的地方,欢迎留言指出.在附上一些代码之前,我们还是先来了解下, ...

  5. GMF Q&A(1): 如何让palette支持拖拽(DnD)等10则

    1,如何让palette支持拖拽(DnD) 在*PaletteFactory类中,把私有类NodeToolEntry 和LinkToolEntry的基类修改为PaletteToolEntry.并在构造 ...

  6. .net mvc mssql easyui treegrid 及时 编辑 ,支持拖拽

    这里提到了,1个问题,怎么扩展 Easyui 参见: http://blog.csdn.net/chenkai6529/article/details/17528833 @{ ViewBag.Titl ...

  7. 一个可以自由定制外观、支持拖拽消除的MaterialDesign风格Android BadgeView

    为了尊重作者,先放上链接:https://github.com/qstumn/BadgeView BadgeView 一个可以自由定制外观.支持拖拽消除的MaterialDesign风格Android ...

  8. 关于安装了VMware tools后仍然不支持拖拽文件的问题

    我在学校机房里面的redhat4上面安装了VMware tools之后能正常支持拖拽,但是我自己电脑上的却不支持,折腾了好久,网上找了很久也还是没有解决,不过发现了一些问题,总结如下:(当然我总结的这 ...

  9. 让一个view 或者控件不支持拖拽

    让一个view 或者控件不支持拖拽: dragView.userInteractionEnabled = NO;

随机推荐

  1. C Golden gun的巧克力

    Time Limit:1000MS  Memory Limit:65535K 题型: 编程题   语言: 无限制 描述 众所周知,13级有尊大神Golden gun,人称根叔,简称金枪!众立志进校队的 ...

  2. Making raycast ignore multiple layers

    I know how to make the raycast ignore a layer but I want it to ignore layers 9 and 10 but collide wi ...

  3. RectAnimation用于在DrawingVisual画进度条

    使用Visual来画图,可以使用其派生类,UIElement.Viewport3DVisual用于呈现3D内容,其他可以用来画图的为DrawingVisual,使用DrawingVisual可以使用编 ...

  4. 【NOI2015】品酒大会

    一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 ...

  5. COJ0700 数学(一)

    试题描述 现在有一大堆数,请你对这些数进行检验. 输入 第一行:CAS,代表数据组数(不大于500000),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字检验是 ...

  6. (转)微信公众平台开发之基于百度 BAE3.0 的开发环境搭建(采用 Baidu Eclipse)

    原文传送门(http://blog.csdn.net/bingtianxuelong/article/details/17843111) 版本说明:     V1:         2014-2-13 ...

  7. Struts2 中result type属性说明

    Struts2 中result type属性说明 首先看一下在struts-default.xml中对于result-type的定义: <result-types><result-t ...

  8. Function Scope

    JavaScript’s function scope means that all variables declared within a function are visi-ble through ...

  9. cookie 换肤

    jquery.Cookies.js /** * Cookie plugin * * Copyright (c) 2006 ziqiu.zhang * Dual licensed under the M ...

  10. 连接access的语句

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...