MFC day02 伪代码

Afx开头的函数:  MFC的全局函数
::开头的函数:   Win32的API函数
::Afx开头的函数:中转到相应的Win32的API函数
  ::AfxCtxRegisterClass(lpWndClass) ==> ::RegisterClass(lpWC)

三个全局变量:
AFX_MODULE_STATE:        当前程序模块状态信息(aaa)
AFX_MODULE_THREAD_STATE:当前程序线程状态信息(bbb)
_AFX_THREAD_STATE:      当前程序线程信息 (ccc)

// MFC窗口创建流程
pFrame->Create(NULL,"MFCCreate")
{
   // 1. 加载菜单
   ::LoadMenu(...);
   // 2.调用CreateEx创建带扩展风格的窗口
   CreateEx(...,NULL,...)
   {
     CREATESTRUCT cs;
     ...
     cs.lpszClass = lpszClassName;//lpszClassName为NULL 后面会改
     ...
     cs.hInstance = AfxGetInstanceHandle();
     ...
     // 2.1 设计和注册窗口类
     PreCreateWindow(cs)
     {
        // AFX_WNDFRAMEORVIEW_REG的值为0x08,代表一种类型的窗口
        AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)
        {
           WNDCLASS wndcls;
           ...
           wndcls.lpfnWndProc = DefWindowProc;// 后面会改
           ...
           // 每个if 对应一种窗口的类型
           if (fToRegister & AFX_WNDFRAMEORVIEW_REG)
       {
             //  _afxWndFrameOrView保存窗口类名称,
             //  "AfxFrameOrView100sd"
              _AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView,..)
              {
                 wndcls->lpszClassName = lpszClassName;
                 pWndCls->hIcon = ::LoadIcon(NULL,...);
                 return AfxRegisterClass(pWndCls)
                 {
                    // 注册窗口类
                    ::AfxCtxRegisterClass(lpWndClass);
                 }
              }
           }
        }
        cs.lpszClass = _afxWndFrameOrView;// "AfxFrameOrView100sd"
     }
     // 2.2 安装类型为WH_CBT的钩子
     AfxHookWindowCreate(this) // this是pFrame
     {
       // 获取ccc的地址
       _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
       // 利用Win32的API函数在程序中安装了一个类型为WH_CBT的钩子
       ::SetWindowsHookEx(WH_CBT,_AfxCbtFilterHook,...);
       // 把自己new的框架窗口类对象的地址保存在ccc的一个成员中
       pThreadState->m_pWndInit = pWnd;//pWnd就是pFrame
     }
     // 2.3 创建窗口
     ::AfxCtxCreateWindowEx(...);// 该函数执行成功,狗子处理函数立即执行
     // 2.4 钩子处理函数
     // 2.5 跳转回2.3后的代码
   }
}

*******************************************
 2.4 钩子处理函数 
*******************************************
_AfxCbtFilterHook(.., WPARAM wParam,...)
{
  // 获取&ccc
   _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
  // 获取框架对象地址 pFrame
  CWnd* pWndInit = pThreadState->m_pWndInit;
  // 获取窗口句柄
  HWND hWnd = (HWND)wParam;
  // 2.4.1 将句柄(hWnd)附加到窗口对象(pFrame,就是pWndInit)
  pWndInit->Attach(hWnd)
  {
    CHandleMap* pMap = afxMapHWND(TRUE)
    {
      // 获取&bbb
      AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
      // new了一个映射类的对象,并将对象地址保存在了bbb的一个成员中
      pState->m_pmapHWND = new CHandleMap(...);
      // 返回映射类对象的地址
      return pState->m_pmapHWND;
    }
    // 将窗口句柄保存在框架窗口类对象的成员m_hWnd中
    pMap->SetPermanent(pFrame->m_hWnd = hWnd, this);
    {
       // 以句柄为键,以框架窗口类对象为值,建立映射关系
       m_permanentMap[(LPVOID)h] = permOb;
       // 等效于:m_permanentMap[hWnd] = pFrame;
    }
  }
  // 2.4.2 将窗口处理函数由原来的DefWindowProc改为AfxWndProc
  // 获取AfxWndProc函数的地址
  WNDPROC afxWndProc = AfxGetAfxWndProc();
  // 将窗口处理函数更改为真正的窗口处理函数(AfxWndProc)
  oldWndProc = (WNDPROC)SetWindowLongPtr(...);
}

**********************************************
 消息处理函数(WM_CREATE为例)
**********************************************
AfxWndProc(...)
{
   // 1. 根据句柄获取窗口对象地址pFrame
   CWnd* pWnd = CWnd::FromHandlePermanent(hWnd)
   {
     CHandleMap* pMap = afxMapHWND()
     {
       // 获取&bbb
       AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
       // 返回上面保存在bbb中映射类对象地址
       return pState->m_pmapHWND;
     }
     pWnd = (CWnd*)pMap->LookupPermanent(hWnd)
     {
        //return (CObject*)m_permanentMap.GetValueAt((LPVOID)h);
        // 等效于
        return m_permanentMap[hWnd]; // 返回的是pFrame
     }
   }
   // 2.调用AfxCallWndProc函数,参数中pWnd就是pFrame
   AfxCallWndProc(pWnd,...)
   {
      // 3. 由于虚函数机制,调用CMyFrameWnd::WindowProc函数
      pWnd->WindowProc(...)
      {
         // 回到自己的代码
      }
   }
}

猜你喜欢

转载自blog.csdn.net/kikizxc999/article/details/86671835