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;
}