1、MFC视图结构框架分析MFC文档视图结构框架分析1:程序的“导火索”-theAppCmyApp theApp;在声明对象的同时,调用其构造函数。按C+的语法,首先要调用其基类Cwinapp的构造函数. 这个文件主要用于应用程序的一些初始化操作。class CWinApp : public CWinThread DECLARE_DYNAMIC(CWinApp)public:/ Constructor CWinApp(LPCTSTR lpszAppName = NULL); CWinApp:CWinApp(LPCTSTR lpszAppName) if (lpszAppName != NULL)
2、m_pszAppName = _tcsdup(lpszAppName); else m_pszAppName = NULL; / initialize CWinThread state AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); AFX_MODULE_THREAD_STATE* pThreadState = pModuleState-m_thread; ASSERT(AfxGetThread() = NULL); pThreadState-m_pCurrentWinThread = this; ASSERT(AfxGe
3、tThread() = this); m_hThread = :GetCurrentThread(); m_nThreadID = :GetCurrentThreadId(); / initialize CWinApp state ASSERT(afxCurrentWinApp = NULL); / only one CWinApp object please pModuleState-m_pCurrentWinApp = this; ASSERT(AfxGetApp() = this); / in non-running state until WinMain m_hInstance = N
4、ULL; m_hLangResourceDLL = NULL; m_pszHelp = NULL; m_pszPro = NULL; m_pszRegistryKey = NULL; m_pszExeName = NULL; m_pRecent = NULL; m_pDocManager = NULL; m_atomApp = m_atomSystemTopic = NULL; m_lpCmdLine = NULL; m_pCmdInfo = NULL; / initialize wait cursor state m_nWaitCursorCount = 0; m_hcurWaitCurso
5、rRestore = NULL; / initialize current printer state m_hDevMode = NULL; m_hDevNames = NULL; m_nNumPreviewPages = 0; / not specified (defaults to 1) / initialize DAO state m_lpfnDaoTerm = NULL; / will be set if AfxDaoInit called / other initialization m_bHelpMode = FALSE; m_eHelpType = afxWinHelp; m_n
6、SafetyPoolSize = 512; / default size2:theApp之后的隐藏代码,由他控制整个程序的流程。_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) / call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);其中有宏定义:#define _tWinMain wWinMainint AFXAPI AfxWinMa
7、in(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) ASSERT(hPrevInstance = NULL); int nReturnCode = -1; CWinThread* pThread = AfxGetThread();;/ CWinApp是从CWinThread派生的, CWinApp* pApp = AfxGetApp(); /实质上就是pThread=pApp / AFX internal initialization if (!AfxWinInit(hInstance
8、, hPrevInstance, lpCmdLine, nCmdShow) /用于初始化 goto InitFailure; / App global initializations (rare) if (pApp != NULL & !pApp-InitApplication() /用于初始化 goto InitFailure; / Perform specific initializations if (!pThread-InitInstance() /注意多态性 virtual BOOL InitInstance(); /又因为pThread=pApp,所以调用pApp- InitIns
9、tance() if (pThread-m_pMainWnd != NULL) TRACE(traceAppMsg, 0, Warning: Destroying non-NULL m_pMainWndn); pThread-m_pMainWnd-DestroyWindow(); nReturnCode = pThread-ExitInstance(); goto InitFailure; nReturnCode = pThread-Run(); /控制消息循环InitFailure:#ifdef _DEBUG / Check for missing AfxLockTempMap calls
10、if (AfxGetModuleThreadState()-m_nTempMapLock != 0) TRACE(traceAppMsg, 0, Warning: Temp map lock count non-zero (%ld).n, AfxGetModuleThreadState()-m_nTempMapLock); AfxLockTempMaps(); AfxUnlockTempMaps(-1);#endif AfxWinTerm(); return nReturnCode;由上面的程序可以看到几个很重要的函数 (1)AfxWinInit(hInstance, hPrevInstanc
11、e, lpCmdLine, nCmdShow) goto InitFailure;(2) pApp-InitApplication()(3) pThread-InitInstance()(4) pThread-Run()其中1,2 也是完成程序的一些初始化工作,4 主要是为了处理消息,3呢,很关键,我们运行时看到的窗口就是从这里产生。下面一一介绍3:程序自动产生的InitInstance()函数以下是自动生成的InitInstance()源程序:BOOL CmyApp:InitInstance() / 如果一个运行在 Windows XP 上的应用程序清单指定要 / 使用 ComCtl32.d
12、ll 版本 6 或更高版本来启用可视化方式, /则需要 InitCommonControls()。否则,将无法创建窗口。 InitCommonControls(); CWinApp:InitInstance(); / 初始化 OLE 库 if (!AfxOleInit() AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; AfxEnableControlContainer(); / 标准初始化 / 如果未使用这些功能并希望减小 / 最终可执行文件的大小,则应移除下列 / 不需要的特定初始化例程 / 更改用于存储设置的注册表项 / TODO: 应
13、适当修改该字符串, / 例如修改为公司或组织名 SetRegistryKey(_T(应用程序向导生成的本地应用程序); LoadStdPro(4); / 加载标准 INI 文件选项(包括 MRU) / 注册应用程序的文档模板。文档模板 / 将用作文档、框架窗口和视图之间的连接 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_myTYPE, RUNTIME_CLASS(CmyDoc), RUNTIME_CLASS(CChildFrame), / 自定义 MDI 子框架 RUNTIME_CLASS(
14、CmyView); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); / 创建主 MDI 框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame | !pMainFrame-LoadFrame(IDR_MAINFRAME) return FALSE; m_pMainWnd = pMainFrame; / 仅当具有后缀时才调用 DragAcceptFiles / 在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生 / 分析标准外壳命令
15、、DDE、打开文件操作的命令行 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); / 调度在命令行中指定的命令。如果 / 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。 if (!ProcessShellCommand(cmdInfo) /引发窗口注册 return FALSE; / 主窗口已初始化,因此显示它并对其进行更新 pMainFrame-ShowWindow(m_nCmdShow); pMainFrame-UpdateWindow(); re
16、turn TRUE;其中,注册窗口用到了一下函数,比较长,如下:BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister) / mask off all classes that are already registered AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); fToRegister &= pModuleState-m_fRegisteredClasses; if (fToRegister = 0) return TRUE; LONG fRegisteredClasses
17、= 0; / common initialization WNDCLASS wndcls; memset(&wndcls, 0, sizeof(WNDCLASS); / start with NULL defaults wndcls.lpfnWndProc = DefWindowProc; /窗口处理函数 wndcls.hInstance = AfxGetInstanceHandle(); wndcls.hCursor = afxData.hcurArrow; INITCOMMONCONTROLSEX init; init.dwSize = sizeof(init); / work to re
18、gister classes as specified by fToRegister, populate fRegisteredClasses as we go if (fToRegister & AFX_WND_REG) / Child windows - no brush, no icon, safest default class styles wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.lpszClassName = _afxWnd; if (AfxRegisterClass(&wndcls) fRegiste
19、redClasses |= AFX_WND_REG; if (fToRegister & AFX_WNDOLECONTROL_REG) / OLE Control windows - use parent DC for speed wndcls.style |= CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.lpszClassName = _afxWndOleControl; if (AfxRegisterClass(&wndcls) fRegisteredClasses |= AFX_WNDOLECONTROL_REG;
20、 if (fToRegister & AFX_WNDCONTROLBAR_REG) / Control bar windows wndcls.style = 0; / control bars dont handle double click wndcls.lpszClassName = _afxWndControlBar; wndcls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); if (AfxRegisterClass(&wndcls) fRegisteredClasses |= AFX_WNDCONTROLBAR_REG; if (fToRe
21、gister & AFX_WNDMDIFRAME_REG) / MDI Frame window (also used for splitter window) wndcls.style = CS_DBLCLKS; wndcls.hbrBackground = NULL; if (_AfxRegisterWithIcon(&wndcls, _afxWndMDIFrame, AFX_IDI_STD_MDIFRAME) fRegisteredClasses |= AFX_WNDMDIFRAME_REG; if (fToRegister & AFX_WNDFRAMEORVIEW_REG) / SDI
22、 Frame or MDI Child windows or views - normal colors wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); if (_AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView, AFX_IDI_STD_FRAME) fRegisteredClasses |= AFX_WNDFRAMEORVIEW_REG; if (fToRegister & AFX_W
23、NDCOMMCTLS_REG) / this flag is compatible with the old InitCommonControls() API init.dwICC = ICC_WIN95_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WIN95CTLS_MASK); fToRegister &= AFX_WIN95CTLS_MASK; if (fToRegister & AFX_WNDCOMMCTL_UPDOWN_REG) init.dwICC = ICC_UPDOWN_CLASS; fReg
24、isteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_UPDOWN_REG); if (fToRegister & AFX_WNDCOMMCTL_TREEVIEW_REG) init.dwICC = ICC_TREEVIEW_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_TREEVIEW_REG); if (fToRegister & AFX_WNDCOMMCTL_TAB_REG) init.dwICC = ICC_T
25、AB_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_TAB_REG); if (fToRegister & AFX_WNDCOMMCTL_PROGRESS_REG) init.dwICC = ICC_PROGRESS_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_PROGRESS_REG); if (fToRegister & AFX_WNDCOMMCTL_LISTVIEW_REG) in
26、it.dwICC = ICC_LISTVIEW_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_LISTVIEW_REG); if (fToRegister & AFX_WNDCOMMCTL_HOTKEY_REG) init.dwICC = ICC_HOTKEY_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_HOTKEY_REG); if (fToRegister & AFX_WNDCOMM
27、CTL_BAR_REG) init.dwICC = ICC_BAR_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_BAR_REG); if (fToRegister & AFX_WNDCOMMCTL_ANIMATE_REG) init.dwICC = ICC_ANIMATE_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_ANIMATE_REG); if (fToRegister & AFX_WNDCOMMCTL_INTERNET_REG) init.dwICC = ICC_INTERNET_CLASSES; fRegisteredClasses |= _AfxIn
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1