在重載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都會加一句:不要調用基類的函數啦~
呵呵,不知道我講清楚沒有