091002MFC的“窗口函数winproc” DefWindowProc

 

按照我的理解,MFC程序是在Win32程序的基础上而来的,不管采用什么样的包装方式,也一定能够追根索源。

MFC中的窗口创建及窗口消息映射

  MFC为了自身的管理,在CWnd中加了一些额外的内容,包括如何从HWND生成CWnd

AfxWndProc中做了hwnd得到Cwnd的操作。

  在MFC中,有几种典型的窗口对象,CWnd描述的一般窗口对象,CView描述的视图对象,CFrameWnd描述的SDI框窗对象,CMDIFrameWnd描述的MDI框窗对象等等。

  MFC中窗口的创建

   在Window下,创建窗口可以使用两个函数,CreateWindow()CreateWindowEx(),它们都需要一个参数,这个参数是标识 窗口类的字符串。所以,如果要创建窗口,一般的做法是,先使用RegisterClass()RegisterClassEx()注册一个窗口类,然后 使用该窗口类来创建窗口。在前面我也提到过,注册窗口类的最主要目的是为系统提供窗口函数的地址,以便被DispatchMessage()之类的函数 回调。

  在MFC中,创建窗口的函数是CWnd或其派生类的Create()CreateEx方法,注册窗口类一般使用 AfxRegisterWndClass(),在这个全局函数中,并没有发现窗口函数地址这样的参数,因此脑子里自然就会有这样的问题:窗口函数在哪里 它是如何同窗口关联的?下面我们将对MFC的一些与此有关的代码进行仔细分析,回答上述两个问题。

  窗口函数

  在MFC中,有一个全局的函数AfxWndProc(),正如下面的注释所示,它就是CWnd及所有从它派生的窗口类的窗口函数,它的实现如下:

  // The WndProc for all CWnd's and derived classes

  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);

   return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);

  }

 

  AfxCallWndProc()调用pWnd对象的虚拟函数WindowProc(),它的代码如下:

  LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

  {

   // OnWndMsg does most of the work, except for DefWindowProc call

   LRESULT lResult = 0;

   if (!OnWndMsg(message, wParam, lParam, &lResult))

       lResult = DefWindowProc(message, wParam, lParam);

   return lResult;

  }

 

上面的代码中,OnWndMsg()是用来处理该窗口消息的函数,如果某条消息没有OnWndMsg()处理,也就是该窗口没有提供处理该消息的函数,它就调用DefWindowProc()进行处理,DefWindowProc()也是一个虚拟函数,看看它的代码:

  LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)

  {

   if (m_pfnSuper != NULL)

      return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);

   WNDPROC pfnWndProc;

   if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)

    return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);

   else

     return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);

  }

 

DefWindowProc()的策略很简单,调用基类的窗口函数m_pfnSuper来处理该消息。

   通过上面的分析,可以得出这样的结论:与其说AfxWndProc()MFC的唯一窗口函数,还不如说AfxWndProc()MFC的窗口消息分 发中心。正是由于有了这个消息分发中心,才使得MFC的应用程序能够用有限的几个窗口类,作出各种形形色色的窗口,使得在应用程序中,增加CWnd的派生 类,并不增加系统中窗口类的个数,将对系统资源的使用控制在一个稳定的范围之内。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值