Windows消息循环(Windows Message Loop)
在Windows操作系统中,一个程序通过不断地接收和处理消息来保持活动状态的一种机制。在Windows编程中,消息循环是处理用户输入、操作系统事件和其他消息的关键部分。
在Windows应用程序中,用户与程序交互时,比如点击鼠标、按键盘键等,操作系统会生成相应的消息,并将这些消息发送给程序。程序通过消息循环来接收并处理这些消息,然后做出相应的响应。消息循环通常位于程序的主线程中,不断地等待并处理消息,从而实现用户界面的交互和响应。
步骤与主要函数
消息获取(GetMessage): 程序调用GetMessage函数从消息队列中获取消息。如果消息队列中没有消息,程序会等待直到有消息到来。
消息分发(DispatchMessage): 获取到消息后,程序通常会将消息传递给DispatchMessage函数,该函数负责将消息分发给相应的窗口过程(Window Procedure)。
窗口过程处理消息(Window Procedure): 窗口过程是一个回调函数,它定义了窗口如何处理不同类型的消息。当消息循环传递消息给窗口过程时,窗口过程会根据消息类型执行相应的操作,比如更新界面、响应用户输入等。
消息循环继续: 处理完消息后,程序会回到消息循环的开始,等待下一条消息的到来。
代码案例
#include <windows.h>
#include <stdio.h>
LPCTSTR clsName = "My";
LPCTSTR msgName = "欢迎学习";
LRESULT CALLBACK MyWinProc(
HWND unnamedParam1,
UINT unnamedParam2,
WPARAM unnamedParam3,
LPARAM unnamedParam4
);
// 1.设计一个窗口类
// 2.注册窗口类
// 3.创建窗口类
// 4.显示以及更新窗口
// 5.循环等待消息
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
// 定义和配置窗口对象
WNDCLASS wndcls;
wndcls.cbClsExtra = NULL;
wndcls.cbWndExtra = NULL;
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndcls.hInstance = hInstance;
// 交互响应
wndcls.lpfnWndProc = MyWinProc;
// 定义窗口代号
wndcls.lpszClassName = clsName;
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
// 注册窗口类
RegisterClass(&wndcls);
// 创建窗口
HWND hwnd;
hwnd = CreateWindow(clsName, msgName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//显示和刷新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg,NULL, NULL, NULL)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MyWinProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
HDC hdc;
int ret;
switch (uMsg)
{
case WM_CHAR:
char szChar[20];
sprintf_s(szChar, "按下:%c", wParam);
MessageBox(hwnd, szChar, "char", NULL);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "左键", "left", NULL);
break;
case WM_RBUTTONDOWN:
break;
case WM_PAINT:
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 0, "www.baidu,com", strlen("www.baidu.com"));
EndPaint(hwnd, &ps);
MessageBox(hwnd, "重绘", "left", NULL);
break;
case WM_CLOSE:
ret = MessageBox(hwnd, "是否结束", "left", MB_YESNO);
if (ret == IDYES) {
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}