love in C++, live on MFC

to get ready...

C++博客 首页 新随笔 联系 聚合 管理
  47 Posts :: 0 Stories :: 97 Comments :: 0 Trackbacks
在重载CSplitterWnd中,重载了OnPaint(),
默认的代码如下:
void CHideSplitterWnd::OnPaint() 
{
    CPaintDC dc(
this); //
 device context for painting
    
//
 TODO: Add your message handler code here
    
// Do not call CSplitterWnd::OnPaint() for painting messages

}
wizard添加的代码居然有这样一行:// Do not call CSplitterWnd::OnPaint() for painting messages,后面有个猜测。
然后我继续写我的函数:
void CHideSplitterWnd::OnPaint() 
{
    CPaintDC dc(
this); //
 device context for painting
    
    
// 调用基类,先

    CSplitterWnd::OnPaint();
    
     //
利用dc画一些别的东西,但是实际上,它们永远不会被画出来
   //除非不调用基类的OnPaint()

    m_rectButton.DrawButton(&dc);
}
结果我添加的东西怎么也不会被画出来,为什么会这样?

看了CSplitterWnd::OnPaint()的代码,发现它也用了一个CPaintDC,而且也是个临时变量
void CSplitterWnd::OnPaint()
{
    ASSERT_VALID(
this
);
    CPaintDC dc(
this);
而关键的地方就在CPaintDC的ctor和dtor中了:在CPaintDC的ctor中调用了
::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)
而在CPaintDC的dtor中调用了
::EndPaint(m_hWnd, &m_ps);
而:BeginPaint是开始根据当前的cliprect来画,EndPaint则会清空当前的cliprect。

所以,前面调用基类的OnPaint的过程结束后,当前的cliprect为NULL,所以,第二个CPaintDC在视图画点什么时,cliprect已经为NULL,当然什么也画不上去了 :)

如果我一定想再用CPaintDC画点什么,怎么办?再次调用InvalidateRect,使得cliprect不为空。
void CHideSplitterWnd::OnPaint() 
{
    //注意临时变量声明的顺序,因为BeginPaint/EndPaint是不支持嵌套的
    //CPaintDC dc(
this); //
 device context for painting
    
    
// TODO: Add your message handler code here

    CSplitterWnd::OnPaint();
    
    //第二此调用
    InvalidateRect(
&
m_rectButton,FALSE);
    CPaintDC dc(
this); // 在这里,device context for painting

    m_rectButton.DrawButton(&dc);
    
    
// Do not call CSplitterWnd::OnPaint() for painting messages

}
所以,我猜测,所有用了CPaintDC的地方,MFC都会加一句:不要调用基类的函数啦~

呵呵,不知道我讲清楚没有
posted on 2006-05-22 23:39 flyingxu 阅读(3307) 评论(3)  编辑 收藏 引用 所属分类: VC/MFCBug of Today

Feedback

# re: 在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint() 2006-05-23 08:36 cmdn
请教一下,你那个代码不是图片,是怎么贴上去的?  回复  更多评论
  

# re: 在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint() 2006-06-08 23:17 flyingxu
@cmdn
是cppblog编辑时选的“代码段”格式。  回复  更多评论
  

# re: 在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint() 2007-04-27 09:55 困惑于OnPaint的人
void CMyView::OnPaint()
{

CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CView::OnPaint();

dc.TextOut(0,0,"hello"); //这个能在屏幕显示出来,为什么?
// Do not call CView::OnPaint() for painting messages
}

我上面的这段代码能正常运行,且能在屏幕上正确显示"hello"字符串  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理