正在阅读:VC++学习:分析MFC中的映射VC++学习:分析MFC中的映射

2004-02-14 09:34 出处:PConline 作者:jiangsheng/CSDN 责任编辑:linjixiong

  _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为了快速和方便地开发作了很多工作,例如上述的两种映射,但是性能方面有所损失。开发应用程序时,需要在快速方便和性能损失方面的权衡。(话是这么说,但是根据摩尔定律,再过两年我的话就成废话了)
键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品