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



CDC的文档:SelectObject声明"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);

这对我来说很烦人。

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

如前一个答案CPreviewDC为字体覆盖SelectObject。

原因很简单。打印机和屏幕上的字体因字体映射器的不同而不同。因此,诀窍是SelectObject(CFont*)在调用时设置一个内部变量m_hPinterFont。同时调用MirrotFont并填充m_hFont这是应该在屏幕DC上使用的字体。

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

MSDN对此进行了部分描述。

HTH

从我在MFC代码中看到的,这是因为CPreviewDC覆盖了它。

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

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

第二版:但为什么它们不都是虚拟的呢?

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

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

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

其余的GDI对象,笔,画笔,区域。。。不需要这样的特殊待遇,因此它们不被宣布为虚拟的。

相关内容

  • 没有找到相关文章

最新更新