WM_PAINT与WM_ERASEBKGND
当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发送WM_PAINT消息.
如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.
当WM_PAINT由InvalidateRect产生时,先发送WM_PAINT消息(异步),如果InvalidateRect的bErase为TRUE,BeginPaint检查到更新区域需要删除背景,向窗口发送一个WM_ERASEBKGND消息,如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.
如果pt.fErase标记为TRUE,指示应用程序应该处理背景,但是应用程序不一定需要处理,pt.fErase只是作为一个标记.
补充:DefWindowProc(hWnd, message, wParam, lParam)处理WM_ERASEBKGND消息时默认用下面的画刷清除背景
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WM_ERASEBKGND返回TRUE和返回FALSE是一个规范,一般情况下没有什么区别,但是如果什么时候用到了,会根据函数返回值判断后续处理。因此最好按照要求返回数据.
最后再提供一些测试代码,让大家更好的理解上面的内容。
// WM_ERASEBKGNDTest.cpp : Defines the entry point for the application. //
#include \"stdafx.h\"
#include \"WM_ERASEBKGNDTest.h\" #define MAX_LOADSTRING 100 // Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg;
HACCEL hAccelTable; // Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WM_ERASEBKGNDTEST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) {
return FALSE; }
hAccelTable = LoadAccelerators(hInstance,
MAKEINTRESOURCE(IDC_WM_ERASEBKGNDTEST));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg); DispatchMessage(&msg); } }
return (int) msg.wParam; } //
// FUNCTION: MyRegisterClass() //
// PURPOSE: Registers the window class. //
// COMMENTS: //
// This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. //
ATOM MyRegisterClass(HINSTANCE hInstance) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_WM_ERASEBKGNDTEST)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // wcex.hbrBackground = NULL;
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WM_ERASEBKGNDTEST); wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } //
// FUNCTION: InitInstance(HINSTANCE, int) //
// PURPOSE: Saves instance handle and creates main window //
// COMMENTS: //
// In this function, we save the instance handle in a global variable and // create and display the main program window. //
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) {
return FALSE; }
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) //
// PURPOSE: Processes messages for the main window. //
// WM_COMMAND - process the application menu // WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return // //
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) {
case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) {
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break;
case IDM_EXIT: DestroyWindow(hWnd);
break; default:
return DefWindowProc(hWnd, message, wParam, lParam); } break;
case WM_LBUTTONDOWN: RECT rect;
GetClientRect(hWnd, &rect); InvalidateRect(hWnd, &rect, TRUE); MessageBeep(2); break;
//case WM_ERASEBKGND:
// OutputDebugString(_T(\"Enter WM_ERASEBKGND/n\")); // return 1; // break;
case WM_PAINT:
OutputDebugString(_T(\"Enter WM_PAINT/n\")); hdc = BeginPaint(hWnd, &ps); if (ps.fErase == TRUE)
OutputDebugString(_T(\"ps.fErase == TRUE/n/n\")); // TODO: Add any drawing code here... EndPaint(hWnd, &ps); break;
case WM_DESTROY: PostQuitMessage(0); break; default:
if (WM_ERASEBKGND == message)
OutputDebugString(_T(\"Enter WM_ERASEBKGND/n\")); return DefWindowProc(hWnd, message, wParam, lParam); }
// DefWindowProc(hWnd, message, wParam, lParam); return 0; }
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
UNREFERENCED_PARAMETER(lParam); switch (message) {
case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; }
return (INT_PTR)FALSE; }
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo0.com 版权所有 湘ICP备2023021991号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务