全部博文(263)
分类: WINDOWS
2009-10-27 22:34:10
类名 |
作用 |
CMDITestApp |
派生于CWinApp的应用程序类。 |
CMainFrame |
派生于CMDIFrameWnd的MDI框架窗口类。 |
CMDITestDoc |
派生于CDocument的文档类。 |
CChildFrame |
派生于CMDIChildWnd的MDI子窗口类。 |
CMDITestView |
派生于CView的文档显示类。 |
CMainFrame (Menu, Toolbar …)
[StatusBar] |
// CMDITestApp 初始化 BOOL CMDITestApp::InitInstance() |
BOOL CMDITestApp::InitInstance() { InitCommonControls(); // 这里删减了大量注释和错误处理 CWinApp::InitInstance(); AfxOleInit(); AfxEnableControlContainer(); SetRegistryKey(_T("应用程序向导生成的本地应用程序")); LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU) TRACE("Before CMultiDocTemplate\n"); // 注册应用程序的文档模板。文档模板 // 将用作文档、框架窗口和视图之间的连接 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_MDITestTYPE, RUNTIME_CLASS(CMDITestDoc), RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CMDITestView)); if (!pDocTemplate) return FALSE; TRACE("Before AddDocTemplate\n"); AddDocTemplate(pDocTemplate); // 创建主 MDI 框架窗口 TRACE("Before new CMainFrame\n"); CMainFrame* pMainFrame = new CMainFrame; TRACE("Before pMainFrame->LoadFrame\n"); if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; TRACE("Before ParseCommandLine\n"); CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。如果 // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。 TRACE("Before ProcessShellCommand\n"); if (!ProcessShellCommand(cmdInfo)) return FALSE; TRACE("Before pMainFrame->ShowWindow\n"); // 主窗口已初始化,因此显示它并对其进行更新 pMainFrame->ShowWindow(m_nCmdShow); TRACE("Before pMainFrame->UpdateWindow\n"); pMainFrame->UpdateWindow(); return TRUE; } |
CMultiDocTemplate* pDocTemplate = new CMultiDocTemplate(IDR_MDITestTYPE, RUNTIME_CLASS(CMDITestDoc), RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CMDITestView)); AddDocTemplate(pDocTemplate); (作了一点点简化) |
CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; |
CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。如果用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。 if (!ProcessShellCommand(cmdInfo)) // ß 这里创建出初始空文档 return FALSE; |
pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); |
CRuntimeClass* m_pDocClass; // class for creating new documents CRuntimeClass* m_pFrameClass; // class for creating new frames CRuntimeClass* m_pViewClass; // class for creating new views |
m_pDocClass |
表示文档类类型,在此例子中就是CMDITestDoc |
m_pFrameClass |
表示容纳View窗口的框架窗口类类型,此例中为CChildFrame |
m_pViewClass |
表示显示文档的View视类类型,此例中为CMDITestView |
BOOL CMDIFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext) { // 调用基类 CFrameWnd 的 LoadFrame, pContext 在创建主窗口时 = NULL // pParentWnd = NULL if (!CFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext)) return FALSE; // save menu to use when no active MDI child window is present ASSERT(m_hWnd != NULL); // 主窗口带有菜单,所以。。。 m_hMenuDefault = ::GetMenu(m_hWnd); if (m_hMenuDefault == NULL) TRACE(traceAppMsg, 0, "Warning: CMDIFrameWnd without a default menu.\n"); return TRUE; } |
BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext) { // only do this once ASSERT_VALID_IDR(nIDResource); // nIDResource = 128, IDR_MAINFRAME ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource); m_nIDHelp = nIDResource; // ID for help context (+HID_BASE_RESOURCE) CString strFullString; if (strFullString.LoadString(nIDResource)) // = “MDITest” AfxExtractSubString(m_strTitle, strFullString, 0); // 取得第一个子串 VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); // attempt to create the window // GetIconWndClass 会调用 virtual PreCreateWindow 函数,别处也会调用,从而 // 使得子类的PreCreateWindow 将被调用多次 LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource); CString strTitle = m_strTitle; // 调用 CFrameWnd::Create() 实际创建出窗口。 // 注意:在这里将给 CMainFrame 发送 WM_CREATE 等多个消息。触发 CMainFrame 的 // OnCreate 处理等。 if (!Create(lpszClass, strTitle, dwDefaultStyle, rectDefault, pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext)) { return FALSE; // will self destruct on failure normally } // save the default menu handle, 好像 CMDIFrameWnd 也保存了一次? ASSERT(m_hWnd != NULL); m_hMenuDefault = ::GetMenu(m_hWnd); // load accelerator resource LoadAccelTable(MAKEINTRESOURCE(nIDResource)); // WM_INITIALUPDATE 是 MFC 发明的消息,参见后面的说明。 if (pContext == NULL) // send initial update SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); return TRUE; } |
WM_INITIALUPDATE This message is sent by the document template to all descendants of a frame window when it is safe for them to do their initial update. It maps to a call to CView::OnInitialUpdate but can be used in other CWnd-derived classes for other one-shot updating.
|