在重载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都会加一句:不要调用基类的函数啦~
呵呵,不知道我讲清楚没有