|
本帖最后由 SummerGull 于 2022-4-2 21:39 编辑
- int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- _In_ LPTSTR lpCmdLine, int nCmdShow)
- {
- CWinThread* pThread = AfxGetThread();//获取this指针呢 就是theApp
- CWinApp* pApp = AfxGetApp();//获取this指针呢 就是theApp
- //上面有这两个函数的解释
- pApp->InitApplication();//初始化程序
- pThread->InitInstance();//这是个虚函数,初始化程序 进入我们自己重写的函数
- //上面两句代码执行失败都是走 goto InitFailure;
- nReturnCode = pThread->Run();//这里其实是消息循环
- return nReturnCode;
- }
复制代码
创建窗口
接着从下面函数继续执行
pThread->InitInstance();
进入自己重写的虚函数
- pThread->InitInstance()
- {
- MyWnd* pFrame = new MyWnd();
- m_pMainWnd = pFrame;
- //这里是 theApp 成员变量 赋值 也就是主窗口交给成员变量
- pFrame->Create(NULL, "Window");
- //执行的是 CFrameWnd::Create()
- //又执行了CreateEx 也是CFraneWnd的函数
- //提取代码看有用的信息
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
复制代码
CFrameWnd::Create()函数
- BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
- LPCTSTR lpszWindowName,
- DWORD dwStyle,
- const RECT& rect,
- CWnd* pParentWnd,
- LPCTSTR lpszMenuName,
- DWORD dwExStyle,
- CCreateContext* pContext)
- {
- m_strTitle = lpszWindowName; // save title for later
- if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
- rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
- pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))
- {
- TRACE(traceAppMsg, 0, "Warning: failed to create CFrameWnd.\n");
- if (hMenu != NULL)
- DestroyMenu(hMenu);
- return FALSE;
- }
- return TRUE;
- }
复制代码
CWnd::CreateEx()函数
- BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
- LPCTSTR lpszWindowName, DWORD dwStyle,
- int x, int y, int nWidth, int nHeight,
- HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
- {
-
- CREATESTRUCT cs;
- cs.dwExStyle = dwExStyle;
- cs.lpszClass = lpszClassName;
- cs.lpszName = lpszWindowName;
- cs.style = dwStyle;
- cs.x = x;
- cs.y = y;
- cs.cx = nWidth;
- cs.cy = nHeight;
- cs.hwndParent = hWndParent;
- cs.hMenu = nIDorHMenu;
- cs.hInstance = AfxGetInstanceHandle();
- //这里的AfxGetInstanceHandle() == afxCurrentInstanceHandle
- //afxCurrentInstanceHandle == AfxGetModuleState()->m_hCurrentInstanceHandle
- cs.lpCreateParams = lpParam;
- //CREATESTRUCT 这个结构 里面有个lpszClassName是为空的。但是这是不允许的。
- //下面的CreateWindowEx就快要创建窗口了 如果 lpszClassName为空肯定会出错
- //也就是说 下面的 PreCreateWindow(cs) 或 AfxHookWindowCreate(this);
- //一定会把 lpszClassName补上。
- //但是AfxHookWindowCreate(this); 没有cs参数,PreCreateWindow(cs)带了
- //执行步骤在这里总结为:
- //1、PreCreateWindow(cs) 进入下面函数
- //2、VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));//注册窗口类
- //3、上面函数 注册窗口类时wndcls.lpfnWndProc = DefWindowProc;会带来问题。
- //4、AfxRegisterWithIcon()函数协助上面函数注册窗口类
- //5、上面函数使用API注册窗口
- //6、cs.lpszClass = _afxWndFrameOrView;//注册完赋值,这个就是类名 上个函数注册的
- //7、使用 AfxHookWindowCreate(this); 解决问题 消息处理过程HOOK为 MFC提供的
- //需要在该函数文档中搜索_AfxCbtFilterHook() 函数并下断点
- //8、产生窗口CreateWindowEx函数调用API创建窗口
- //创建完毕立马跳转_AfxCbtFilterHook()函数过程中
- //9、跳转HOOK函数_AfxCbtFilterHook()执行代码
- if (!PreCreateWindow(cs))//下面有函数展开信息 这个也是个虚函数
- {
- PostNcDestroy();
- return FALSE;
- }
- AfxHookWindowCreate(this);
- //这个函数将解决 wndcls.lpfnWndProc = DefWindowProc;带来的问题。
- HWND hWnd = CreateWindowEx(cs.dwExStyle, cs.lpszClass,
- cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
- cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
- #ifdef _DEBUG
- if (hWnd == NULL)
- {
- TRACE(traceAppMsg, 0, "Warning: Window creation failed: GetLastError returns 0x%8.8X\n",
- GetLastError());
- }
- #endif
- if (!AfxUnhookWindowCreate())
- PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
- if (hWnd == NULL)
- return FALSE;
- ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
- return TRUE;
- }
复制代码
CFrameWnd::PreCreateWindow
- BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
- {
- if (cs.lpszClass == NULL)
- {
- VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
- //这个函数里面是注册窗口类的
- cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
- //这个赋值是关键 把窗口类名赋值给了 cs里面的 类名称
- }
- if (cs.style & FWS_ADDTOTITLE)
- cs.style |= FWS_PREFIXTITLE;
- cs.dwExStyle |= WS_EX_CLIENTEDGE;
- return TRUE;
- }
复制代码
AfxEndDeferRegisterClass
- BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
- {
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- fToRegister &= ~pModuleState->m_fRegisteredClasses;
- if (fToRegister == 0)
- return TRUE;
- LONG fRegisteredClasses = 0;
- // common initialization
- WNDCLASS wndcls;
- memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
- wndcls.lpfnWndProc = DefWindowProc;
- //这里也有一个问题,为什么要给 默认窗口处理函数处理
- //MFC的窗口处理函数没有来处理!!!
- wndcls.hInstance = AfxGetInstanceHandle();
- wndcls.hCursor = afxData.hcurArrow;
- wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
- wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
- if (_AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView, AFX_IDI_STD_FRAME))
- //第二个参数就是 MFC帮定义好的 类名
- fRegisteredClasses |= AFX_WNDFRAMEORVIEW_REG;
- }
复制代码
_AfxRegisterWithIcon()函数
- AFX_STATIC BOOL AFXAPI _AfxRegisterWithIcon(WNDCLASS* pWndCls,
- LPCTSTR lpszClassName, UINT nIDIcon)
- {
- pWndCls->lpszClassName = lpszClassName;
- //这里的窗口类名赋值了
- HINSTANCE hInst = AfxFindResourceHandle(
- ATL_MAKEINTRESOURCE(nIDIcon), ATL_RT_GROUP_ICON);
- if ((pWndCls->hIcon = ::LoadIconW(hInst, ATL_MAKEINTRESOURCEW(nIDIcon))) == NULL)
- {
- // use default icon
- pWndCls->hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
- }
- return AfxRegisterClass(pWndCls);
- //这个函数执行RegisterClass(lpWndClass) 在执行 API注册函数 注册类
- }
复制代码
AfxHookWindowCreate()函数
_AfxCbtFilterHook()钩子函数
- void AFXAPI AfxHookWindowCreate(CWnd* pWnd)
- {
- SetWindowsHookEx(WH_CBT,
- _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
- //HOOK 窗口的创建过程。
- //也就是说窗口创建完毕后直接跳转_AfxCbtFilterHook()函数!!
- pThreadState->m_pWndInit = pWnd;
- //_module_thread 保存窗口对象指针
- }
- _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
- {
- WNDPROC afxWndProc = AfxGetAfxWndProc();// == &AfxWndProc
- oldWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
- }
- NDPROC AFXAPI AfxGetAfxWndProc()
- {
- #ifdef _AFXDLL
- return AfxGetModuleState()->m_pfnAfxWndProc;
- #else
- return &AfxWndProc;
- #endif
- }
复制代码
nReturnCode = pThread->Run();//这里其实是消息循环
接下来是MFC的消息映射原理。
|
上一篇: 浅谈MFC框架内部结构 一下一篇: 浅谈MFC框架内部结构 三
|