分享

跟踪MFC 事件流程.

 herowuking 2015-10-07

以对话框
1. CDlgExampleApp theApp;
2. 调用 CWinApp::CWinApp(LPCTSTR lpszAppName) 构造函数  主要是设置 AFX_MODULE_STATE,AFX_MODULE_THREAD_STATE 的实例句柄 
3. 链接器直接加_tWinMain 到应用程序. _tWinMain函数调用了 AfxWinMain 函数.该WinMain 是 程序的循环
4. 在WinMain 函数中.首先调用AfxWinInit 函数.该函数主要是进行内部赋值.把 hInstance,lpCmdLine,nCmdShow复制给theApp成员函数 把实例句柄hInstance赋值给pModuleState .并调用AfxInitThread 函数按照钩子到主线程. 获取 _AFX_THREAD_STATE的成员变量  m_hHookOldMsgFilter等于安装的该钩子.该钩子类型为WH_MSGFILTER,回调函数为  _AfxMsgFilterHook
5. 在AfxWinMain 函数中,调用theApp->InitApplication() 函数. 主要是CDocManager 的一些初始化.该函数可以忽略.
6. 在AfxWinMain 函数中 调用 pThread->InitInstance() 虚函数 .实际上调用theApp->InitInstance()。在theApp->InitInstance 函数中调用父类 CWinApp::InitInstance() 加载程序的资源.
6. 创建CMainFrame 对象 并把当前的CMainFrame 对象添加到AFX_MODULE_THREAD_STATE 的 _frameList 队列中.
7. CMainFrame.LoadFrame 函数创建主框体.
8. 在LoadFrame 函数中.调用 AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG).注册 AFX_WNDFRAMEORVIEW_REG 窗体类. 该注册类定义如下
   #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass).在函数中 AfxEndDeferRegisterClass(fClass) 创建了窗体注册类.根据fClass类型.注册该类.设置回调函数为 wndcls.lpfnWndProc = DefWindowProc;
9.AfxEndDeferRegisterClass(fClass) 函数调用_AfxRegisterWithIcon(WNDCLASS* pWndCls,LPCTSTR lpszClassName, UINT nIDIcon) 注册.并把该窗体类的名称lpszClassName设置一个默认值.例如"AfxFrameOrView80sud" 。
10._AfxRegisterWithIcon函数再调用 AfxRegisterClass(pWndCls)然后又调用AfxCtxRegisterClass(lpWndClass) 然后再调用RegisterClassW 注册

11.LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);  在该函数中调用CMainFrame->PreCreateWindow 修改窗口类和样式.CMainFrame->PreCreateWindow调用父类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) 获取已经注册过的窗体类_afxWndFrameOrView.并赋值给当前结构体

12.在LoadFrame 函数调用CFrameWnd::Create(lpszClass, strTitle, dwDefaultStyle, rectDefault, pParentWnd, ATL_MAKEINTRESOURCE(nIDResource), 0L, pContext))
   加载菜单.hMenu = ::LoadMenu(hInst, lpszMenuName) 并调用CWnd::CreateEx();
13.在CWnd::CreateEx() 函数中有一次回调 CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) 的机会
14.在CWnd::CreateEx() 调用AfxHookWindowCreate(this) .在该函数中注册WH_CBT类型的钩子.该钩子函数为_AfxCbtFilterHook。
15.在CWnd::CreateEx() 调用::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams) 函数创建窗体
16. 在钩子函数中_AfxCbtFilterHook 当创建即将产生之前.该函数被调用.并且调用SetWindowLongPtr 在把消息推到AfxWndProc回调函数.
   oldWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(DWORD_PTR)afxWndProc); 修改hWnd 窗口函数为AfxWndProc函数
17. AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) 中调用 AfxCallWndProc
18. AfxCallWndProc函数调用 pWnd->WindowProc(nMsg, wParam, lParam); 正式进入MFC 类库
19. CWinApp::Run() 函数调用  CWinThread::Run().该函数为一个死循环.在该循环中.从消息队列中获取消息.并分批到指定的窗口函数.
20. CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 调用 OnWndMsg 函数来分辨并处理消息的专职机构.
21. 在CWnd::OnWndMsg中.如果是命令消息Command.就交给OnCommand()处理,如果是通知消息Notification,就交给OnNotify处理.而一般的Windows 消息则直接在消息映射表中上溯
    寻找消息处理函数
22.OnCommand()函数调用 CFrameWnd::OnCommand()函数.在该函数中没有处理什么.直接调用CWnd::OnCommand();

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多