小标
2018-08-14
来源 :
阅读 1370
评论 0
摘要:本文主要向大家介绍了窗体皮肤实现 - 在VC编程中简单实现绘制(五),通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
本文主要向大家介绍了窗体皮肤实现 - 在VC编程中简单实现绘制(五),通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
代码中处理了四个消息,还是比较简单。只有 WM_WINDOWPOSCHANGING 消息的处理稍微长些。
WM_NCPAINT --- 绘制非客户区
WM_NCCALCSIZE --- 重新设置边缘宽度
WM_NCACTIVATE --- 程序切换时重绘非客户去
WM_WINDOWPOSCHANGING --- 重设界面样式
重新绘制非客户区 WM_NCPAINT
复制代码
// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_NCPAINT:
hdc = GetWindowDC(hWnd);
PaintNC(hWnd, hdc);
ReleaseDC(hWnd, hdc);
break;
// 非客户去绘制
void PaintNC(HWND hWnd, HDC dc)
{
HBRUSH hBrush;
RECT rw;
RECT rc;
POINT pt;
GetWindowRect(hWnd, &rw);
GetClientRect(hWnd, &rc);
pt.x = rc.left;
pt.y = rc.top;
ClientToScreen(hWnd, &pt);
OffsetRect(&rc, pt.x - rw.left, pt.y - rw.top);
ExcludeClipRect(dc, rc.left, rc.top, rc.right, rc.bottom); // 扣除客户区
OffsetRect(&rw, -rw.left, -rw.top);
hBrush = CreateSolidBrush(0xBF7B18);
FillRect(dc, &rw, hBrush);
DeleteObject(hBrush);
}
复制代码
重新设置窗体边缘宽度 WM_NCCALCSIZE
复制代码
1 // 设置窗体边框宽度
2 case WM_NCCALCSIZE:
3 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].left += 3;
4 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].top += 55;
5 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].right -= 4;
6 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].bottom -= 4;
7 break;
复制代码
切换程序时重绘非客户去WM_NCACTIVATE
1 case WM_NCACTIVATE:
2 PostMessage(hWnd, WM_NCPAINT, 1, 0);
3 break;
设置窗体样式 WM_WINDOWPOSCHANGING
复制代码
1 // 有修改窗体尺寸时重设样式
2 //
3
4 case WM_WINDOWPOSCHANGING:
5 bChanged = FALSE;
6 if (!gChangeSizeCalled) {
7 bChanged = (((LPWINDOWPOS)lParam)->flags & SWP_FRAMECHANGED);
8 if ((((LPWINDOWPOS)lParam)->flags & SWP_NOMOVE) == 0){
9 gWindowSize.left = ((LPWINDOWPOS)lParam)->x;
10 gWindowSize.top = ((LPWINDOWPOS)lParam)->y;
11 }
12 if ((((LPWINDOWPOS)lParam)->flags & SWP_NOSIZE) == 0){
13 bChanged = bChanged || (((LPWINDOWPOS)lParam)->cx != gWindowSize.right) || (((LPWINDOWPOS)lParam)->cy != gWindowSize.bottom);
14 gWindowSize.right = ((LPWINDOWPOS)lParam)->cx;
15 gWindowSize.bottom = ((LPWINDOWPOS)lParam)->cy;
16 }
17 bChanged = bChanged && ((gWindowSize.right * gWindowSize.bottom) != 0);
18
19 if (bChanged){
20 gChangeSizeCalled = TRUE;
21 __try {
22 hTmp = gRegion;
23 gRegion = CreateRoundRectRgn(0, 0, gWindowSize.right, gWindowSize.bottom, 3, 3);
24 SetWindowRgn(hWnd, gRegion, TRUE);
25 if (hTmp)
26 DeleteObject(hTmp);
27 }
28 __finally {
29 gChangeSizeCalled = FALSE;
30 }
31 }
32 }
33
34 if (!bChanged)
35 return DefWindowProc(hWnd,message, wParam, lParam);
36
37 break;
1 // skin.cpp : Defines the entry point for the application.
2 //
3
4 #include "stdafx.h"
5 #include "skin.h"
6
7 #define MAX_LOADSTRING 100
8
9 // Global Variables:
10 HINSTANCE hInst; // current instance
11 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
12 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
13
14 HRGN gRegion = 0;
15 BOOL gChangeSizeCalled = FALSE;
16 RECT gWindowSize = {0,0,0,0};
17
18 // Forward declarations of functions included in this code module:
19 ATOM MyRegisterClass(HINSTANCE hInstance);
20 BOOL InitInstance(HINSTANCE, int);
21 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
22 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
23
24 void PaintNC(HWND, HDC);
25
26
27 int APIENTRY _tWinMain(HINSTANCE hInstance,
28 HINSTANCE hPrevInstance,
29 LPTSTR lpCmdLine,
30 int nCmdShow)
31 {
32 UNREFERENCED_PARAMETER(hPrevInstance);
33 UNREFERENCED_PARAMETER(lpCmdLine);
34
35 // TODO: Place code here.
36 MSG msg;
37 HACCEL hAccelTable;
38
39 // Initialize global strings
40 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
41 LoadString(hInstance, IDC_SKIN, szWindowClass, MAX_LOADSTRING);
42 MyRegisterClass(hInstance);
43
44 // Perform application initialization:
45 if (!InitInstance (hInstance, nCmdShow))
46 {
47 return FALSE;
48 }
49
50 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SKIN));
51
52 // Main message loop:
53 while (GetMessage(&msg, NULL, 0, 0))
54 {
55 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
56 {
57 TranslateMessage(&msg);
58 DispatchMessage(&msg);
59 }
60 }
61
62 return (int) msg.wParam;
63 }
64
65
66
67 //
68 // FUNCTION: MyRegisterClass()
69 //
70 // PURPOSE: Registers the window class.
71 //
72 // COMMENTS:
73 //
74 // This function and its usage are only necessary if you want this code
75 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
76 // function that was added to Windows 95. It is important to call this function
77 // so that the application will get 'well formed' small icons associated
78 // with it.
79 //
80 ATOM MyRegisterClass(HINSTANCE hInstance)
81 {
82 WNDCLASSEX wcex;
83
84 wcex.cbSize = sizeof(WNDCLASSEX);
85
86 wcex.style = CS_HREDRAW | CS_VREDRAW;
87 wcex.lpfnWndProc = WndProc;
88 wcex.cbClsExtra = 0;
89 wcex.cbWndExtra = 0;
90 wcex.hInstance = hInstance;
91 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SKIN));
92 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
93 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
94 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SKIN);
95 wcex.lpszClassName = szWindowClass;
96 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
97
98 return RegisterClassEx(&wcex);
99 }
100
101 //
102 // FUNCTION: InitInstance(HINSTANCE, int)
103 //
104 // PURPOSE: Saves instance handle and creates main window
105 //
106 // COMMENTS:
107 //
108 // In this function, we save the instance handle in a global variable and
109 // create and display the main program window.
110 //
111 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
112 {
113 HWND hWnd;
114
115 hInst = hInstance; // Store instance handle in our global variable
116
117 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
118 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
119
120 if (!hWnd)
121 {
122 return FALSE;
123 }
124
125 ShowWindow(hWnd, nCmdShow);
126 UpdateWindow(hWnd);
127
128 return TRUE;
129 }
130
131 //
132 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
133 //
134 // PURPOSE: Processes messages for the main window.
135 //
136 // WM_COMMAND - process the application menu
137 // WM_PAINT - Paint the main window
138 // WM_DESTROY - post a quit message and return
139 //
140 //
141 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
142 {
143 int wmId, wmEvent;
144 PAINTSTRUCT ps;
145 HDC hdc;
146
147 HRGN hTmp;
148 BOOL bChanged;
149 LRESULT result;
150
151 switch (message)
152 {
153 case WM_COMMAND:
154 wmId = LOWORD(wParam);
155 wmEvent = HIWORD(wParam);
156 // Parse the menu selections:
157 switch (wmId)
158 {
159 case IDM_ABOUT:
160 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
161 break;
162 case IDM_EXIT:
163 DestroyWindow(hWnd);
164 break;
165 default:
166 return DefWindowProc(hWnd, message, wParam, lParam);
167 }
168 break;
169 case WM_PAINT:
170 hdc = BeginPaint(hWnd, &ps);
171 // TODO: Add any drawing code here...
172 EndPaint(hWnd, &ps);
173 break;
174
175 case WM_NCPAINT:
176 hdc = GetWindowDC(hWnd);
177 PaintNC(hWnd, hdc);
178 ReleaseDC(hWnd, hdc);
179 break;
180
181 case WM_NCCALCSIZE:
182 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].left += 3;
183 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].top += 55;
184 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].right -= 4;
185 ((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0].bottom -= 4;
186 break;
187
188 case WM_NCACTIVATE:
189 PostMessage(hWnd, WM_NCPAINT, 1, 0);
190 break;
191
192 case WM_WINDOWPOSCHANGING:
193 bChanged = FALSE;
194
195 if (!gChangeSizeCalled) {
196 bChanged = (((LPWINDOWPOS)lParam)->flags & SWP_FRAMECHANGED);
197
198 if ((((LPWINDOWPOS)lParam)->flags & SWP_NOMOVE) == 0){
199 gWindowSize.left = ((LPWINDOWPOS)lParam)->x;
200 gWindowSize.top = ((LPWINDOWPOS)lParam)->y;
201 }
202 if ((((LPWINDOWPOS)lParam)->flags & SWP_NOSIZE) == 0){
203 bChanged = bChanged || (((LPWINDOWPOS)lParam)->cx != gWindowSize.right) || (((LPWINDOWPOS)lParam)->cy != gWindowSize.bottom);
204 gWindowSize.right = ((LPWINDOWPOS)lParam)->cx;
205 gWindowSize.bottom = ((LPWINDOWPOS)lParam)->cy;
206 }
207
208 bChanged = bChanged && ((gWindowSize.right * gWindowSize.bottom) != 0);
209
210 if (bChanged)
211 {
212 gChangeSizeCalled = TRUE;
213 __try {
214 hTmp = gRegion;
215 gRegion = CreateRoundRectRgn(0, 0, gWindowSize.right, gWindowSize.bottom, 3, 3);
216 SetWindowRgn(hWnd, gRegion, TRUE);
217 if (hTmp)
218 DeleteObject(hTmp);
219 }
220 __finally {
221 gChangeSizeCalled = FALSE;
222 }
223 }
224 }
225
226 if (!bChanged)
227 return DefWindowProc(hWnd,message, wParam, lParam);
228
229 break;
230
231 case WM_DESTROY:
232 PostQuitMessage(0);
233 break;
234
235 case WM_QUIT:
236 if (gRegion) {
237 DeleteObject(gRegion);
238 gRegion = 0;
239 }
240 return DefWindowProc(hWnd, message, wParam, lParam);
241
242 default:
243 return DefWindowProc(hWnd, message, wParam, lParam);
244 }
245 return 0;
246 }
247
248 // Message handler for about box.
249 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
250 {
251 UNREFERENCED_PARAMETER(lParam);
252 switch (message)
253 {
254 case WM_INITDIALOG:
255 return (INT_PTR)TRUE;
256
257 case WM_COMMAND:
258 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
259 {
260 EndDialog(hDlg, LOWORD(wParam));
261 return (INT_PTR)TRUE;
262 }
263 break;
264 }
265 return (INT_PTR)FALSE;
266 }
267
268 void PaintNC(HWND hWnd, HDC dc)
269 {
270 HBRUSH hBrush;
271 RECT rw;
272 RECT rc;
273 POINT pt;
274
275 GetWindowRect(hWnd, &rw);
276 GetClientRect(hWnd, &rc);
277 pt.x = rc.left;
278 pt.y = rc.top;
279 ClientToScreen(hWnd, &pt);
280 OffsetRect(&rc, pt.x - rw.left, pt.y - rw.top);
281
282 ExcludeClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
283
284 OffsetRect(&rw, -rw.left, -rw.top);
285 hBrush = CreateSolidBrush(0xBF7B18);
286 FillRect(dc, &rw, hBrush);
287 DeleteObject(hBrush);
288 }
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号