在OnPaint中必須調用一次BeginPaint和EndPaint,且也只能調用一次。(上) .


基於對話框的程序(mfc默認生成),重載OnEraseBkgnd函數,其它不動,若在OnPaint函數中不調用其基類的OnPaint函數,即注釋掉CDialog::OnPaint();,代碼如下:
  1. void CDDDDlg::OnPaint()  
  2. {  
  3.     if (IsIconic())  
  4.     {  
  5.         CPaintDC dc(this); // device context for painting   
  6.   
  7.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
  8.   
  9.         // Center icon in client rectangle   
  10.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  11.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  12.         CRect rect;  
  13.         GetClientRect(&rect);  
  14.         int x = (rect.Width() - cxIcon + 1) / 2;  
  15.         int y = (rect.Height() - cyIcon + 1) / 2;  
  16.   
  17.         // Draw the icon   
  18.         dc.DrawIcon(x, y, m_hIcon);  
  19.     }  
  20.     else  
  21.     {  
  22.         //CDialog::OnPaint();   
  23.     }  
  24. }  


 則執行后界面沒有問題,如下圖:

但是,如果將此界面隱藏后再顯示,則上面的控件都不能顯示了,如下圖:

 

跟蹤程序會發現,第一次生成界面時候,進入過OnCtlColor函數(TRACE("OnCtlColor\n");語句輸出),

當隱藏界面再顯示后,就再也沒進過OnCtlColor函數。當然看不見原先界面的控件了,因為根本沒有重繪出來。原因見下篇

 

 

 

A:在OnPaint中注釋此句CDialog::OnPaint();為什么會不停地調用OnPaint函數呢(不斷執行TRACE("OnPaint\n");語句)?

 

Q:如果自己的OnPaint代碼什么也沒做的話(至少沒有聲明過CPaintDC類型的變量),還必須調用一下CDialog::OnPaint,否則BeginPaint和EndPaint就沒有辦法被調用了。
總之,在響應WM_PAINT消息的時候,必須調用一遍BeginPaint和EndPaint。調用的方法有三種:
1、聲明一個CPaintDC類型的變量(即使你什么也不畫),CPaintDC的構造函數就是調用BeginPaint,析構函數就是調用EndPaint。
2、調用基類的OnPaint(實際上就是調用API的DefWindowProc,它會自動調用BeginPaint和EndPaint)。
3、自己直接調用BeginPaint和EndPaint。
上述三種方法,必須選擇其一,而且也只能選擇其一(因為在一個WM_PAINT消息內不能調用兩次BeginPaint和EndPaint)。

 

正如我猜想的,因為你調用了CDialog::OnPaint();
你把這句注釋掉就可以了。
所以說凡事總有因果,CDialog::OnPaint()調用默認的窗口過程來繪制,也會調用BeginPaint/EndPaint()。而這兩個函數的作用,是獲取DC、剪裁區域和從消息隊列中移走WM_PAINT消息(因此,如果不用上述三種方法的一種調用一遍BeginPaint和EndPaint的話,WM_PAINT消息就不會從消息隊列里面移走,系統就會不停的發送WM_PAINT,這就是問題中所提到的不停的調用OnPaint函數的原因了)。這兩個函數,必須在WM_PAINT消息中調用,而且只能調用一次!

 

相關帖子:

http://topic.csdn.net/u/20100801/11/40897468-807e-445a-a817-ede00dfd406e.html

 

http://topic.csdn.net/u/20080620/15/1D8E30FD-584A-4551-B93A-DA97D5F6423C.html#r_50392023

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM