问题描述:
简单地使用随即的尺寸和颜色不停的绘制一系列的图像。
一种古老的方式:
设置一个向窗口函数发送WM_TIMER消息的windows计时器。
对每个WM_TIMER消息,调用GetDC函数获取设备环境,然后绘制一个随机矩形,接着调用ReleaseDC函数释放设备环境。
方法弊端:
程序不能很快的绘制随机矩形,必须等待每个WM_TIMER消息,会依赖于系统时钟的精度
新函数:
PeekMessage(&msg,NULL,0,0,PM_REMOVE);这个函数允许一个程序检查程序队列中的下一个消息,而不是真实的获取并删除它看到的消息。
正常的循环消息:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
替换后的循环消息:
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
DrawRctangle(hWnd);
}
在这里,必须明确检查WM_QUIT消息。在一个正常的消息循环中,不需要这样做。
因为正常的GetMessage返回值是false(0),但是PeekMessage的返回值是队列中有没有消息,因此检查wm_quit是必要的。
源文件代码:
// peekmessage.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "peekmessage.h"
#include <Windows.h>
#include <stdlib.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawRctangle(HWND);
int cxClient,cyClient;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: 在此放置代码。
HWND hWnd;
static TCHAR szAppName[] = TEXT("RandRect");
MSG msg;
WNDCLASS wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PEEKMESSAGE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szAppName;
if (!RegisterClass(&wcex))
{
MessageBox(NULL,TEXT("this program requires Windows ",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,nCmdShow);
UpdateWindow(hWnd);
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
DrawRctangle(hWnd);
}
return (int) msg.wParam;
}
void DrawRctangle(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);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(wParam);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}