好久没有写博客了,因为本身自己就是个菜鸟,今天碰到个小问题,正好看到还有博客这个东西。。。就写写吧。
关于CFont的,先什么也不说,先贴一个自己写的短代码,查看变量数据的。
void SeeMem(void* Variable,int size)
{
unsigned char *pPointer = static_cast<unsigned char*>(Variable);
for(int i = 1;i<=size;i++,pPointer++)
{
std::cout<<std::setw(2)<<std::setfill('0')<<std::hex<<std::setiosflags(std::ios_base::uppercase)
<<static_cast<unsigned int>(*pPointer);
(i%16 != 0)&(i!=size)?(std::cout<<" "):(std::cout<<std::endl);
}
}
啊~哈哈,很简单的一段小代码。
今天看到CFont的一句话
HFONT hf = static_cast<HFONT>(font);
我在想,CFont作为一个类,是怎么做到这一点的?
于是,在这样一段代码以后:
font.CreatePointFont(80,"Arial",NULL);
HFONT hf = static_cast<HFONT>(font);
SeeMem(&font,sizeof(font));
SeeMem(&hf,sizeof(hf));
两次的结果:
20 E8 90 60 43 16 0A 12
43 16 0A 12
请按任意键继续. . .
20 E8 90 60 18 1B 0A E1
18 1B 0A E1
请按任意键继续. . .
这就说明
CFont里面的从第5个字节开始为我们要的东西,而且,这个东西是个指针,因为字体一样。
那然后呢。。。
发现前四个字节一样了么。。。
可是在后来的运行中。。。
20 E8 65 5E 28 19 0A B2
28 19 0A B2
请按任意键继续. . .
他又不一样了。。。20 E8是一样的。。
可是,有用的肯定是后四个字节,否则,后四个字节的传值就是没有意义的。。。
然后看到了CFile的类。。
class CFont : public CGdiObject
{
DECLARE_DYNAMIC(CFont)
public:
static CFont* PASCAL FromHandle(HFONT hFont);
// Constructors
CFont();
BOOL CreateFontIndirect(const LOGFONT* lpLogFont);
BOOL CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename);
BOOL CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL);
BOOL CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC = NULL);
// Attributes
operator HFONT() const;
int GetLogFont(LOGFONT* pLogFont);
// Implementation
public:
virtual ~CFont();
#ifdef _DEBUG
virtual void Dump(CDumpContext& dc) const;
#endif
};
于是,找到了operator HFONT() const;
这就是为什么强制转换不是转换的地址了,然后,直接单步,找到了该重载函数体。。。
_AFXWIN_INLINE CFont::operator HFONT() const
{ return (HFONT)(this == NULL ? NULL : m_hObject); }
原来,那是CObject的地址。。。