马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
知识点回顾:
1. PeekMessage 函数
一直以来,我们都是使用 GetMessage 函数为主导的这个循环来处理程序的消息队列。但 GetMessage 函数有一个问题,就是它比较执着……因为当消息队列中如果没有消息了,它也会一直在那等待,直到获取消息才返回。本来这也没什么问题,因为 Windows 的核心理念就是“Don’t call me, I will call you.”,我们只需要写好回调函数,然后等着消息触发来调用即可。
不过在有些时候,我们倒是希望应用程序能在空闲时做一些“业余”的事情。也就是说,当消息队列为空的时候,让我们的应用程序也可以执行一些操作。由于 GetMessage 函数会一直等到获取消息才交出控制权。所以,我们应该使用另外一个函数来代替。没错,就是 PeekMessage 函数。
PeekMessage 函数的一个特点就是无论是否从消息队列中获取消息,它总是立即返回。我们通过观察它的返回值来判断是否获取得到消息:如果返回值是非 0,那么说明已经从消息队列中取得消息;如果返回值为 0,则说明此时消息队列为空。
2. 使用 PeekMessage 函数改造消息循环
……
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // 偷窥
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// 让程序空闲时执行的代码
}
}
……
解释一下:
首先我们构造一个条件永远为真的死循环,因为 PeekMessage 函数不会因为接收到退出消息就返回 FALSE。所以我们后边需要明确检测 WM_QUIT 消息,如果拿到的消息是 WM_QUIT,则使用break语句退出循环,否则转换并分派消息。
3. 利用 PeekMessage 函数生成随机矩形
#include <windows.h>
#include <stdlib.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void DrawRectangle (HWND) ;
int cxClient, cyClient ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
……
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
DrawRectangle (hwnd) ;
}
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) ;
}
|