MFC实现原理
来源:互联网 发布:natapp 8080端口 编辑:程序博客网 时间:2024/04/28 08:42
通过VC++ 新建一个MFC单文档应用程序,其工程名为mfcproject.新建后通过类视图可以看到一共有5个类:
CAboutDlg:对话框类,如关于对话框
CMainFrame:应用程序框架类,包括工具栏菜单等
CMfcprojectApp:应用程序类
CMfcprojectDoc:文档类
CMfcprojectView:也是和文档有关的视图类
1、mfcproject.cpp文件中定义了全局类 CMfcprojectApp theApp;在这个地方设置断点,调试运行可以发现整个程序首先执行到这个地方。
2、全局变量定义后将会调用CMfcprojectApp 类的构造函数
3、从mfcproject.h中可以发现 CMfcprojectApp继承自CWinApp类(在APPCORE.cpp中),根据继承性原理,程序将会首先调用CWinApp类的构造函数,如果细心地话会发现CWinApp的构造函数有参数,但CMfcprojectApp类构造函数并没有带参数,这是怎么回事呢?再仔细看下CWinApp类的构造函数:CWinApp(LPCTSTR lpszAppName = NULL); 看见了没这里的参数是默认值,这也就是为什么CMfcprojectApp构造函数没有带参数的缘故了
4、定义好全局变量以后,就要找主函数入口了,MFC程序的主函数入口为
extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}
该函数在APPMODUL.cpp中,从这个函数可以看出真正的入口函数应该为AfxWinMain(Winmain.cpp中)
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ASSERT(hPrevInstance == NULL); int nReturnCode = -1; CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); //获取子类 // AFX internal initialization if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) goto InitFailure; // App global initializations (rare) if (pApp != NULL && !pApp->InitApplication()) goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) //初始化注册窗口 { if (pThread->m_pMainWnd != NULL) { TRACE0("Warning: Destroying non-NULL m_pMainWnd\n"); pThread->m_pMainWnd->DestroyWindow(); } nReturnCode = pThread->ExitInstance(); goto InitFailure; } nReturnCode = pThread->Run(); InitFailure: #ifdef _DEBUG // Check for missing AfxLockTempMap calls if (AfxGetModuleThreadState()->m_nTempMapLock != 0) { TRACE1("Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock); } AfxLockTempMaps(); AfxUnlockTempMaps(-1); #endif AfxWinTerm(); return nReturnCode; }
关键的语句是line8获取子类实例,line19初始化子类,完成窗口注册,line20可以在这些行上设置断点
5、 由于pThred当前指向子类,InitInstance函数是虚函数,因此 pThread->InitInstance()将调用子类的CMfcprojectApp::InitInstance()
BOOL CMfcprojectApp::InitInstance(){ AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need.#ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL#else Enable3dControlsStatic(); // Call this when linking to MFC statically#endif // Change the registry key under which our settings are stored. // TODO: You should modify this string to be something appropriate // such as the name of your company or organization. SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMfcprojectDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CMfcprojectView)); AddDocTemplate(pDocTemplate);//新建一个单文档的模板,并将 doc,view,frame类添加到该模板中。 // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo))//窗口的注册(不太确定) return FALSE; // The one and only window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_SHOW);//显示窗口 m_pMainWnd->UpdateWindow();//更新窗口 return TRUE;}
上述代码中红色部分是比较重要的地方,可以在这些地方设置断点。
6、窗口注册会调用函数BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)在文件WINCORE.CPP中
7、紧接着调用BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs),创建窗口
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){ if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs //此处修改cs,实现用户自定义窗口 return TRUE;}
8、接下来调用line3父类的precreatewindow函数
9、由于窗口包括frame框架类,因此需要调用cfrmwnd的create函数(WINFRM.cpp中),这个函数又会调用Cfrmwnd的父类CWnd::CreateEx函数
10、注册完窗口后就会执行消息响应,消息响应是通过 AfxWinMain中nReturnCode = pThread->Run()实现的
11、用一个dowhile循环实现消息循环 PumpMessage()
大概的MFC实现就写到这,可能有很多不对的地方,等熟悉以后再来更新!
- MFC RTTI实现原理
- MFC实现原理
- MFC实现原理
- MFC 消息映射实现原理
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- CMAP原理及其在MFC中的实现
- CMAP原理及其在MFC中的实现
- CMAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MAP原理及其在MFC中的实现
- MFC动态创建(dynamic creation)实现原理
- MAP原理及其在MFC中的实现
- MFC 模态对话框的实现原理
- java执行.bat文件
- JS 选中的DOM对象高亮处理
- hdu/hdoj 1083 Courses
- system V信号量和Posix信号量
- oracle体系结构
- MFC实现原理
- 浅谈HTTP中Get与Post的区别
- 如何name服务的配置文件
- WebResponse获取网页跳转后的地址
- 【COCOS2DX-LUA 脚本开发】解决自定义cpp类通过tolua++ binding LuaCocos2d后编译到Android运行黑屏(没有调用自定义cpp类)的问题!
- Graphics
- 解决ubuntu中文乱码问题的方法总结
- 做什么都好,关键是用心
- 合并资产负债表注意事项