在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint()

在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint()
在重载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都会加一句:不要调用基类的函数啦~

呵呵,不知道我讲清楚没有

你可能感兴趣的:(在OnPaint()使用两次CPaintDC,关于::BeginPaint()/::EndPaint())