3.5 显示窗口。
创建了窗口之后,如果要想运行时能够看见窗口,我们还需要显式的设置显示窗口:ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
ShowWindow和UpdateWindow都是系统的API,前者是设置窗口的显示属性。后者重新更新窗口属性,只有更新之后,属性才会生效。经过了上述步骤,我们的WinMain函数已经变成了如下:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
//注册窗口类
WNDCLASSEX wce = { 0 };
wce.cbSize = sizeof(wce);
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = hInstance;
wce.lpfnWndProc = wndProc;
wce.lpszClassName = “Main”;
wce.lpszMenuName = NULL;
wce.style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
if (!nAtom )
{
MessageBox(NULL, "注册失败", "Infor", MB_OK);
return 0;
}
//创建窗口
HWND hWnd = CreateWindowEx(0, “Main”, “Window”, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL);
//显示窗口
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
}
3.6 开启消息循环
所谓的消息循环,其实就是一个死循环,不断的通过GetMessage捕捉着窗口的消息,再通过TranslateMessage将虚拟键消息转换为字符消息,然后通过DispatchMessage将消息分派给我们的窗口程序进行处理(所谓处理就是调用我们定义的窗口处理函数WinProc):
void Message()
{
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
完成了消息循环之后,我们最终的代码如下(这里面对窗口注册的程序进行了封装,但是过程是一致的):
#include<windows.h>
HINSTANCE g_hInstance = 0;
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);//可以使GetMessage返回0
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
WNDCLASSEX wce = { 0 };
wce.cbSize = sizeof(wce);
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = g_hInstance;
wce.lpfnWndProc = wndProc;
wce.lpszClassName = lpClassName;
wce.lpszMenuName = NULL;
wce.style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
if (nAtom == 0)
return FALSE;
return true;
}
//创建主窗口
HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName)
{
HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL);
return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
}
//消息循环
void Message()
{
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
// TODO: Place code here.
g_hInstance = hInstance;
BOOL nRet = Register("Main", WndProc);
if (!nRet)
{
MessageBox(NULL, "注册失败", "Infor", MB_OK);
return 0;
}
HWND hWnd = CreateMain("Main", "window");
Display(hWnd);
Message();
return 0;
}
就此我们完成了窗口处理的整个过程,运行程序,成功创建并显示的一个Windows窗口:
https ://github.com/HymanLiuTS/Win32SDK
克隆本项目:
Git clone git@github.com : HymanLiuTS / Win32SDK.git
获取本文源代码:
git checkout WL03