【OpenGL】七、桌面窗口搭建 ( 導(dǎo)入頭文件 | 桌面程序入口函數(shù) | 注冊窗口 | 創(chuàng)建窗口 | 顯示窗口 )
文章目錄
一、導(dǎo)入頭文件
二、桌面程序入口函數(shù)
三、注冊窗口
四、創(chuàng)建窗口
五、顯示窗口
六、完整代碼示例
七、相關(guān)資源
基于 【OpenGL】一、Visual Studio 2019 創(chuàng)建 Windows 桌面程序 ( Visual Studio Installer 安裝 C++ 桌面開發(fā)庫 | 創(chuàng)建桌面程序 ) 博客中創(chuàng)建的 Windows 桌面程序繼續(xù)向下講解 , Visual Studio 自動生成了空白的桌面程序 , OpenGL 系列開發(fā)基于該桌面程序進行 ;
本篇博客簡單介紹下該桌面初始化的操作 , 注冊桌面窗口 , 創(chuàng)建桌面窗口 , 顯示桌面窗口 ;
一、導(dǎo)入頭文件
Windows 窗口程序需要導(dǎo)入 windows.h 頭文件 ;
// Windows 頭文件 #include
1
2
下面的代碼時 Visual Studio 創(chuàng)建桌面程序時 , 自動生成的頭文件 , 其中包含了 windows.h 頭文件 ;
// header.h: 標(biāo)準(zhǔn)系統(tǒng)包含文件的包含文件, // 或特定于項目的包含文件 // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // 從 Windows 頭文件中排除極少使用的內(nèi)容 // Windows 頭文件 #include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
二、桌面程序入口函數(shù)
Windows 桌面程序的入口
是
wWinMain
函數(shù) ,
該函數(shù)相當(dāng)于命令行程序中的 void main() 函數(shù) ;
完整的 wWinMain 函數(shù)格式 :
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
1
2
3
4
三、注冊窗口
使用
WNDCLASSEXW
結(jié)構(gòu)體注冊窗口 ;
WNDCLASSEXW 結(jié)構(gòu)體代碼如下 :
typedef struct tagWNDCLASSEXW { UINT cbSize; /* Win 3.x */ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; /* Win 4.0 */ HICON hIconSm; } WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
下面是該結(jié)構(gòu)體各個字段的含義 :
style : 窗口風(fēng)格 ;
lpfnWndProc : 設(shè)置消息響應(yīng)函數(shù) , 如響應(yīng)鼠標(biāo) , 鍵盤事件 ;
cbWndExtra : 窗口是否需要額外空間 ;
hInstance : 窗口實體 , 通過桌面程序入口函數(shù)傳入 ;
hIcon : 生成的程序在文件夾中的樣式 , 可執(zhí)行程序的圖標(biāo)
hCursor : 設(shè)置鼠標(biāo)光標(biāo)樣式 ;
hbrBackground : 設(shè)置背景 ;
lpszMenuName : 設(shè)置菜單 ;
lpszClassName : 設(shè)置窗口標(biāo)識 ;
窗口注冊代碼示例 : 下面的代碼時 Visual Studio 自動身
// // 函數(shù): MyRegisterClass() // // 目標(biāo): 注冊窗口類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { // 注冊窗口的結(jié)構(gòu)體 WNDCLASSEXW wcex; // 設(shè)置結(jié)構(gòu)體的大小 wcex.cbSize = sizeof(WNDCLASSEX); // 窗口風(fēng)格 , CS 是 Class Style 縮寫 , VREDRAW 垂直重繪 , HREDRAW 水平重繪 wcex.style = CS_HREDRAW | CS_VREDRAW; // 消息響應(yīng)函數(shù) , 鼠標(biāo)點擊窗口 , 或打字字后的回調(diào)函數(shù) wcex.lpfnWndProc = WndProc; // 不需要額外的空間 wcex.cbClsExtra = 0; // 不需要額外的空間 wcex.cbWndExtra = 0; // 設(shè)置程序的實例, 通過桌面程序入口函數(shù)傳入 wcex.hInstance = hInstance; // 生成的程序在文件夾中的樣式 , 可執(zhí)行程序的圖標(biāo) wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL)); // 設(shè)置鼠標(biāo)光標(biāo)樣式 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // 設(shè)置背景 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 菜單 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL); // 窗口的唯一標(biāo)識符 wcex.lpszClassName = szWindowClass; // 設(shè)置窗口運行后顯示在右上角的圖標(biāo) wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // 設(shè)置完上述參數(shù)后 , 最后調(diào)用該方法注冊窗口 return RegisterClassExW(&wcex); }
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
四、創(chuàng)建窗口
調(diào)用 CreateWindowW 方法 , 創(chuàng)建 Windows 窗口 ,
創(chuàng)建完成之后 , 驗證下創(chuàng)建方法返回值 hWnd , 如果創(chuàng)建失敗 , 直接退出 ;
// 創(chuàng)建窗口的核心邏輯 HWND hWnd = CreateWindowW( szWindowClass, // 窗口主類 szTitle, // 窗口標(biāo)題名稱 WS_OVERLAPPEDWINDOW, // 窗口風(fēng)格 100 , // x 坐標(biāo) 100 , // y 坐標(biāo) 800, // 寬度 600, // 高度 nullptr, // 父窗口 nullptr, // 菜單 hInstance, // 程序?qū)嶓w nullptr); // 如果創(chuàng)建失敗 , 直接退出 if (!hWnd) { return FALSE; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
五、顯示窗口
創(chuàng)建完成后 , 顯示窗口 ;
// 顯示窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
1
2
3
六、完整代碼示例
Windows 窗口完整代碼 , 這是 Visual Studio 自動生成的代碼 ;
// OpenGL.cpp : 定義應(yīng)用程序的入口點。 // 窗口程序入口 // 代碼提交測試 #include "framework.h" #include "OpenGL.h" #define MAX_LOADSTRING 100 // 全局變量: HINSTANCE hInst; // 當(dāng)前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標(biāo)題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口類名 // 此代碼模塊中包含的函數(shù)的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此處放置代碼。 // 初始化全局字符串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_OPENGL, szWindowClass, MAX_LOADSTRING); // 注冊窗口 MyRegisterClass(hInstance); // 執(zhí)行應(yīng)用程序初始化: // 創(chuàng)建窗口 if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // 下面的邏輯是一個死循環(huán) , 避免讓窗口退出 HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGL)); MSG msg; // 主消息循環(huán): while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函數(shù): MyRegisterClass() // // 目標(biāo): 注冊窗口類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { // 注冊窗口的結(jié)構(gòu)體 WNDCLASSEXW wcex; // 設(shè)置結(jié)構(gòu)體的大小 wcex.cbSize = sizeof(WNDCLASSEX); // 窗口風(fēng)格 , CS 是 Class Style 縮寫 , VREDRAW 垂直重繪 , HREDRAW 水平重繪 wcex.style = CS_HREDRAW | CS_VREDRAW; // 消息響應(yīng)函數(shù) , 鼠標(biāo)點擊窗口 , 或打字字后的回調(diào)函數(shù) wcex.lpfnWndProc = WndProc; // 不需要額外的空間 wcex.cbClsExtra = 0; // 不需要額外的空間 wcex.cbWndExtra = 0; // 設(shè)置程序的實例, 通過桌面程序入口函數(shù)傳入 wcex.hInstance = hInstance; // 生成的程序在文件夾中的樣式 , 可執(zhí)行程序的圖標(biāo) wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL)); // 設(shè)置鼠標(biāo)光標(biāo)樣式 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // 設(shè)置背景 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 菜單 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL); // 窗口的唯一標(biāo)識符 wcex.lpszClassName = szWindowClass; // 設(shè)置窗口運行后顯示在右上角的圖標(biāo) wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // 設(shè)置完上述參數(shù)后 , 最后調(diào)用該方法注冊窗口 return RegisterClassExW(&wcex); } // // 函數(shù): InitInstance(HINSTANCE, int) // // 目標(biāo): 保存實例句柄并創(chuàng)建主窗口 // // 注釋: // // 在此函數(shù)中,我們在全局變量中保存實例句柄并 // 創(chuàng)建和顯示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 將實例句柄存儲在全局變量中 // 創(chuàng)建窗口的核心邏輯 HWND hWnd = CreateWindowW( szWindowClass, // 窗口主類 szTitle, // 窗口標(biāo)題名稱 WS_OVERLAPPEDWINDOW, // 窗口風(fēng)格 100 , // x 坐標(biāo) 100 , // y 坐標(biāo) 800, // 寬度 600, // 高度 nullptr, // 父窗口 nullptr, // 菜單 hInstance, // 程序?qū)嶓w nullptr); // 如果創(chuàng)建失敗 , 直接退出 if (!hWnd) { return FALSE; } // 顯示窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函數(shù): WndProc(HWND, UINT, WPARAM, LPARAM) // // 目標(biāo): 處理主窗口的消息。 // // WM_COMMAND - 處理應(yīng)用程序菜單 // WM_PAINT - 繪制主窗口 // WM_DESTROY - 發(fā)送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 分析菜單選擇: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此處添加使用 hdc 的任何繪圖代碼... EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “關(guān)于”框的消息處理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
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
七、相關(guān)資源
GitHub 地址 : https://github.com/han1202012/OpenGL
博客源碼快照 : https://download.csdn.net/download/han1202012/14503846
OpenGL Windows
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。