├── README.md
├── Resources
├── close.png
├── close_h.png
├── close_p.png
├── default.qss
├── logo.png
├── maximize.png
├── maximize_h.png
├── maximize_p.png
├── menu.png
├── menu_h.png
├── menu_p.png
├── minimize.png
├── minimize_h.png
├── minimize_p.png
├── pin.png
├── pin_h.png
├── pin_p.png
├── restore.png
├── restore_h.png
├── restore_p.png
├── unpin.png
├── unpin_h.png
└── unpin_p.png
├── StyleWindow.sln
├── StyleWindow.vcxproj
├── StyleWindow.vcxproj.filters
├── StyleWindow.vcxproj.user
├── framelesswindow.cpp
├── framelesswindow.h
├── main.cpp
├── resource.h
├── stdafx.cpp
├── stdafx.h
├── stylewindow.cpp
├── stylewindow.h
├── stylewindow.ico
├── stylewindow.qrc
├── stylewindow.rc
├── titlebar.cpp
├── titlebar.h
├── windoweffect.cpp
└── windoweffect.h
/README.md:
--------------------------------------------------------------------------------
1 | # 项目简介
2 | 一款基于Qt/QWidget的无边框窗口框架,支持拖拽,缩放,阴影,桌面吸附等特性。
3 |
4 | # 窗口特性
5 | * Win11圆角/Win10直角边框自动适配
6 | * 多显示器且不同dpi下表现接近完美
7 | * 支持aero阴影
8 | * 自定义标题栏按钮
9 | * 最大/还原按钮图片能自动切换
10 | * Win快捷键+上下左右吸附
11 | * Win快捷键+左右可跨屏移动
12 | * 标题栏按钮悬浮/点击/弹起时有不同效果
13 | * 上下左右边框可鼠标拉伸
14 | * 最大化状态下拖拽标题栏可以还原窗口
15 | * 通过qss文件定义标题按钮,方便替换
16 |
17 | # 功能演示
18 | 
19 |
20 | 
21 |
--------------------------------------------------------------------------------
/Resources/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/close.png
--------------------------------------------------------------------------------
/Resources/close_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/close_h.png
--------------------------------------------------------------------------------
/Resources/close_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/close_p.png
--------------------------------------------------------------------------------
/Resources/default.qss:
--------------------------------------------------------------------------------
1 | #logoLabel
2 | {
3 | margin-left:3px;
4 | margin-right:3px;
5 | min-height:32px;
6 | min-width:32px;
7 | max-height:32px;
8 | max-width:32px;
9 | border-image:url(:/StyleWindow/Resources/logo.png)
10 | }
11 |
12 | #minToolButton
13 | {
14 | min-height:38px;
15 | min-width:38px;
16 | max-height:38px;
17 | max-width:38px;
18 | border-image:url(:/StyleWindow/Resources/minimize.png);
19 | }
20 |
21 | #minToolButton:hover
22 | {
23 | min-height:38px;
24 | min-width:38px;
25 | max-height:38px;
26 | max-width:38px;
27 | border-image:url(:/StyleWindow/Resources/minimize_h.png);
28 | }
29 |
30 | #minToolButton:pressed
31 | {
32 | min-height:38px;
33 | min-width:38px;
34 | max-height:38px;
35 | max-width:38px;
36 | border-image:url(:/StyleWindow/Resources/minimize_p.png);
37 | }
38 |
39 | #minToolButton:checked
40 | {
41 | min-height:38px;
42 | min-width:38px;
43 | max-height:38px;
44 | max-width:38px;
45 | border-image:url(:/StyleWindow/Resources/minimize_p.png);
46 | }
47 |
48 | #maxToolButton[MaxState="false"]
49 | {
50 | min-height:38px;
51 | min-width:38px;
52 | max-height:38px;
53 | max-width:38px;
54 | border-image:url(:/StyleWindow/Resources/maximize.png);
55 | }
56 |
57 | #maxToolButton:hover[MaxState="false"]
58 | {
59 | min-height:38px;
60 | min-width:38px;
61 | max-height:38px;
62 | max-width:38px;
63 | border-image:url(:/StyleWindow/Resources/maximize_h.png);
64 | }
65 | #maxToolButton:pressed[MaxState="false"]
66 | {
67 | min-height:38px;
68 | min-width:38px;
69 | max-height:38px;
70 | max-width:38px;
71 | border-image:url(:/StyleWindow/Resources/maximize_p.png);
72 | }
73 |
74 | #maxToolButton:checked[MaxState="false"]
75 | {
76 | min-height:38px;
77 | min-width:38px;
78 | max-height:38px;
79 | max-width:38px;
80 | border-image:url(:/StyleWindow/Resources/maximize_p.png);
81 | }
82 |
83 | #maxToolButton[MaxState="true"]
84 | {
85 | min-height:38px;
86 | min-width:38px;
87 | max-height:38px;
88 | max-width:38px;
89 | border-image:url(:/StyleWindow/Resources/restore.png);
90 | }
91 |
92 | #maxToolButton:hover[MaxState="true"]
93 | {
94 | min-height:38px;
95 | min-width:38px;
96 | max-height:38px;
97 | max-width:38px;
98 | border-image:url(:/StyleWindow/Resources/restore_h.png);
99 | }
100 |
101 | #maxToolButton:pressed[MaxState="true"]
102 | {
103 | min-height:38px;
104 | min-width:38px;
105 | max-height:38px;
106 | max-width:38px;
107 | border-image:url(:/StyleWindow/Resources/restore_p.png);
108 | }
109 |
110 | #maxToolButton:checked[MaxState="true"]
111 | {
112 | min-height:38px;
113 | min-width:38px;
114 | max-height:38px;
115 | max-width:38px;
116 | border-image:url(:/StyleWindow/Resources/restore_p.png);
117 | }
118 |
119 | #closeToolButton
120 | {
121 | min-height:38px;
122 | min-width:38px;
123 | max-height:38px;
124 | max-width:38px;
125 | border-image:url(:/StyleWindow/Resources/close.png);
126 | }
127 |
128 | #closeToolButton:hover
129 | {
130 | min-height:38px;
131 | min-width:38px;
132 | max-height:38px;
133 | max-width:38px;
134 | border-image:url(:/StyleWindow/Resources/close_h.png);
135 | }
136 |
137 | #closeToolButton:pressed
138 | {
139 | min-height:38px;
140 | min-width:38px;
141 | max-height:38px;
142 | max-width:38px;
143 | border-image:url(:/StyleWindow/Resources/close_p.png);
144 | }
145 |
146 | #closeToolButton:checked
147 | {
148 | min-height:38px;
149 | min-width:38px;
150 | max-height:38px;
151 | max-width:38px;
152 | border-image:url(:/StyleWindow/Resources/close_p.png);
153 | }
154 |
--------------------------------------------------------------------------------
/Resources/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/logo.png
--------------------------------------------------------------------------------
/Resources/maximize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/maximize.png
--------------------------------------------------------------------------------
/Resources/maximize_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/maximize_h.png
--------------------------------------------------------------------------------
/Resources/maximize_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/maximize_p.png
--------------------------------------------------------------------------------
/Resources/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/menu.png
--------------------------------------------------------------------------------
/Resources/menu_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/menu_h.png
--------------------------------------------------------------------------------
/Resources/menu_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/menu_p.png
--------------------------------------------------------------------------------
/Resources/minimize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/minimize.png
--------------------------------------------------------------------------------
/Resources/minimize_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/minimize_h.png
--------------------------------------------------------------------------------
/Resources/minimize_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/minimize_p.png
--------------------------------------------------------------------------------
/Resources/pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/pin.png
--------------------------------------------------------------------------------
/Resources/pin_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/pin_h.png
--------------------------------------------------------------------------------
/Resources/pin_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/pin_p.png
--------------------------------------------------------------------------------
/Resources/restore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/restore.png
--------------------------------------------------------------------------------
/Resources/restore_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/restore_h.png
--------------------------------------------------------------------------------
/Resources/restore_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/restore_p.png
--------------------------------------------------------------------------------
/Resources/unpin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/unpin.png
--------------------------------------------------------------------------------
/Resources/unpin_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/unpin_h.png
--------------------------------------------------------------------------------
/Resources/unpin_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/Resources/unpin_p.png
--------------------------------------------------------------------------------
/StyleWindow.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31911.196
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StyleWindow", "StyleWindow.vcxproj", "{453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x86 = Debug|x86
11 | Release|x86 = Release|x86
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}.Debug|x86.ActiveCfg = Debug|Win32
15 | {453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}.Debug|x86.Build.0 = Debug|Win32
16 | {453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}.Release|x86.ActiveCfg = Release|Win32
17 | {453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}.Release|x86.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {5489DF14-C131-4BE3-BBEC-8806F1B19CA1}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/StyleWindow.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {453E9FD7-1CEC-46BC-A4A2-9B39B7AB874E}
15 | QtVS_v304
16 | 10.0.19041.0
17 | 10.0.19041.0
18 | $(MSBuildProjectDirectory)\QtMsBuild
19 | StyleWindow
20 |
21 |
22 |
23 | Application
24 | v142
25 |
26 |
27 | Application
28 | v142
29 |
30 |
31 |
32 |
33 |
34 |
35 | 5.15.2_msvc2019
36 | core;gui;widgets
37 | debug
38 |
39 |
40 | 5.15.2_msvc2019
41 | core;gui;widgets
42 | release
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Use
65 |
66 |
67 |
68 |
69 | Use
70 |
71 |
72 |
73 |
74 | true
75 | true
76 | ProgramDatabase
77 | Disabled
78 | MultiThreadedDebugDLL
79 | Use
80 | stdafx.h
81 |
82 |
83 | Windows
84 | true
85 |
86 |
87 | stdafx.h;%(PrependInclude)
88 |
89 |
90 |
91 |
92 | true
93 | true
94 | None
95 | MaxSpeed
96 | MultiThreadedDLL
97 | Use
98 | stdafx.h
99 |
100 |
101 | Windows
102 | false
103 |
104 |
105 | stdafx.h;%(PrependInclude)
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | Create
123 | Create
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/StyleWindow.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3}
18 | ui
19 |
20 |
21 | {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}
22 | ts
23 |
24 |
25 |
26 |
27 | Resource Files
28 |
29 |
30 | Header Files
31 |
32 |
33 | Source Files
34 |
35 |
36 | Header Files
37 |
38 |
39 | Source Files
40 |
41 |
42 |
43 |
44 | Source Files
45 |
46 |
47 | Source Files
48 |
49 |
50 | Source Files
51 |
52 |
53 | Source Files
54 |
55 |
56 |
57 |
58 | Header Files
59 |
60 |
61 | Header Files
62 |
63 |
64 | Header Files
65 |
66 |
67 |
68 |
69 | Header Files
70 |
71 |
72 |
73 |
74 | Resource Files
75 |
76 |
77 |
--------------------------------------------------------------------------------
/StyleWindow.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2021-12-10T10:27:12.3705982Z
6 |
7 |
8 | 2021-12-10T10:27:12.9377735Z
9 |
10 |
--------------------------------------------------------------------------------
/framelesswindow.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "framelesswindow.h"
3 | #include "titlebar.h"
4 | #include "windoweffect.h"
5 |
6 | FramelessWindow::FramelessWindow(QWidget* parent)
7 | : QWidget(parent)
8 | {
9 | memset(&monitorInfo, 0, sizeof(MONITORINFO));
10 | monitorInfo.cbSize = sizeof(MONITORINFO);
11 |
12 | QVBoxLayout* layout = new QVBoxLayout(this);
13 | layout->setSpacing(0);
14 | layout->setContentsMargins(0, 0, 0, 0);
15 |
16 | titleBar = new TitleBar(this);
17 | titleBar->setObjectName("titleBar");
18 | titleBar->setStyleSheet("background: rgb(47,70,146);");
19 | layout->addWidget(titleBar);
20 |
21 | QLabel* testLabel = new QLabel(this);
22 | testLabel->setObjectName("testLabel");
23 | testLabel->setStyleSheet("background: rgb(240, 240, 240);");
24 | layout->addWidget(testLabel);
25 |
26 | setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
27 |
28 | WindowEffect::addWindowAnimation((HWND)winId());
29 | WindowEffect::addShadowEffect((HWND)winId());
30 |
31 | connect(windowHandle(), &QWindow::screenChanged, this, [=] {
32 | auto hWnd = reinterpret_cast(windowHandle()->winId());
33 | SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
34 | });
35 | }
36 |
37 | bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
38 | {
39 | MSG* msg = reinterpret_cast(message);
40 | if (msg->message == WM_NCHITTEST)
41 | {
42 | int xPos = (LOWORD(msg->lParam) - frameGeometry().x()) % 65536;
43 | int yPos = HIWORD(msg->lParam) - frameGeometry().y();
44 | int w = width();
45 | int h = height();
46 | bool lx = xPos < BORDER_WIDTH;
47 | bool rx = xPos > w - BORDER_WIDTH;
48 | bool ty = yPos < BORDER_WIDTH;
49 | bool by = yPos > h - BORDER_WIDTH;
50 |
51 | if (lx && ty)
52 | {
53 | *result = HTTOPLEFT;
54 | return true;
55 | }
56 | else if (rx && by)
57 | {
58 | *result = HTBOTTOMRIGHT;
59 | return true;
60 | }
61 | else if (rx && ty) {
62 | *result = HTTOPRIGHT;
63 | return true;
64 | }
65 | else if (lx && by) {
66 | *result = HTBOTTOMLEFT;
67 | return true;
68 | }
69 | else if (ty) {
70 | *result = HTTOP;
71 | return true;
72 | }
73 | else if (by) {
74 | *result = HTBOTTOM;
75 | return true;
76 | }
77 | else if (lx) {
78 | *result = HTLEFT;
79 | return true;
80 | }
81 | else if (rx) {
82 | *result = HTRIGHT;
83 | return true;
84 | }
85 | }
86 | else if (msg->message == WM_NCCALCSIZE)
87 | {
88 | if (isWindowMaximized(msg->hwnd))
89 | {
90 | monitorNCCALCSIZE(msg);
91 | }
92 |
93 | *result = HTNOWHERE;
94 | return true;
95 | }
96 | else if (msg->message == WM_GETMINMAXINFO)
97 | {
98 | if (isWindowMaximized(msg->hwnd))
99 | {
100 | RECT window_rect;
101 | if (!GetWindowRect(msg->hwnd, &window_rect))
102 | {
103 | *result = HTNOWHERE;
104 | return false;
105 | }
106 |
107 | HMONITOR hMonitor = MonitorFromRect(&window_rect, MONITOR_DEFAULTTONULL);
108 | if (!hMonitor)
109 | {
110 | *result = HTNOWHERE;
111 | return false;
112 | }
113 |
114 | GetMonitorInfoW(hMonitor, &monitorInfo);
115 | RECT monitor_rect = monitorInfo.rcMonitor;
116 | RECT work_area = monitorInfo.rcWork;
117 |
118 | LPMINMAXINFO info = reinterpret_cast(msg->lParam);
119 |
120 | info->ptMaxSize.x = work_area.right - work_area.left;
121 | info->ptMaxSize.y = work_area.bottom - work_area.top;
122 | info->ptMaxTrackSize.x = info->ptMaxSize.x;
123 | info->ptMaxTrackSize.y = info->ptMaxSize.y;
124 |
125 | info->ptMaxPosition.x = abs(window_rect.left - monitor_rect.left);
126 | info->ptMaxPosition.y = abs(window_rect.top - monitor_rect.top);
127 | *result = HTCLIENT;
128 | return true;
129 | }
130 | }
131 |
132 | return QWidget::nativeEvent(eventType, message, result);
133 | }
134 |
135 | void FramelessWindow::changeEvent(QEvent* event)
136 | {
137 | if (event->type() == QEvent::WindowStateChange)
138 | {
139 | RefreshStyle(titleBar->findChild("maxToolButton"), "MaxState", isMaximized());
140 | }
141 |
142 | return QWidget::changeEvent(event);
143 | }
144 |
145 | bool FramelessWindow::isWindowMaximized(HWND hWnd)
146 | {
147 | WINDOWPLACEMENT wp;
148 | wp.length = sizeof(WINDOWPLACEMENT);
149 | if (!GetWindowPlacement(hWnd, &wp))
150 | {
151 |
152 | }
153 | return wp.showCmd == SW_MAXIMIZE;
154 | }
155 |
156 | void FramelessWindow::monitorNCCALCSIZE(MSG* msg)
157 | {
158 | HMONITOR hMonitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONULL);
159 | if (hMonitor != NULL)
160 | {
161 | GetMonitorInfoW(hMonitor, &monitorInfo);
162 | }
163 |
164 | NCCALCSIZE_PARAMS& params = *reinterpret_cast(msg->lParam);
165 | params.rgrc[0].left = monitorInfo.rcWork.left;
166 | params.rgrc[0].top = monitorInfo.rcWork.top;
167 | params.rgrc[0].right = monitorInfo.rcWork.right;
168 | params.rgrc[0].bottom = monitorInfo.rcWork.bottom;
169 |
170 | //qDebug() << params.rgrc[0].left << params.rgrc[0].top << params.rgrc[0].right << params.rgrc[0].bottom;
171 | }
--------------------------------------------------------------------------------
/framelesswindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "windows.h"
6 |
7 | class TitleBar;
8 |
9 | class FramelessWindow : public QWidget
10 | {
11 | public:
12 | FramelessWindow(QWidget* parent = Q_NULLPTR);
13 | protected:
14 | bool nativeEvent(const QByteArray& eventType, void* message, long* result);
15 | void changeEvent(QEvent* event);
16 | private:
17 | bool isWindowMaximized(HWND hWnd);
18 | void monitorNCCALCSIZE(MSG* msg);
19 |
20 | TitleBar* titleBar;
21 | MONITORINFO monitorInfo;
22 | RECT monitor_rect;
23 | RECT work_area;
24 | };
25 |
26 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "stylewindow.h"
3 | #include
4 |
5 | #pragma comment(lib, "Dwmapi.lib")
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | QApplication a(argc, argv);
10 | LoadStyle(DEFAULT_STYLE);
11 |
12 | StyleWindow w;
13 | w.show();
14 | return a.exec();
15 | }
16 |
--------------------------------------------------------------------------------
/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by stylewindow.rc
4 |
5 | // Next default values for new objects
6 | //
7 | #ifdef APSTUDIO_INVOKED
8 | #ifndef APSTUDIO_READONLY_SYMBOLS
9 | #define _APS_NEXT_RESOURCE_VALUE 101
10 | #define _APS_NEXT_COMMAND_VALUE 40001
11 | #define _APS_NEXT_CONTROL_VALUE 1001
12 | #define _APS_NEXT_SYMED_VALUE 101
13 | #endif
14 | #endif
15 |
--------------------------------------------------------------------------------
/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | void RefreshStyle(QWidget* widget, const char* name, QVariant value)
4 | {
5 | widget->setProperty(name, value);
6 |
7 | qApp->style()->unpolish(widget);
8 | qApp->style()->polish(widget);
9 |
10 | widget->update();
11 | }
12 |
13 | void LoadStyle(QString filePath)
14 | {
15 | QString styleSheet;
16 |
17 | QFile file(filePath);
18 | if (file.open(QFile::ReadOnly))
19 | {
20 | styleSheet.append(QString::fromLocal8Bit(file.readAll()));
21 |
22 | file.close();
23 | }
24 |
25 | qApp->setStyleSheet(styleSheet);
26 |
27 | }
--------------------------------------------------------------------------------
/stdafx.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define BORDER_WIDTH 5
4 | #define TITLE_HEIGHT 38
5 | #define BUTTON_WIDTH 38
6 |
7 | #define DEFAULT_STYLE ":/StyleWindow/Resources/default.qss"
8 |
9 | extern void RefreshStyle(QWidget* widget, const char* name, QVariant value);
10 | extern void LoadStyle(QString filePath);
--------------------------------------------------------------------------------
/stylewindow.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "stylewindow.h"
3 | #include "stdafx.h"
4 |
5 | StyleWindow::StyleWindow(QWidget* parent)
6 | : FramelessWindow(parent)
7 | {
8 | resize(800, 600);
9 | }
10 |
--------------------------------------------------------------------------------
/stylewindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "framelesswindow.h"
6 |
7 | class StyleWindow : public FramelessWindow
8 | {
9 | Q_OBJECT
10 |
11 | public:
12 | StyleWindow(QWidget *parent = Q_NULLPTR);
13 |
14 | protected:
15 | private:
16 |
17 | };
18 |
--------------------------------------------------------------------------------
/stylewindow.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/stylewindow.ico
--------------------------------------------------------------------------------
/stylewindow.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/default.qss
4 | Resources/logo.png
5 | Resources/close.png
6 | Resources/close_h.png
7 | Resources/close_p.png
8 | Resources/maximize.png
9 | Resources/maximize_h.png
10 | Resources/maximize_p.png
11 | Resources/menu.png
12 | Resources/menu_h.png
13 | Resources/menu_p.png
14 | Resources/minimize.png
15 | Resources/minimize_h.png
16 | Resources/minimize_p.png
17 | Resources/restore.png
18 | Resources/restore_h.png
19 | Resources/restore_p.png
20 | Resources/pin.png
21 | Resources/pin_h.png
22 | Resources/pin_p.png
23 | Resources/unpin.png
24 | Resources/unpin_h.png
25 | Resources/unpin_p.png
26 |
27 |
28 |
--------------------------------------------------------------------------------
/stylewindow.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcaihao/StyleWindow/869c9c2a4b071457902c7ba09071152558a0290a/stylewindow.rc
--------------------------------------------------------------------------------
/titlebar.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "titlebar.h"
3 | #include "windows.h"
4 |
5 | #include
6 |
7 | TitleBar::TitleBar(QWidget* parent)
8 | : QWidget(parent)
9 | {
10 | //resize(1360, 38);
11 | setFixedHeight(TITLE_HEIGHT);
12 | setAttribute(Qt::WA_StyledBackground);
13 |
14 | QHBoxLayout* layout = new QHBoxLayout(this);
15 | layout->setSpacing(0);
16 | layout->setContentsMargins(0, 0, 0, 0);
17 |
18 | QLabel* logoLabel = new QLabel(this);
19 | logoLabel->setObjectName("logoLabel");
20 | layout->addWidget(logoLabel);
21 | layout->addStretch(1);
22 |
23 | QToolButton* minToolButton = new QToolButton(this);
24 | minToolButton->setObjectName("minToolButton");
25 | connect(minToolButton, &QToolButton::clicked, this->window(), &QWidget::showMinimized);
26 | layout->addWidget(minToolButton);
27 |
28 | QToolButton* maxToolButton = new QToolButton(this);
29 | maxToolButton->setObjectName("maxToolButton");
30 | connect(maxToolButton, &QToolButton::clicked, this, &TitleBar::toggleMaxState);
31 | maxToolButton->setProperty("MaxState", false);
32 | layout->addWidget(maxToolButton);
33 |
34 | QToolButton* closeToolButton = new QToolButton(this);
35 | closeToolButton->setObjectName("closeToolButton");
36 | connect(closeToolButton, &QToolButton::clicked, this->window(), &QWidget::close);
37 | layout->addWidget(closeToolButton);
38 | }
39 |
40 | TitleBar::~TitleBar()
41 | {
42 | }
43 |
44 | void TitleBar::mouseDoubleClickEvent(QMouseEvent* event)
45 | {
46 | toggleMaxState();
47 | }
48 |
49 | void TitleBar::mousePressEvent(QMouseEvent* event)
50 | {
51 | ReleaseCapture();
52 | SendMessage((HWND)window()->winId(), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
53 | event->ignore();
54 | }
55 |
56 | void TitleBar::toggleMaxState()
57 | {
58 | if (window()->isMaximized())
59 | {
60 | window()->showNormal();
61 | }
62 | else
63 | {
64 | window()->showMaximized();
65 | }
66 | }
--------------------------------------------------------------------------------
/titlebar.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | class TitleBar : public QWidget
9 | {
10 | Q_OBJECT
11 |
12 | public:
13 | TitleBar(QWidget *parent);
14 | ~TitleBar();
15 | protected:
16 | void mousePressEvent(QMouseEvent* event);
17 | void mouseDoubleClickEvent(QMouseEvent* event);
18 | private:
19 | void toggleMaxState();
20 | };
21 |
--------------------------------------------------------------------------------
/windoweffect.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "windoweffect.h"
3 |
4 | #include
5 |
6 | namespace WindowEffect
7 | {
8 | void moveWindow(HWND hWnd)
9 | {
10 | ReleaseCapture();
11 | SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
12 | }
13 |
14 | void addShadowEffect(HWND hWnd)
15 | {
16 | DWMNCRENDERINGPOLICY ncrp = DWMNCRP_ENABLED;
17 | ::DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));
18 |
19 | MARGINS margins = { -1 };
20 | ::DwmExtendFrameIntoClientArea(hWnd, &margins);
21 | }
22 |
23 | void removeShadowEffect(HWND hWnd)
24 | {
25 | DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED;
26 | ::DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));
27 | }
28 |
29 | void removeMenuShadowEffect(HWND hWnd)
30 | {
31 | DWORD style = GetClassLong(hWnd, GCL_STYLE);
32 | style &= ~0x00020000; // CS_DROPSHADOW;
33 | SetClassLong(hWnd, GCL_STYLE, style);
34 | }
35 |
36 | void addWindowAnimation(HWND hWnd)
37 | {
38 | DWORD style = GetWindowLong(hWnd, GWL_STYLE);
39 | SetWindowLong(hWnd, GWL_STYLE, style
40 | | WS_MAXIMIZEBOX
41 | | WS_CAPTION
42 | | CS_DBLCLKS
43 | | WS_THICKFRAME
44 | );
45 | }
46 | }
--------------------------------------------------------------------------------
/windoweffect.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "windows.h"
4 |
5 | namespace WindowEffect
6 | {
7 | void moveWindow(HWND hWnd);
8 | void addShadowEffect(HWND hWnd);
9 | void removeShadowEffect(HWND hWnd);
10 | void removeMenuShadowEffect(HWND hWnd);
11 | void addWindowAnimation(HWND hWnd);
12 | };
13 |
14 |
--------------------------------------------------------------------------------