MFC 随机矩形
问题描述:
简单地使用随即的尺寸和颜色不停的绘制一系列的图像。
一种古老的方式:
设置一个向窗口函数发送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); }