1.消息的获取
GetMessage - 从系统获取消息,将消息从系统中移除,是阻塞函数。当系统无消息时,GetMessage会等候下一条消息。
PeekMessage - 以查看的方式从系统获取消息,可以不将消息从系统移除,是非阻塞函数。当系统无消息时,返回FALSE,继续执行后续代码。
BOOL PeekMessage( LPMSG lpMsg, //消息结构体指针
HWND hWnd, //窗口句柄
UINT wMsgFilterMin, //消息最小ID
UINT wMsgFilterMax, //消息最大ID
UINT wRemoveMsg); //移除标识
2.消息的发送
SendMessage - 发送消息,会等候消息处理的结果。
LRESULT SendMessage( HWND hWnd, //消息发送的目的窗口
UINT Msg, //消息ID
WPARAM wParam, //消息参数
LPARAM lParam); //消息参数
PostMessage - 投递消息,消息发出消息后立刻返回,不会等候消息的执行结果。
BOOL PostMessage( HWND hWnd, //消息发送的目的窗口
UINT Msg, //消息ID
WPARAM wParam, //消息参数
LPARAM lParam); //消息参数
windows系统中的所有消息都是这两个函数发出来的,无一例外。
3.消息的分类
(1)系统消息 - ID范围 0 - 0x03FF (0 - 1023)
由系统定义好的消息,可以在程序中直接使用。
(2)用户自定义消息 - ID范围 0x0400 - 0x7FFF(1024 - 32767)
#define WM_MYMESSAGE WM_USER(0x0400) + n
由用户自定义,满足用户自己的需求。由用户自己发出消息并响应处理。
(3)应用程序消息 - ID范围 0x8000 - 0xBFFF(32768 - 49151)
程序之间通讯时使用的消息。
应用程序消息宏:WM_APP
(4)系统注册消息 - ID范围 0xC000 - 0xFFFF(49152 - 65535)
在系统注册并生成响应消息,然后可以在各个程序中使用这个消息。
下面是示例代码:

#include "stdafx.h" #include <stdio.h> HINSTANCE g_hInstance = 0; //接收当前程序实例句柄 HANDLE g_hOutput = 0; //接收标准输出句柄 HWND g_hEdit = 0; //接收编辑框控件句柄 #define WM_MYMESSAGE WM_USER + 1001 void OnCreate(HWND hWnd, LPARAM lParam) { CREATESTRUCT* cs = (CREATESTRUCT*)lParam; char *pszText = (char*)cs->lpCreateParams; //MessageBox(hWnd, pszText, "Info", MB_OK); g_hEdit = CreateWindowEx(0, "EDIT", "OK", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 200, 200, hWnd, NULL, g_hInstance, NULL); PostMessage(hWnd, WM_MYMESSAGE, 1, 2); } void OnSize(HWND hWnd, LPARAM lParam) { int nWidth = LOWORD(lParam); int nHeight = HIWORD(lParam); char szText[256] = { 0 }; sprintf_s(szText, "宽:%d, 高:%d ", nWidth, nHeight); //MessageBox(hWnd, szText, "Info", MB_OK); WriteConsole(g_hOutput, szText, strlen(szText), NULL, NULL); MoveWindow(g_hEdit, 10, 10, nWidth-20, nHeight-20, TRUE); } void OnMyMessage(HWND hWnd, WPARAM wParam, LPARAM lParam) { char szText[256] = { 0 }; sprintf_s(szText, "wParam=%d, lParam=%d", wParam, lParam); MessageBox(hWnd, szText, "Info", MB_OK); } //窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_MYMESSAGE: OnMyMessage(hWnd, wParam, lParam); break; case WM_SIZE: OnSize(hWnd, lParam); break; case WM_CREATE: OnCreate(hWnd, lParam); break; case WM_DESTROY: //PostQuitMessage(0); //SendMessage(hWnd, WM_QUIT, 0, 0); //用SendMessage发送WM_QUIT,关闭窗口进程不会退出 PostMessage(hWnd, WM_QUIT, 0, 0); break; } return DefWindowProc(hWnd, msg, wParam, lParam); } //注册窗口类 BOOL Register(LPSTR lpClassName, WNDPROC wndProc) { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); wce.cbClsExtra = 200; wce.cbClsExtra = 200; 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 (0 == nAtom) { return FALSE; } return TRUE; } //创建主窗口 HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName) { HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, "hello create"); return hWnd; }//显示窗口 void Display(HWND hWnd) { ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); } //消息循环 void Message() { MSG nMsg = { 0 }; while (1) { if (PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE)) { //有消息 if (!GetMessage(&nMsg, NULL, 0, 0)) //是WM_QUIT消息 { return; } else { //不是WM_QUIT消息 TranslateMessage(&nMsg); DispatchMessage(&nMsg); } } else { //没消息(空闲处理) WriteConsole(g_hOutput, "OnIdle", 6, NULL, NULL); } } } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { AllocConsole();//给窗口程序添加一个附带的dows窗口 g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE); g_hInstance = hInstance; Register("Main", WndProc); HWND hWnd = CreateMainWindow("Main", "window"); Display(hWnd); Message(); return 0; }