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(...)
{
// 回到自己的代码
}
}
}