C++程序编程中的WM_PAINT、WM_ERASEBKGND、InvalidateRect、UpdateWindow、BeginPaint和EndPaint详解

本文详细介绍了Windows编程中的WM_PAINT消息的产生,WM_ERASEBKGND消息的作用,InvalidateRect和UpdateWindow的功能,以及何时使用BeginPaint和EndPaint进行窗口自绘。内容涵盖WM_PAINT的产生场景、无效区域的处理、强制窗口刷新的方法以及避免闪烁的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、WM_PAINT消息的产生

2、WM_ERASEBKGND消息说明

3、InvalidateRect和UpdateWindow

4、何时使用BeginPaint和EndPaint?


       在做Windows应用程序开发时,我们要处理多个Windows窗口消息,其中WM_PAINT窗口绘制消息在我们自绘窗口时会频繁地用到。有很多新人遇到与WM_PAINT消息相关的InvalidateRect、UpdateWindow、BeginPaint、EndPaint等函数时,会有很多疑惑,搞不清楚它们之间的关系,今天就来详细地给大家讲述一下这方面的内容。

1、WM_PAINT消息的产生

       WM_PAINT消息是系统产生的,应用程序是不能给窗口发送该消息的。系统会去定期检测窗口中是否有无效区域,如果有则系统会产生一个WM_PAINT消息,并将消息放置到窗口所属线程的消息队列中。然后消息循环从消息队列中取出WM_PAINT消息,派发给对应的窗口:

 这样消息就进入了窗口的窗口处理过程函数,进而执行到处理WM_PAINT消息的代码。

      那什么时候窗口才会有无效区域呢?有很多场景会使窗口产生无效区域。比如窗口初次创建时整个窗口区域都是无效的,需要去绘制;当目

#include <Windows.h> #include <math.h> #include <time.h> #include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void DrawClock(HDC hdc, RECT rect); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT(“Clock”); HWND hWnd; MSG msg; WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; if (!RegisterClass(&wc)) { MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hWnd = CreateWindow(szAppName, TEXT("Analog Clock"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: SetTimer(hWnd, 1, 1000, NULL); break; case WM_TIMER: InvalidateRect(hWnd, NULL, TRUE); break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rect; GetClientRect(hWnd, &rect); DrawClock(hdc, rect); EndPaint(hWnd, &ps); } break; case WM_DESTROY: KillTimer(hWnd, 1); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } void DrawHand(HDC hdc, int cx, int cy, double angle, int length, int width, COLORREF color) { double radians = (angle - 90.0) * 3.1415926535 / 180.0; int x = cx + (int)(length * cos(radians)); int y = cy + (int)(length * sin(radians)); HPEN hPen = CreatePen(PS_SOLID, width, color); HPEN hOldPen = (HPEN)
03-14
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dvlinker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值