documentation for 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);
这对我来说很烦人。
有人知道这个的原因吗?我可以想象这是出于性能原因,出于兼容性原因还是仅仅因为某些Microsoft程序员的懒惰?
答案 0 :(得分:3)
如上一个答案中所述,CPreviewDC会覆盖字体的SelectObject。
原因很简单。由于字体映射器,打印机和屏幕上的字体不同。 所以诀窍是SelectObject(CFont *)在调用时设置内部变量m_hPinterFont。调用MirrotFont并填充m_hFont这是应该在屏幕DC上使用的字体。
画笔,笔不需要这样的映射,因为只有设备上的字体处理非常特殊。
这部分描述于MSDN。
HTH
答案 1 :(得分:2)
从我在MFC代码中看到的,这是因为CPreviewDC会覆盖它。
CPreviewDC是一个CDC派生类,用于打印预览,似乎没有文档。您可以在afxpriv.h
中找到其声明,并在dcprev.cpp
中找到它。
编辑:
这些文件的示例路径:
%Program Files%\ Microsoft Visual Studio 9.0 \ VC \ atlmfc \ include \ afxpriv.h
%Program Files%\ Microsoft Visual Studio 9.0 \ VC \ atlmfc \ src \ mfc \ dcprev.cpp
EDIT2:但为什么它们都不虚拟?
我的猜测是微软不希望人们搞乱GDI对象(它们是系统中的有限资源),因此这些函数被声明为非虚拟的。他们已经努力在Win32周围创建一个包装器,它可以正确处理GDI对象(并使用户免于进行大部分处理),并且他们不希望用户改变这种行为并且很可能引入错误。 / p>
但是他们必须打破“规则”才能实现CPreviewDC,这是一种特殊的DC。
所有DC都有两个成员,m_hDC和m_hAttribDC,它们通常是相同的。但在CPreviewDC中,一个代表屏幕,另一个代表打印机。字体是一种特殊的东西,因为打印机不一定与计算机具有相同的字体。因此,当MFC需要为打印预览准备文档时,它首先选择打印机上的字体(它告诉打印机(驱动程序)“嘿,我需要选择这个字体”,打印机选择最接近的字体)然后CPreviewDC镜像它以在屏幕上显示它(它选择系统上最接近打印机选择的字体)。
其余的GDI对象,笔,画笔,区域......不需要这样的特殊处理,因此它们不会被声明为虚拟。