一个基于Dialog的测试程序的OpPaint部分,VC2005SP1,XP下编程void CTest2Dlg::OnPaint()
{
//计算运行了多少次
m_Counter++; //转换成字符串缓冲
TCHAR buf[10];
memset(buf,0,10*sizeof(TCHAR));
int a=_itot_s(m_Counter,buf,10);
//InvalidateRect(NULL,true); //我发现这个地方如果屏蔽跟不屏蔽是不一样的。 //在界面上绘制
PAINTSTRUCT ps;
BeginPaint(&ps);
::TextOut(ps.hdc,0,0,buf,(int)_tcslen(buf));
EndPaint(&ps); //下面是VC自动加的代码。
if (IsIconic())
{
/*这里是VC自动加的代码*/
}
else
{
CDialog::OnPaint();
}
}
我的想法是:
1.InvalidateRect(NULL,true); 如果屏蔽,本人试验的结果是相当于 InvalidateRect(NULL,false) ,Dialog客户区左上角输出数字自动增加而且白底黑字。
2.InvalidateRect(NULL,true); 不屏蔽,Dialog客户区左上角应该是什么都没有的。显示情况是:
1.InvalidateRect(NULL,true); 屏蔽的时候,Dailog客户区左上角的确有白底黑字的输出,这个跟理论情况一样。
2.InvalidateRect(NULL,true); 不屏蔽的时候,Dialog客户区左上角的是背景跟Dialog背景一样的,黑色数字的输出。
看上去有点背景透明的感觉。我的问题:
1,第二种情况是怎么产生的呢?为什么跟理论部一样
2. MSDN上说InvalidateRect(NULL,true);这个时候BeginPaint会清空界面,而很多书上有说系统默认的画刷是白色的,为什么这个时候Dialog的客户区还是系统窗口的颜色?
3.InvalidateRect(NULL,true); 如果屏蔽是否真的相当于 InvalidateRect(NULL,false);感谢高手们。
{
//计算运行了多少次
m_Counter++; //转换成字符串缓冲
TCHAR buf[10];
memset(buf,0,10*sizeof(TCHAR));
int a=_itot_s(m_Counter,buf,10);
//InvalidateRect(NULL,true); //我发现这个地方如果屏蔽跟不屏蔽是不一样的。 //在界面上绘制
PAINTSTRUCT ps;
BeginPaint(&ps);
::TextOut(ps.hdc,0,0,buf,(int)_tcslen(buf));
EndPaint(&ps); //下面是VC自动加的代码。
if (IsIconic())
{
/*这里是VC自动加的代码*/
}
else
{
CDialog::OnPaint();
}
}
我的想法是:
1.InvalidateRect(NULL,true); 如果屏蔽,本人试验的结果是相当于 InvalidateRect(NULL,false) ,Dialog客户区左上角输出数字自动增加而且白底黑字。
2.InvalidateRect(NULL,true); 不屏蔽,Dialog客户区左上角应该是什么都没有的。显示情况是:
1.InvalidateRect(NULL,true); 屏蔽的时候,Dailog客户区左上角的确有白底黑字的输出,这个跟理论情况一样。
2.InvalidateRect(NULL,true); 不屏蔽的时候,Dialog客户区左上角的是背景跟Dialog背景一样的,黑色数字的输出。
看上去有点背景透明的感觉。我的问题:
1,第二种情况是怎么产生的呢?为什么跟理论部一样
2. MSDN上说InvalidateRect(NULL,true);这个时候BeginPaint会清空界面,而很多书上有说系统默认的画刷是白色的,为什么这个时候Dialog的客户区还是系统窗口的颜色?
3.InvalidateRect(NULL,true); 如果屏蔽是否真的相当于 InvalidateRect(NULL,false);感谢高手们。
解决方案 »
- 2012第一帖
- ftp下载同一个IP建立多个数据连接的问题?请教高手, 在线等!!
- 如何在Edit Box里面追加显示字符串呢?
- #pragma是什么的缩写?
- 请教有开发经验的前辈:为了节省空间,您是否这么用过vector?
- 请问有谁知道那些程序能在windows下看linux,unix的桌面。
- 13个球中有一个是假的,用天平三次称出!那个问题怎么解决的?
- 关于CHotKeyCtrl的问题
- 求助CPropertySheet构造函数问题??
- ____你的IE被网站黑后,可以用这个小程序改回来__
- 请问谁会mfc? 我想编写关于学生选课管理的程序!! 请指导!
- 有关Bitmap类FromFile的问题以及怎么对一幅图片进行连续修改?
有两次绘画过程,第二次绘画把第一次覆盖了
BeginPaint(&ps);
EndPaint(&ps);
否则,OnPaint里面直接return 0;是会死循环的。但我觉得这两步是在OnPaint之后的,
因为只要在OnPaint里面加ValidateRect(NULL);界面就没有被绘制了。这说明因为ValidateRect(NULL);后程序欺骗windows的更新区域已经消失,BeginPaint就没产生或者失效了。
首先感谢 shuigsls 的关注,我觉得两次这个是有一定道理的,能说得再清楚一点么?
我试过做一个按钮,然后OnLButtonDown事件里面就只有
InvalidateRect( NULL, TRUE );
结果发现
1.InvalidateRect( NULL, FALSE); 跟InvalidateRect(NULL,true); 被屏蔽的时候,现象一样。
2.InvalidateRect(NULL,true); 跟InvalidateRect(NULL,true); 没被屏蔽的时候,现象一样。
根据你说的情况我尝试了一下,发现会触发两次的ERASEBKGND 但我的问题还是没有解决。我的问题:
1,第二种情况是怎么产生的呢?为什么跟理论部一样
2. MSDN上说InvalidateRect(NULL,true);这个时候BeginPaint会清空界面,而很多书上有说系统默认的画刷是白色的,为什么这个时候Dialog的客户区还是系统窗口的颜色?
3.InvalidateRect(NULL,true); 如果屏蔽是否真的相当于 InvalidateRect(NULL,false);
2、你在OnPaint里面调用InvalidateRect,而InvalidateRect本身会发送WM_PAINT消息,虽然该消息不一定会马上得到处理,这样的结果是未知的。但是从理论上说,嵌套调用的结果,可能是系统资源耗尽或者堆栈溢出。
3、默认的话刷,对Windows来说,颜色是GeySystemColor(COLOR_WINDOW),对对话框来说,是GeySystemColor(COLOR_BTNFACE)
4、InvalidateRect的第二个参数是确定是否需要擦出背景,这需要看你是怎么处理WM_ERASEBKGND消息的。不管擦出不擦出背景,都会导致发送WM_PAINT给窗口,屏蔽和不屏蔽效果显然是不一样的。不是钻牛角尖,这样的尖不值得钻,你其实仔细看看MSDN,就会明白你问的这几个问题。
MSDN在99%的时候是正确的
PAINTSTRUCT ps;
BeginPaint(&ps);
::TextOut(ps.hdc,0,0,buf,(int)_tcslen(buf));
EndPaint(&ps);这一段换成了//在界面上绘制
PAINTSTRUCT ps;
BeginPaint(&ps);
CPoint pt;
HPEN hPen=(HPEN)GetStockObject(BLACK_PEN);
HPEN oldPen=(HPEN)::SelectObject(hdc,hPen);
::MoveToEx(hdc,0,0,&pt);
::LineTo(hdc,100,100);
::SelectObject(hdc,oldPen);
EndPaint(&ps);发现,无论InvalidateRect(NULL,true);屏蔽不屏蔽,Dailog客户区左上角的都能画出线条来。但如果我添加一个按钮,LBUTTONDOWN里面添加代码
CPoint pt;
HDC hdc=::GetDC(m_hWnd);
HPEN hPen=(HPEN)GetStockObject(BLACK_PEN);
HPEN oldPen=(HPEN)::SelectObject(hdc,hPen);
::MoveToEx(hdc,0,0,&pt);
::LineTo(hdc,100,100);
::SelectObject(hdc,oldPen);
::ReleaseDC(m_hWnd,hdc);
InvalidateRect(NULL,false);这个时候,OnPaint上的
1.InvalidateRect(NULL,true); 如果屏蔽,点击按键,线条能够出来
2.InvalidateRect(NULL,true); 不屏蔽,点击按键,线条没有出现在OnPaint上的InvalidateRect(NULL,true);屏蔽的情况下,把按钮LBUTTONDOWN上的
1,改成InvalidateRect(NULL,true);点击按钮,看的出线条是先出来再消失的。
2. 改回InvalidateRect(NULL,false);点击按钮,线条是存在的,虽然被其他窗口遮住再出现就消失了。
这个表明系统在消息队列空下来的时候才发WM_PAINT 的,这表明非常的低优先级。第三段说的是背景擦除的时候是系统记录的整个无效区而不紧紧是传进去的参数上的Rect但很可惜的是MSDN没有提及这个刷除是在BeginPaint之前,之后,还是就是BeginPaint开始刷的。而且根据我后面的实验发现,是TextOut造成的这个背景透明的效果,单单绘制一条线或者一个矩形还是合符理论的。