在MDI程序中,新建和打開菜單都是系統自帶的,有些時候並不能通過ON_FILE_NEW來顯示出視圖,某種類型的視圖往往可能只顯示一個。
那么撇開系統自帶的ON_FILE_NEW命令,我們自己寫一個。
在程序啟動時,我們不想新建出一個空的視圖,只要大的框架就行。
在app的InitInstance函數中,將下面幾行注釋掉
// 分析標准外殼命令、DDE、打開文件操作的命令行
//CCommandLineInfo cmdInfo;
//ParseCommandLine(cmdInfo);
// 調度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 啟動應用程序,則返回 FALSE。
//if (!ProcessShellCommand(cmdInfo))
// return FALSE;
創建主框架的代碼是:
// 創建主 MDI 框架窗口
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame;
pMainFrame->ShowWindow(SW_SHOW);
pMainFrame->UpdateWindow();
為了演示創建視圖,我們可以在菜單中添加一個菜單項,並在MainFrame中處理,當然在WinApp中也可以。代碼很簡單
void CMainFrame::OnTestCreate()
{
// TODO: 在此添加命令處理程序代碼
CDocTemplate* pDocTemplate = ((CxxApp*)AfxGetApp())->m_pDocTemplate;
ASSERT_VALID(pDocTemplate);
pDocTemplate->OpenDocumentFile(NULL);
}
我翻過mfc里面的源碼,主要處理是:
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument();
if (pDocument == NULL)
{
TRACE(traceAppMsg, 0, "CDocTemplate::CreateNewDocument returned NULL.\n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return NULL;
}
ASSERT_VALID(pDocument);
BOOL bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = FALSE; // don't destroy if something goes wrong
CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);
pDocument->m_bAutoDelete = bAutoDelete;
if (pFrame == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
delete pDocument; // explicit delete on error
return NULL;
}
ASSERT_VALID(pFrame);
if (lpszPathName == NULL)
{
// create a new document - with default document name
SetDefaultTitle(pDocument);
// avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = TRUE;
if (!pDocument->OnNewDocument())
{
// user has be alerted to what failed in OnNewDocument
TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE.\n");
pFrame->DestroyWindow();
return NULL;
}
// it worked, now bump untitled count
m_nUntitledCount++;
}
else
{
// open an existing document
CWaitCursor wait;
if (!pDocument->OnOpenDocument(lpszPathName))
{
// user has be alerted to what failed in OnOpenDocument
TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE.\n");
pFrame->DestroyWindow();
return NULL;
}
pDocument->SetPathName(lpszPathName);
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}