Mfc 为什么CDC::SelectObject仅适用于CFont版本?

Mfc 为什么CDC::SelectObject仅适用于CFont版本?,mfc,Mfc,声明CFont版本是虚拟的,但CPen、CBrush、CBitmap和CRgn版本不是 CPen* SelectObject(CPen* pPen); CBrush* SelectObject(CBrush* pBrush ); virtual CFont* SelectObject(CFont* pFont); CBitmap* SelectObject(CBitmap* pBitmap); int SelectObject(CRgn* pRgn); CGdiObject* SelectObj

声明CFont版本是虚拟的,但CPen、CBrush、CBitmap和CRgn版本不是

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);
这对我来说很烦人


有人知道原因吗?我可以想象,这是出于性能原因,出于兼容性原因,或者可能只是因为某些Microsoft程序员的懒惰?

从MFC代码中可以看出,这是因为CPreviewDC覆盖了它

CPreviewDC是CDC派生的类,用于打印预览,似乎没有文档记录。您可以在afxpriv.h中找到它的声明,在dcprev.cpp中找到它的实现

编辑: 这些文件的示例路径: %程序文件%\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxpriv.h %程序文件%\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\dcprev.cpp

编辑2:但是为什么它们不是虚拟的呢

我的猜测是,微软不希望人们摆弄GDI对象,因为它们在系统中是有限的资源,所以这些函数被声明为非虚拟的。他们已经在Win32周围创建了一个包装器,它可以正确处理GDI对象,并将用户从大部分处理中解放出来,他们不希望用户改变这种行为,并且很可能引入bug

但他们必须打破这一规则才能实现CPreviewDC,这是一种特殊的DC

所有DC都有两个成员,m_hDC和m_hAttribDC,这两个成员通常是相同的。但在CPreviewDC中,一个代表屏幕,另一个代表打印机。字体是一种特殊的东西,因为打印机不一定和计算机有相同的字体。因此,当MFC需要为打印预览准备文档时,它首先选择打印机上的字体,告诉打印机驱动程序嘿,我需要选择这种字体,打印机选择它能选择的最接近的字体,然后CPreviewDC将其镜像以在屏幕上显示。它选择系统上可用的最接近打印机选择的字体


其余的GDI对象、笔、画笔、区域。。。不需要这样的特殊处理,因此它们不被声明为虚拟的。

从MFC代码中可以看出,这是因为CPreviewDC覆盖了它

CPreviewDC是CDC派生的类,用于打印预览,似乎没有文档记录。您可以在afxpriv.h中找到它的声明,在dcprev.cpp中找到它的实现

编辑: 这些文件的示例路径: %程序文件%\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxpriv.h %程序文件%\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\dcprev.cpp

编辑2:但是为什么它们不是虚拟的呢

我的猜测是,微软不希望人们摆弄GDI对象,因为它们在系统中是有限的资源,所以这些函数被声明为非虚拟的。他们已经在Win32周围创建了一个包装器,它可以正确处理GDI对象,并将用户从大部分处理中解放出来,他们不希望用户改变这种行为,并且很可能引入bug

但他们必须打破这一规则才能实现CPreviewDC,这是一种特殊的DC

所有DC都有两个成员,m_hDC和m_hAttribDC,这两个成员通常是相同的。但在CPreviewDC中,一个代表屏幕,另一个代表打印机。字体是一种特殊的东西,因为打印机不一定和计算机有相同的字体。因此,当MFC需要为打印预览准备文档时,它首先选择打印机上的字体,告诉打印机驱动程序嘿,我需要选择这种字体,打印机选择它能选择的最接近的字体,然后CPreviewDC将其镜像以在屏幕上显示。它选择系统上可用的最接近打印机选择的字体


其余的GDI对象、笔、画笔、区域。。。不需要这种特殊处理,因此它们不会被声明为虚拟的。

如前一个回答中所述,CPreviewDC会覆盖字体的SelectObject

原因很简单。打印机和屏幕上的字体因字体映射器而异。 因此,技巧在于SelectObjectCFont*在调用时设置一个内部变量m_hPinterFont。同时调用MirrotFont并填充m_hFont,这是应该在屏幕上使用的字体

画笔、笔不需要这样的映射,因为只有设备上的字体处理非常特殊

这在中有部分描述


HTH

如前一个回答中所述,CPreviewDC将覆盖字体的SelectObject

原因很简单。打印机和屏幕上的字体因字体映射器而异。 因此,技巧在于SelectObjectCFont*在调用时设置一个内部变量m_hPinterFont。同时调用MirrotFont并填充m_hFont,这是应该在屏幕上使用的字体

画笔、笔不需要这样的映射,因为只有F 设备上的ont处理非常特殊

这在中有部分描述


HTH

这解释了为什么CFont*CDC:SelectObjectCFont*pFont是虚拟的,但它没有解释为什么,例如CBrush*CDC::SelectObjectCBrush*pBrush;不是虚拟的。谢谢,这听起来很合理。这解释了为什么CFont*CDC:SelectObjectCFont*pFont是虚拟的,但没有解释为什么,例如CBrush*CDC::SelectObjectCBrush*pBrush;不是虚拟的。谢谢,听起来很合理。