c++ WM_PAINT

c++win32响应WM_PAINT时,为什么必须用BeginPaint来获取dc,能不能用GetDC,这两种有什么区别#include<windows.h>HINSTA... c++ win32
响应WM_PAINT时,为什么必须用BeginPaint来获取dc,能不能用GetDC,这两种有什么区别

#include <windows.h>
HINSTANCE g_hInstance;
void myDraw(HWND hwnd,HDC dc)
{
RECT rect;
GetClientRect(hwnd, &rect);
HDC hdcmem=::CreateCompatibleDC(dc);

HBITMAP hbitmap=::CreateCompatibleBitmap(dc,rect.right,rect.bottom);
::SelectObject(hdcmem,hbitmap);
::FillRect(hdcmem,&rect,NULL);
::Rectangle(hdcmem,0,0,rect.right,rect.bottom);
::BitBlt(dc,0,0,rect.right,rect.bottom,hdcmem,0,0,SRCCOPY);
::DeleteObject(hbitmap);
::DeleteDC(hdcmem);
}

LRESULT CALLBACK WindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{

case WM_PAINT:
HDC dc;
dc=::GetDC(hwnd);//如果这里用BeginPaint来获取dc,运行的结果就差太多了
myDraw(hwnd,dc);
::ReleaseDC(hwnd,dc);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_hInstance=hInstance;
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hIcon=NULL;
wndcls.lpszMenuName=NULL;
wndcls.hbrBackground=NULL;
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WindowProc;
wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wndcls.lpszClassName="Window";
wndcls.style=CS_DBLCLKS;
RegisterClass(&wndcls);

HWND hwnd;
hwnd=CreateWindow("Window","",WS_OVERLAPPEDWINDOW,100,100,400,300,NULL,NULL,hInstance,NULL);

ShowWindow(hwnd,SW_SHOWNORMAL);

MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
请高人指点
展开
 我来答
jimmy14888888
2015-08-12 · TA获得超过1340个赞
知道小有建树答主
回答量:550
采纳率:80%
帮助的人:359万
展开全部

  第一种情况显示出来的字很正常。

case WM_PAINT: 
           gdc = BeginPaint (hwnd, &ps); 
           TextOut (gdc, 0, 0, s, strlen (s)); 
           break;

  第二种情况显示 的字不停闪烁。

case WM_PAINT: 
           gdc = GetDC (hwnd);
           TextOut (gdc, 0, 0, s, strlen (s)); 
           ReleaseDC (hwnd, gdc); 
break;

  原因在于:

  BeginPaint() 和EndPaint() 可以删除消息队列中的WM_PAINT消息,并使无效区域有效。
GetDC()和 ReleaseDC()并不删除也不能使无效区域有效,因此当程序 跳出 WM_PAINT 时 ,无效区域仍然存在。系统 就回不断发送WM_PAINT消息,于是程序不断处 理WM_PAINT消息。
BeginPaint、 EndPaint会告诉GDI内部,这个窗口 需要重画的地方已经重画了,这样WM_PAINT处 理完返回给系统后,系统不会再重发WM_PAINT,而GetDC没有告诉系统这个窗口需要重画的地方已经画过,在你把程序返回给系统后,系统一直以为通 知你的重画命令你还没有乖乖的执行或者执行出错,所以在消息空闲时,它还会不断地发WM_PAINT催促你画,导致程序卡死。


无效区域就是指需要重画的区域,无效的意思是:当前内容是旧的,过时的。 
假设A是新弹出的一个对话框或被 激活的现有对话框,A对话框置于原来的活动 对话框B前面,造成对话框B的部分或全部被覆盖,当 对话框A移开或关闭后,使对话框B原来被覆盖的地方重新可见。那部分被覆盖的地方就称为无效区域。 
只 有当一个窗口消息空闲时,系统才会抽空检查一下这个窗口的无效区域是否为非空(WM_PAINT的优先级是最低的。这也就是为什么系统很忙时窗口和桌面往 往会出现变白、刷新不了、留拖拽痕迹等现象的原因),如果非空,系统就发送WM_PAINT。所以一定要用BeginPaint、EndPaint把无效 区域设为空,否则WM_PAINT将一直被发送。

本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式