写一个Windows编程的WinMain函数模板

前言

为了能快速编写Windows应用程序,避免重复敲同样的代码,特地写一个WinMain函数模板,然后封装一些组件,随时用随时粘贴

WinMain函数代码如下

这个代码随时用随时复制粘贴就完事了

编译命令gcc 3demo.cpp -o 3demo -static -Wall -std=c++11 -mwindows

运行命令./main.exe

main.cpp

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <Windows.h>
#include <strsafe.h>
#include <commctrl.h>

/*****
* CALLBACK代表__stdcall 参数的传递顺序 从右到左 依次入栈 并且在函数返回前 依次出栈
* HWND UINT WPARAM LPARAM
* 消息所属的窗口句柄
* 消息名称 WM_XXX消息名
* 键盘附加消息
* 鼠标附加消息
*/

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
break;
}
case WM_PAINT:
{
break;
}
case WM_SIZE:
{
break;
}
case WM_COMMAND:
{
break;
}
case WM_LBUTTONDOWN:
{
PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
break;
}
case WM_RBUTTONDOWN:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TCHAR buffer[256];
StringCchPrintf(buffer, 256, TEXT("xPos: %d, yPos: %d"), xPos, yPos);
MessageBox(hWnd, buffer, TEXT("WM_LBUTTONDOWN"), MB_OK);
break;
}
case WM_KEYDOWN:
{
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
break;
}
LPCTSTR lpWindowplace = TEXT("./WinConfig.ini");
if (uMsg == WM_CREATE) {
// Window place
WINDOWPLACEMENT wp;
GetPrivateProfileStruct(TEXT("MainFrame"), TEXT("WindowPlace"), &wp, sizeof(wp), lpWindowplace);
// 如果窗口最小化了,可以将它还原
if (wp.showCmd == SW_SHOWMINIMIZED) {
wp.showCmd = SW_SHOWNORMAL;
}
// 检查窗口是否在屏幕外部 将其移到屏幕内部
RECT screenRect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
if (!IntersectRect(&screenRect, &wp.rcNormalPosition, &screenRect)) {
wp.rcNormalPosition.left = screenRect.left;
wp.rcNormalPosition.top = screenRect.top;
wp.rcNormalPosition.right = screenRect.left + (wp.rcNormalPosition.right - wp.rcNormalPosition.left);
wp.rcNormalPosition.bottom = screenRect.top + (wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
}
SetWindowPlacement(hWnd, &wp);
}
else if (uMsg == WM_DESTROY) {
// Window place
WINDOWPLACEMENT wp;
GetWindowPlacement(hWnd, &wp);
WritePrivateProfileStruct(TEXT("MainFrame"), TEXT("WindowPlace"), &wp, sizeof(wp), lpWindowplace);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

// WINAPI代表__stdcall 参数的传递顺序 从右到左 依次入栈 并且在函数返回前 依次出栈
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0; // 类的额外内存
wcex.cbWndExtra = 0; // 窗口额外内存
wcex.hbrBackground = GetSysColorBrush(/*COLOR_3DFACE*/ COLOR_3DFACE /*COLOR_3DSHADOW*/); // 背景
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标 第一个为NULL代表使用系统提供的光标
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标 第一个为NULL代表使用系统提供的图标
wcex.hInstance = hInstance; // 应用程序实例句柄
wcex.lpfnWndProc = WindowProc; // 回调函数
wcex.lpszClassName = TEXT("MainClass"); // 窗口类名称
wcex.lpszMenuName = NULL; // 菜单名称
wcex.style = CS_HREDRAW | CS_VREDRAW; // 显示风格

RegisterClassEx(&wcex);

/*****
* CreateWindow()
* lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam
* 类名
* 标题名
* WS_OVERLAPPEDWINDOW 混合风格
* x坐标 CW_USEDEFAULT
* y坐标
* 宽
* 高
* 父窗口 NULL
* 菜单 NULL
* 实例句柄 hInstance
* 附加值
*/
HWND hWnd = CreateWindowEx(NULL, wcex.lpszClassName, TEXT("MainFrame"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
return 0;
}
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);

/*****
* HWND hwnd; 主窗口句柄
* UINT message; 具体消息名称
* WPARAM wParam; 附加消息 键盘消息
* LPARAM lParam; 附加消息 鼠标消息
* DWORD time; 消息产生时间
* POINT pt; 附加消息 鼠标消息 x y
*/
MSG msg;

/*****
* LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax
* 消息
* 捕获窗口 NULL代表捕获所有窗口
* 最小的过滤消息 0代表捕获所有消息
* 最大的过滤消息 0代表捕获所有消息
*/
while (GetMessage(&msg, NULL, 0, 0))
{
// 如果按的是组合键 需要翻译
TranslateMessage(&msg);
// 单按一个键盘就直接分发消息
DispatchMessage(&msg);
}
return 0;
}

WinMain和控件封装

当然,只有这么些肯定还是不够的,我们新建完窗口之后需要创建控件等,为了更方便的创建控件,我直接把WinMain函数和一些控件封装在一起,以后复制下面的代码随便改改就行了,这样就不用写大量重复代码了

运行截图

WinMain

编译命令g++ main.cpp -o main -static -Wall -std=c++11 -mwindows

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "winapp.hpp"

using namespace std;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WinApp app;
app.init(hInstance, TEXT("Windows"));

app.Menu();
app.Button();
app.Edit();
app.ListView();

app.run();
return 0;
}

winapp.hpp

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#include <Windows.h>
#include <commctrl.h>
#include <strsafe.h>

// 调试窗口
HANDLE hOutput;
void consoleInit(void)
{
AllocConsole();
SetConsoleTitle(TEXT("Debug Window"));
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}

// 线程回调
HANDLE hThread1;
HANDLE hThread2;
DWORD CALLBACK ThreadProc1(LPVOID pParam)
{
char *pszText = (char *)pParam;
for (int i = 0; i < 99; i++)
{
WriteConsole(hOutput, pszText, 9, NULL, NULL);
WriteConsole(hOutput, TEXT("\n"), 1, NULL, NULL);
Sleep(1000);
}
return 0;
}
DWORD CALLBACK ThreadProc2(LPVOID pParam)
{
char *pszText = (char *)pParam;
for (int i = 0; i < 99; i++)
{
WriteConsole(hOutput, pszText, 9, NULL, NULL);
WriteConsole(hOutput, TEXT("\n"), 1, NULL, NULL);
Sleep(1000);
}
return 0;
}

#define IDM_OPEN 301
#define IDM_CLOSE 302
#define IDM_EXIT 303
#define IDM_FIND 304
#define IDM_RUN 305
#define IDM_STOP 306
#define IDM_OPTIONS 307
#define IDM_ABOUT 308
class WinMenu
{
public:
WinMenu() {}
~WinMenu() {}
inline BOOL createMenu(HWND hWnd)
{
HMENU hMenu = CreateMenu();
if (!hMenu)
return -1;
HMENU pop1 = CreatePopupMenu();
HMENU pop2 = CreatePopupMenu();
HMENU pop3 = CreatePopupMenu();
HMENU pop4 = CreatePopupMenu();
HMENU pop5 = CreatePopupMenu();
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)pop1, TEXT("File"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)pop2, TEXT("Find"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)pop3, TEXT("Run"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)pop4, TEXT("Tools"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)pop5, TEXT("Help"));

AppendMenu(pop1, MF_STRING, IDM_OPEN, TEXT("Open"));
AppendMenu(pop1, MF_STRING, IDM_CLOSE, TEXT("Close"));
AppendMenu(pop2, MF_STRING, IDM_FIND, TEXT("Find"));
AppendMenu(pop3, MF_STRING, IDM_RUN, TEXT("Run"));
AppendMenu(pop3, MF_STRING, IDM_STOP, TEXT("Stop"));
AppendMenu(pop4, MF_STRING, IDM_OPTIONS, TEXT("Options"));
AppendMenu(pop5, MF_STRING, IDM_ABOUT, TEXT("About"));

SetMenu(hWnd, hMenu);
return TRUE;
}
};

#define IDB_BUTTON_START 111
#define IDB_BUTTON_STOP 112
#define IDB_BUTTON_OPEN 113
#define IDB_BUTTON_CLEAN 114
class WinButton
{
public:
WinButton() {}
~WinButton() {}
inline BOOL createButton(HWND hWnd, TCHAR title[], INT x = 0, INT y = 0, HMENU IDB_BUTTON = NULL, INT width = 100, INT height = 50)
{
CreateWindow(WC_BUTTON, title, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x, y, width, height, hWnd, IDB_BUTTON, NULL, NULL);
return TRUE;
}
inline BOOL onClick(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(wParam))
{
case IDB_BUTTON_START:
{
HDC hdc = GetDC(hWnd);
HPEN hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0));
HPEN holdPen = (HPEN)SelectObject(hdc, hPen);
HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

Ellipse(hdc, 10 + 25, 10, 60 + 25, 60);

SelectObject(hdc, holdPen);
SelectObject(hdc, holdBrush);

DeleteObject(hPen);
DeleteObject(hBrush);
ReleaseDC(hWnd, hdc);

consoleInit();
ResumeThread(hThread1);
ResumeThread(hThread2);
}
break;
case IDB_BUTTON_STOP:
{
FreeConsole();
SuspendThread(hThread1);
SuspendThread(hThread2);

HDC hdc = GetDC(hWnd);
HPEN hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0));
HPEN holdPen = (HPEN)SelectObject(hdc, hPen);
HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0));
HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

Ellipse(hdc, 10 + 25, 10, 60 + 25, 60);

SelectObject(hdc, holdPen);
SelectObject(hdc, holdBrush);

DeleteObject(hPen);
DeleteObject(hBrush);
ReleaseDC(hWnd, hdc);
}
break;
case IDB_BUTTON_OPEN:
{

MessageBox(hWnd, TEXT("click113"), TEXT("prompt"), MB_OK | MB_ICONINFORMATION);
}
break;
case IDB_BUTTON_CLEAN:
{

MessageBox(hWnd, TEXT("click114"), TEXT("prompt"), MB_OK | MB_ICONINFORMATION);
}
default:
{
}
}
return TRUE;
}
};

class WinEdit
{
public:
WinEdit() {}
~WinEdit() {}
inline BOOL createEdit(HWND hWnd, INT x, INT y, INT width = 100, INT height = 50)
{
//创建edit编辑窗口,子窗口,可视,有边框,多行,识别enter为回车,失去焦点后光标不消失
m_hEdit = CreateWindow(WC_EDIT, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_WANTRETURN | ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
x, y, width, height, hWnd, NULL, NULL, NULL);
return TRUE;
}
// 追加文本函数
inline BOOL appendLogText(HWND hWndLog, LPCTSTR newText)
{
DWORD left, right;
int len = GetWindowTextLength(hWndLog);
SendMessage(hWndLog, EM_GETSEL, (WPARAM)&left, (LPARAM)&right);
SendMessage(hWndLog, EM_SETSEL, len, len);
SendMessage(hWndLog, EM_REPLACESEL, 0, (LPARAM)newText);
SendMessage(hWndLog, EM_SETSEL, left, right);
return TRUE;
}
HWND m_hEdit;
};

#define IDC_LIST_CLICK 401
class WinListView
{
public:
WinListView() {}
~WinListView() {}
inline BOOL createListView(HWND hWnd, INT x, INT y, HMENU IDC_LIST = NULL, INT width = 100, INT height = 50)
{
m_hListView = CreateWindow(WC_LISTVIEW, TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, x, y, width, height, hWnd, IDC_LIST, NULL, NULL);
ListView_SetExtendedListViewStyle(m_hListView, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_GRIDLINES);

RECT rect;
GetClientRect(hWnd, &rect);

colTime.mask |= LVCF_WIDTH | LVCF_TEXT;
colTime.cx = (rect.right - rect.left) * 0.15;
colTime.pszText = TEXT("time");
ListView_InsertColumn(m_hListView, 0, &colTime);

colContent.mask |= LVCF_WIDTH | LVCF_TEXT;
colContent.cx = (rect.right - rect.left) * 0.15;
colContent.pszText = TEXT("content");
ListView_InsertColumn(m_hListView, 1, &colContent);

for (int i = 0; i < 10; ++i)
{
ZeroMemory(&rowInfo, sizeof(rowInfo));
rowInfo.iItem = i;
ListView_InsertItem(m_hListView, &rowInfo);

TCHAR szBuffer[128];
StringCchPrintf(szBuffer, 128, TEXT("element %d"), i);
ListView_SetItemText(m_hListView, i, 0, szBuffer);
ListView_SetItemText(m_hListView, i, 1, szBuffer);
}

return TRUE;
}
inline BOOL onClick(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
// 判断点击的什么控件
NMHDR *pNmHdr = (NMHDR *)lParam;
if (pNmHdr->idFrom == IDC_LIST_CLICK)
{
if (pNmHdr->code == NM_CLICK)
{
// 判断哪一行哪一列
LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
TCHAR szText[128];
StringCchPrintf(szText, 128, TEXT("click is %d row %d col"), lpnmitem->iItem, lpnmitem->iSubItem);
// MessageBox(hWnd, szText, TEXT("WM_NOTIFY"), MB_OK);
}
}
return TRUE;
}
LVCOLUMN colTime = {0};
LVCOLUMN colContent = {0};
LVITEM rowInfo = {0};
HWND m_hListView;
};

class WinApp
{
public:
WinApp() {}
~WinApp() {}
virtual BOOL init(HINSTANCE hInstance, TCHAR title[])
{
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));

wc.cbClsExtra = 0; // 类的额外内存
wc.cbWndExtra = 0; // 窗口额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标 第一个为NULL代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标 第一个为NULL代表使用系统提供的图标
wc.hInstance = hInstance; // 应用程序实例句柄
wc.lpfnWndProc = WindowProc; // 回调函数
wc.lpszClassName = TEXT("main"); // 窗口类名称
wc.lpszMenuName = NULL; // 菜单名称
wc.style = CS_HREDRAW | CS_VREDRAW; // 显示风格

RegisterClass(&wc);
m_hWnd = CreateWindow(wc.lpszClassName, title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL, wc.hInstance, NULL);
CenterWindow(m_hWnd);
SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this); //使WindowProc能够访问this指针
RECT rect;
GetClientRect(m_hWnd, &rect);
this->clientWidth = rect.right - rect.left;
this->clientHeight = rect.bottom - rect.top;
this->clientSeparator = 10;

ShowWindow(m_hWnd, SW_SHOWNORMAL);
UpdateWindow(m_hWnd);

DWORD nID1 = 1;
DWORD nID2 = 2;
hThread1 = CreateThread(NULL, 0, ThreadProc1, (LPVOID) "********", CREATE_SUSPENDED, &nID1);
hThread2 = CreateThread(NULL, 0, ThreadProc2, (LPVOID) "--------", CREATE_SUSPENDED, &nID2);

return TRUE;
}
virtual BOOL CenterWindow(HWND hWnd)
{
INT scrWidth, scrHeight;
RECT rect;
//获得屏幕尺寸
scrWidth = GetSystemMetrics(SM_CXSCREEN);
scrHeight = GetSystemMetrics(SM_CYSCREEN);
//取得窗口尺寸
GetWindowRect(hWnd, &rect);
//重新设置rect里的值
long width = rect.right - rect.left;
long height = rect.bottom - rect.top;
rect.left = (scrWidth - width) / 2;
rect.top = (scrHeight - height) / 2;

//移动窗口到指定的位置
SetWindowPos(hWnd, HWND_TOP, rect.left, rect.top, width, height, SWP_NOSIZE | SWP_NOZORDER);
return TRUE;
}
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WinApp *pWinApp = (WinApp *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (pWinApp)
{
return pWinApp->wndProc(uMsg, wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// 因为static成员不能访问this 所以封装此方法
virtual LRESULT CALLBACK wndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_NCCREATE:
{
}
break;
case WM_CREATE:
{
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hWnd, &ps);
HPEN hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0));
HPEN holdPen = (HPEN)SelectObject(hdc, hPen);
HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0));
HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

Ellipse(hdc, 10 + 25, 10, 60 + 25, 60);

SelectObject(hdc, holdPen);
SelectObject(hdc, holdBrush);

DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(m_hWnd, &ps);
}
break;
case WM_SIZE:
{
MoveWindow(this->m_listView.m_hListView, 10, 70, LOWORD(lParam) * 0.3, HIWORD(lParam) - 80, TRUE);

int x = LOWORD(lParam) * 0.3 + clientSeparator * 2;
int cx = LOWORD(lParam) * 0.7 - clientSeparator * 3;
MoveWindow(this->m_edit.m_hEdit, x, 70, cx, HIWORD(lParam) - 80, TRUE);

ListView_SetColumnWidth(this->m_listView.m_hListView, 0, LOWORD(lParam) * 0.15);
ListView_SetColumnWidth(this->m_listView.m_hListView, 1, LOWORD(lParam) * 0.15);
}
break;
case WM_COMMAND:
{
this->m_button.onClick(m_hWnd, wParam, lParam);
}
break;
case WM_NOTIFY:
{
this->m_listView.onClick(m_hWnd, wParam, lParam);
}
break;
case WM_SYSCOMMAND:
{
if (wParam == SC_CLOSE)
{
int nRet = MessageBox(m_hWnd, TEXT("Do you want to quit?"), TEXT("prompt"), MB_YESNO | MB_ICONINFORMATION);
if (nRet != IDYES)
{
return 0;
}
}
}
break;
case WM_CLOSE:
{
DestroyWindow(m_hWnd);
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
default:
{
}
}
return DefWindowProc(m_hWnd, uMsg, wParam, lParam);
}
virtual BOOL run()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
// 如果按的是组合键 需要翻译
TranslateMessage(&msg);
// 单按一个键盘就直接分发消息
DispatchMessage(&msg);
}
return TRUE;
}

HWND m_hWnd;
HINSTANCE m_hInstance;

virtual BOOL Menu()
{
m_menu.createMenu(m_hWnd);
return TRUE;
}
virtual BOOL Button()
{
m_button.createButton(m_hWnd, TEXT("start"), 110, 10, (HMENU)IDB_BUTTON_START);
m_button.createButton(m_hWnd, TEXT("stop"), 220, 10, (HMENU)IDB_BUTTON_STOP);
m_button.createButton(m_hWnd, TEXT("open"), 330, 10, (HMENU)IDB_BUTTON_OPEN);
m_button.createButton(m_hWnd, TEXT("clean"), 440, 10, (HMENU)IDB_BUTTON_CLEAN);
return TRUE;
}
virtual BOOL Edit()
{
int x = this->clientWidth * 0.3 + clientSeparator * 2;
int y = 70;
int cx = this->clientWidth * 0.7 - clientSeparator * 3;
int cy = this->clientHeight - 100;
m_edit.createEdit(m_hWnd, x, y, cx, cy);
return TRUE;
}
virtual BOOL ListView()
{
int x = 10;
int y = 70;
int cx = this->clientWidth * 0.3;
int cy = this->clientHeight - 100;
m_listView.createListView(m_hWnd, x, y, (HMENU)IDC_LIST_CLICK, cx, cy);
return TRUE;
}
int clientWidth;
int clientHeight;
int clientSeparator;

WinMenu m_menu;
WinButton m_button;
WinEdit m_edit;
WinListView m_listView;
};

Author: chacebai
Link: http://www.spyhex.com/2019/2019-写一个Windows编程的WinMain函数模板/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.