PeekMessage与GetMessage的对比:
1.相同点:
PeekMessage函数与GetMessage函数都用于查看应用程序消息队列,有消息时将队列中的消息派发出去。
2.不同点:
无论应用程序消息队列是否有消息,PeekMessage函数都立即返回,程序得以继续执行后面的语句(无消息则执行其它指令,有消息时一般要将消息派发出去,再执行其它
指令)。GetMessage函数只有在消息队列中有消息时返回,队列中无消息就会一直等,直至下一个消息出现时才返回。在等的这段时间,应用程序不能执行任何指令。
(从他们的不同点上来看,PeekMessage函数有点像“乞丐行乞”,有你就施舍点,没有也不强求。GetMessage函数有点像“强盗打劫”,有你得给,没有我就等你什么时候有了再给,这段时间我什么都不干,我就等你。)
下面的程序用来在窗体内画随机生成的矩形,分别使用PeekMessage函数和GetMessage函数实现,读者可以种实际效果看出他们两者的区别。
#include <windows.h> #include <stdlib.h> // for the rand function LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; void DrawRectangle (HWND) ; int cxClient, cyClient ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("RandRect") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; 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 = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Random Rectangles"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; //用于替换的部分 //while (TRUE) //{ // if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) // { // if (msg.message == WM_QUIT) // break ; // TranslateMessage (&msg) ; // DispatchMessage (&msg) ; // } // else // DrawRectangle (hwnd) ; //} while (TRUE) { if (GetMessage (&msg, NULL, 0, 0)) { if (msg.message == WM_QUIT) break ; TranslateMessage (&msg) ; DispatchMessage (&msg) ; DrawRectangle (hwnd) ; } else break; } //用于替换的部分 return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } void DrawRectangle (HWND hwnd) { HBRUSH hBrush ; HDC hdc ; RECT rect ; if (cxClient == 0 || cyClient == 0) return ; SetRect (&rect, rand () % cxClient, rand () % cyClient, rand () % cxClient, rand () % cyClient) ; hBrush = CreateSolidBrush ( RGB (rand () % 256, rand () % 256, rand () % 256)) ; hdc = GetDC (hwnd) ; FillRect (hdc, &rect, hBrush) ; ReleaseDC (hwnd, hdc) ; DeleteObject (hBrush) ; }
以上程序用PeekMessage函数实现,在应用程序消息队列没有消息时,随机生成的矩形
将坚持不懈地画下去。当有消息产生时,PeekMessage函数获取并派发消息出去,然后
继续画随机生成的矩形。
下面部分代码用于替换WinMain函数中“用于替换的部分”的代码。
while (TRUE) { if (GetMessage (&msg, NULL, 0, 0)) { if (msg.message == WM_QUIT) break ; TranslateMessage (&msg) ; DispatchMessage (&msg) ; DrawRectangle (hwnd) ; } else break; }
替换后,应用程序产生一个消息(鼠标移动、改变窗体大小等),在窗体内画一个随
机生成的矩形,无消息产生时,窗体无变化。