创建窗口后,要对窗口的行为负责。操作系统不断的向应用程序发送消息,通知它发生了什么事情。
当Widnows向程序发送消息时,它调用程序中的一个函数,这个函数的参数精确地描述了Windows发送的消息。
在程序中称其为窗口函数或消息处理函数。它是一个自定义的回调函数。原型如下:
LRESULT CALLBACK WindowProc(HWND hwnd,UINT hMsg,WPARAM wParam,LPARAM lParam);
1、注册窗口类RegisterClassEx
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
wndclass.hIconSm = NULL;
::RegisterClassEx(&wndclass);
......
}
2、创建窗口CreateWindowEx
//创建主窗口
HWND hWnd = ::CreateWindowEx(0,
szClassName,//类名
"我的第一个GUI程序",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (NULL == hWnd) {
::MessageBox(NULL, "创建窗口失败", "错误", MB_OK);
return -1;
}
3、在桌面显示窗口ShowWindow
//显示窗口
::ShowWindow(hWnd, nCmdShow);
4、更新窗口客户区UpdateWindow
::UpdateWindow(hWnd);
5、进入消息获取和处理的循环。
首先是获取消息GetMessage,如果有消息到达,则将消息分派到回调函数处理DispatchMessage,如果是WM_QUIT,则GetMessage返回FALSE,则整个消息循环结束。消息的具体处理过程在MainWndProc函数中进行。
//从操作系统的消息队列中不断的捡取消息
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
//转化键盘消息
::TranslateMessage(&msg);
// 将消息发送到相应的窗口函数
::DispatchMessage(&msg);
}
// 当GetMessage返回0时,程序结束
return msg.wParam;
6、回调函数
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_DESTROY: // 正在销毁窗口
// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
::PostQuitMessage(0);
return 0;
}
// 将我们不处理的消息交给操作系统默认处理。
return ::DefWindowProc(hWnd, message, wparam, lparam);
}
1、实例
#include
#include
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
wndclass.hIconSm = NULL;
::RegisterClassEx(&wndclass);
//创建主窗口
HWND hWnd = ::CreateWindowEx(0,
szClassName,//类名
"我的第一个GUI程序",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (NULL == hWnd) {
::MessageBox(NULL, "创建窗口失败", "错误", MB_OK);
return -1;
}
//显示窗口
::ShowWindow(hWnd, nCmdShow);
::UpdateWindow(hWnd);
//从操作系统的消息队列中不断的捡取消息
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, message, wparam, lparam);
}
2、运行结果