_AFXWIN_INLINE CWnd* CWnd::GetParent() const { ASSERT(::IsWindow(m_hWnd)); return CWnd::FromHandle(::GetParent(m_hWnd)); } 看到了么,它首先调用API GetParent,然后去本线程的窗口<->句柄映射查找对象指针,然后调用CWnd::IsFrameWnd来决定对象是否是框架。(谢天谢地,这个函数是用虚函数而不是用CObject::IsKindOf,不然又得遍历一遍运行时类信息) 在一些经常调用的函数里面也使用到这个映射 LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { // special message which identifies the window as using AfxWndProc if (nMsg == WM_QUERYAFXWNDPROC) return 1; // all other messages route through message map CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); ASSERT(pWnd != NULL); ASSERT(pWnd->m_hWnd == hWnd); if (pWnd == NULL || pWnd->m_hWnd != hWnd) return ::DefWindowProc(hWnd, nMsg, wParam, lParam); return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam); } 也就是说,它要遍历一遍afxMapHWND()返回的对象里面的永久的句柄映射。而这个函数在每个消息到达的时候都要调用。这是MFC应用程序性能损失的原因之一。 同样的,由于这些对象是被线程所拥有的,MFC的这些句柄映射的存储方式是线程局部存储 (thread-local-storage ,TLS)。也就是说,对于同一个句柄,句柄映射中相应的对象可以不一致。这在多线程程序中会造成一些问题,参见微软知识库文章Q147578 CWnd Derived MFC Objects and Multi-threaded Applications。 总结 MFC为了快速和方便地开发作了很多工作,例如上述的两种映射,但是性能方面有所损失。开发应用程序时,需要在快速方便和性能损失方面的权衡。(话是这么说,但是根据摩尔定律,再过两年我的话就成废话了) |
閺€鎯版閹存劕濮�閺屻儳婀呴弨鎯版>>
正在阅读:VC++学习:分析MFC中的映射VC++学习:分析MFC中的映射
2004-02-14 09:34
出处:PConline
责任编辑:linjixiong
键盘也能翻页,试试“← →”键