2013-12-09 39 views
0

documentation for CDC::SelectObject指出「CFont」版本是虛擬的,但CPen,CBrush,CBitmap和CRgn版本不是。爲什麼CDC :: SelectObject只爲CFont版本虛擬?

CPen* SelectObject(CPen* pPen); 
CBrush* SelectObject(CBrush* pBrush); 
virtual CFont* SelectObject(CFont* pFont); 
CBitmap* SelectObject(CBitmap* pBitmap); 
int SelectObject(CRgn* pRgn); 
CGdiObject* SelectObject(CGdiObject* pObject); 

這對我來說很煩人。

有人知道這個的原因嗎?我可以想象這是出於性能原因,出於兼容性的原因,還是僅僅因爲一些微軟程序員的懶惰?

回答

2

從我在MFC代碼中看到的,這是因爲CPreviewDC重寫它。

CPreviewDC是CDC派生類,用於打印預覽,似乎沒有文檔。您可以在afxpriv.h中找到它的聲明,並在dcprev.cpp中找到它的聲明。

編輯: 實例路徑這些文件:
%程序Files%\微軟的Visual Studio 9.0 \ VC \ atlmfc \包括\ AFXPRIV.H
%程序Files%\微軟的Visual Studio 9.0 \ VC \ atlmfc \ src \ mfc \ dcprev.cpp

編輯2:但爲什麼他們都不是虛擬的?

我的猜測是,微軟不希望人們搞亂GDI對象(他們是系統中有限的資源),所以這些函數被聲明爲非虛擬的。他們已經努力在Win32上創建一個包裝器,它能夠正確處理GDI對象(並且可以讓用戶從大部分處理中解放出來),並且他們不希望用戶改變這種行爲並且很可能引入錯誤。

但他們不得不打破那個「規則」才能夠實現CPreviewDC,這是一種特殊的DC。

所有DC都有兩個成員m_hDC和m_hAttribDC,它們通常是相同的。但在CPreviewDC中,一個代表屏幕,另一個代表打印機。而字體是一件特別的事情,因爲打印機不一定與計算機具有相同的字體。所以,當MFC需要準備打印預覽文檔時,它首先選擇打印機上的字體(它告訴打印機(驅動程序)「嘿,我需要選擇這種字體」,並且打印機選擇最接近的字體)然後CPreviewDC將其鏡像以在屏幕上顯示(它選擇系統上可用的最接近字體與打印機選擇的字體)。

其餘的GDI對象,筆,畫筆,區域...不需要這樣的特殊處理,因此它們不被聲明爲虛擬。

+0

這就解釋了爲什麼'的CFont * CDC:選擇對象(CFont類* pFont)'是虛擬的,但它並不能解釋爲什麼如'CBrush * CDC :: SelectObject(CBrush * pBrush);'**不是**虛擬的。 –

+0

是的。我會編輯我的答案 – MikMik

+0

謝謝,這聽起來很合理。 –

3

正如先前回答中所寫,CPreviewDC會覆蓋SelectObject以獲取字體。

原因很簡單。由於字體映射器,打印機和屏幕上的字體不同。 所以訣竅是SelectObject(CFont *)在調用它時會設置一個內部變量m_hPinterFont。 MirrotFont也被調用,m_hFont被填充這是應該在屏幕DC上使用的字體。

筆刷不需要這種映射,因爲只有設備上的字體處理非常特殊。

這部分描述在MSDN

HTH

相關問題