Windows窗口消息实例详解
简介
在 Windows 操作系统中,窗口消息是非常重要的概念。这些消息包括用户输入、系统通知以及应用程序间的通信等信息。理解窗口消息的处理方式对于开发 Windows 应用程序非常重要。
本篇文章将详细探讨 Windows 窗口消息的处理,并提供两个实例来帮助理解。
窗口消息的处理方式
消息循环
窗口消息是通过消息循环机制进行处理的。在消息循环中,程序会不断地从消息队列中取出消息,并把它们分发给相应的窗口进行处理。
Windows 应用程序中的主消息循环可以简单地描述为以下的代码:
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
该代码段中,GetMessage 函数从消息队列中获取一个消息,并将其存储在 msg 变量中。然后,TranslateMessage 函数用于将一些特定的键盘消息(如 WM_KEYDOWN、WM_KEYUP 等)翻译成对应的字符消息,最后 DispatchMessage 函数将该消息发送给目标窗口的窗口回调函数(即 WndProc)进行处理。
窗口回调函数
每个窗口都有一个窗口过程函数(即窗口回调函数),该函数用于处理窗口收到的消息。在窗口创建时,可以为窗口指定一个回调函数。
回调函数的模板如下所示:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// 处理各种消息
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
其中,hWnd 参数代表目标窗口的句柄,message 参数代表窗口收到的消息类型,wParam 和 lParam 参数则是消息的参数。
在窗口过程函数中,常常使用 switch 语句来处理各种类型的消息,如 WM_PAINT、WM_SIZE、WM_CLOSE 等。
处理用户输入
窗口消息中的一种很重要的消息类型是用户输入,如鼠标、键盘等。使用窗口回调函数可以方便地处理这些消息。
以下是一个处理鼠标输入消息的示例(仅提供代码片段):
switch (message)
{
case WM_LBUTTONDOWN:
//鼠标左键按下的处理代码
break;
case WM_LBUTTONUP:
//鼠标左键释放的处理代码
break;
case WM_MOUSEMOVE:
//鼠标移动的处理代码
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
在该示例中,当收到 WM_LBUTTONDOWN 消息时,会执行鼠标左键按下的处理代码。其他类型的鼠标消息也可以在 switch 语句中进行处理。
示例一:创建一个窗口
以下是一个创建一个简单窗口的示例代码:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// 注册窗口类
WNDCLASS wc = { 0 };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"WindowClass";
RegisterClass(&wc);
// 创建窗口
HWND hWnd = CreateWindow(
L"WindowClass",
L"Hello, Windows!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 300,
NULL, NULL,
hInstance, NULL
);
// 显示窗口
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, L"Hello, Windows!", 16);
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
在该示例中,我们首先注册了一个名为 "WindowClass" 的窗口类,然后创建了一个名为 "Hello, Windows!" 的窗口。在消息循环中,我们将窗口消息发送到 WndProc 函数进行处理。
在 WndProc 函数中,我们使用了 switch 语句来处理收到的不同类型消息。其中,在 WM_PAINT 消息种我们使用 TextOut 函数向窗口绘制了一些文本,在 WM_CLOSE 和 WM_DESTROY 消息中则分别销毁了窗口和退出程序。
示例二:向窗口发送自定义消息
以下是一个向窗口发送自定义消息的示例:
#include <Windows.h>
#define WM_MY_MESSAGE (WM_USER + 1)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// 注册窗口类
WNDCLASS wc = { 0 };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"WindowClass";
RegisterClass(&wc);
// 创建窗口
HWND hWnd = CreateWindow(
L"WindowClass",
L"Hello, Windows!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 300,
NULL, NULL,
hInstance, NULL
);
// 显示窗口
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
// 发送自定义消息
SendMessage(hWnd, WM_MY_MESSAGE, 0, 0);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MY_MESSAGE:
MessageBox(hWnd, L"This is my message!", L"Message", MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, L"Hello, Windows!", 16);
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
在该示例中,我们向窗口发送一个自定义的消息 WM_MY_MESSAGE,并在 WndProc 函数中将该消息与一个 MessageBox 进行关联。当收到该消息时,程序将会弹出一个包含字符串 "This is my message!" 的对话框。
结论
对于 Windows 应用程序开发,理解窗口消息的处理方式是非常必要的。本文探讨了消息循环、窗口回调函数以及事实中的两个示例,并希望这可以提高读者对 Windows 窗口消息的理解能力。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Windows窗口消息实例详解 - Python技术站