利用Windows空闲时间绘制随机大小和颜色的矩形


Windows 有很多的 “ 空闲时间 ”,在这期间所有的消息队列都是空的,Windows 就在等待键盘或者鼠标的输入。 那么能否在空闲期间从某种程度上获取控制并绘制随机矩形,而一旦有消息加载到程序的消息队列,就释放控制呢?这正是 PeekMessage 函数的 ” 用武之地 “

PeekMessage

The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

BOOL PeekMessage(
  LPMSG lpMsg,         // message information
  HWND hWnd,           // handle to window
  UINT wMsgFilterMin,  // first message
  UINT wMsgFilterMax,  // last message
  UINT wRemoveMsg      // removal options
);
Parameters
lpMsg
[out] Pointer to an MSG structure that receives message information.
hWnd
[in] Handle to the window whose messages are to be examined.
wMsgFilterMin
[in] Specifies the value of the first message in the range of messages to be examined.
wMsgFilterMax
[in] Specifies the value of the last message in the range of messages to be examined.
wRemoveMsg
[in] Specifies how messages are handled. This parameter can be one of the following values.
ValueMeaning
PM_NOREMOVEMessages are not removed from the queue after processing by PeekMessage.
PM_REMOVEMessages are removed from the queue after processing by PeekMessage.

You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or PM_REMOVE. This flag prevents the system from releasing any thread that is waiting for the caller to go idle (see WaitForInputIdle).

By default, all message types are processed. To specify that only certain message should be processed, specify one of more of the following values.

ValueMeaning
PM_QS_INPUTWindows 98, Windows 2000: Process mouse and keyboard messages.
PM_QS_PAINTWindows 98, Windows 2000: Process paint messages.
PM_QS_POSTMESSAGEWindows 98, Windows 2000: Process all posted messages, including timers and hotkeys.
PM_QS_SENDMESSAGEWindows 98, Windows 2000: Process all sent messages.

Return Values

If a message is available, the return value is nonzero.

If no messages are available, the return value is zero. 



有了这个 PeekMessage 函数,我们只需简单修改一下正常的消息循环,如下:

while (TRUE)
{
if(PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
[ other program lines to do some work ]
}
return msg.wParam;


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

注意:在这里,必须明确检查 WM_QUIT 消息,在一个正常的消息循环中,不需要这样做,因为当获取一个 WM_QUIT 消息时, GetMessage 函数返回值是 FALSE ( 0 ) 。但是 PeekMessage 函数的返回值是队列中是否有消息,因此检查 WM_QUIT 是必要的。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


源代码:
#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, LPSTR lpCmdLine, int nShowCmd )
{
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 = LoadIcon (NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName =szAppName ;
wndclass.lpszMenuName =NULL ;


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,nShowCmd);
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);
}
return msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SIZE:
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
return 0;


case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,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);
}


运行结果:



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值