VS2010 單文件+多檢視+Outlook風格
阿新 • • 發佈:2019-02-14
先來個段子
十年生死兩茫茫,喜羊羊,灰太狼。舒克貝塔,藍貓話淒涼。縱使相逢應不識,聖鬥士,美猴王。老夫聊發少年狂,治腎虧,不含糖。錦帽貂裘,千騎用康王。為報傾城隨太守,三百年,九芝堂。夜來幽夢忽還鄉,學外語,新東方。相顧無言,洗洗更健康。
------------------調皮的分割線-----------------------
=======好羨慕出雙入對的分割線========
先分析下VS2010給的示例程式碼OutlookMultiViews,看看相關的部分。
在COutlookMultiViewsApp的InitInstance中
將CSingleDocTemplate的建構函式的第4個引數改為自己的類
BOOL COutlookMultiViewsApp::InitInstance() { // Initialize OLE libraries if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } 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. // 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("Microsoft\\MFC\\Samples")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) SetRegistryBase (_T("Settings")); // Initialize all Managers for usage. They are automatically constructed // if not yet present InitContextMenuManager(); InitKeyboardManager(); // 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(COutlookMultiViewsDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(/*COutlookMultiViewsView*/CFV1));//改為自己的檢視類 AddDocTemplate(pDocTemplate); // 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; }
主框架視窗類CMainFrame中的檢視成員變數
// Array of views attached to single document
CView * m_pViews[NUMVIEWS];
// Index to current view
UINT m_nCurView;
在CMainFrame的InitViews中
void CMainFrame::InitViews () { m_nCurView = 0; // Save index of the currently active view class CView* pActiveView = GetActiveView(); m_pViews[0] = pActiveView;//這裡MFC讓預設的模板作為第一個檢視陣列成員 // m_pViews[1] = (CView*) new CView1; // m_pViews[2] = (CView*) new CView2; // m_pViews[3] = (CView*) new CView3; m_pViews[1] = (CView*) new CFV2;//改為自己的檢視類,我這裡是CFormView型別的 m_pViews[2] = (CView*) new CFV3;//改為自己的檢視類,我這裡是CFormView型別的 m_pViews[3] = (CView*) new CFV4;//改為自己的檢視類,我這裡是CFormView型別的 CDocument* pCurrentDoc = GetActiveDocument(); // Initialize a CCreateContext to point to the active document. // With this context, the new view is added to the document // when the view is created in CView::OnCreate(). CCreateContext newContext; newContext.m_pNewViewClass = NULL; newContext.m_pNewDocTemplate = NULL; newContext.m_pLastView = NULL; newContext.m_pCurrentFrame = NULL; newContext.m_pCurrentDoc = pCurrentDoc; CRect rect(0, 0, 0, 0); // gets resized later for (int nView = 1; nView < NUMVIEWS; nView++) { // Create the new view. In this example, the view persists for // the life of the application. The application automatically // deletes the view when the application is closed. m_pViews[nView]->Create(NULL, NULL, (AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE), // views are created with the style of AFX_WS_DEFAULT_VIEW // In MFC 4.0, this is (WS_BORDER | WS_VISIBLE | WS_CHILD) rect, this, IDD_FORMVIEW1-1 + nView, &newContext);//這裡面的ID是連續定義的(在resource.h中),便於迴圈處理。 // When a document template creates a view, the WM_INITIALUPDATE // message is sent automatically. However, this code must // explicitly send the message, as follows. //m_pViews [nView]->OnInitialUpdate();//這裡要注意,如果是CFormView型別的檢視,要注掉。 } }
然後再在COutlookMultiViewsApp的InitInstance中新增對InitViews的呼叫。
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
((CMainFrame*)m_pMainWnd)->InitViews ();//呼叫InitViews
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
在CMainFrame的訊息對映巨集中
感覺這個是手工新增的,因為Wizard新增不了ON_COMMAND_RANGE的巨集,好像。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CUSTOMIZE, OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_RESETTOOLBAR, OnToolbarReset)
ON_REGISTERED_MESSAGE(AFX_WM_TOOLBARMENU, OnToolbarContextMenu)
ON_COMMAND(ID_VIEW_OUTLOOKBAR, OnViewOutlookBar)
ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLOOKBAR, OnUpdateViewOutlookBar)
ON_COMMAND_RANGE(ID_SHORTCUT_1, ID_SHORTCUT_4, OnOutlookBarShortcut)//就是這個,對這四個ID代表的按鈕做處理
ON_UPDATE_COMMAND_UI_RANGE(ID_SHORTCUT_1, ID_SHORTCUT_4, OnUpdateOutlookBarShortcut)
ON_COMMAND(ID_VIEW_CAPTIONBAR, OnViewCaptionBar)
ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONBAR, OnUpdateViewCaptionBar)
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_2000, ID_VIEW_APPLOOK_2007_4, OnAppLook)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_2000, ID_VIEW_APPLOOK_2007_4, OnUpdateAppLook)
END_MESSAGE_MAP()
在CMainFrame的OnOutlookBarShortcut中
void CMainFrame::OnOutlookBarShortcut(UINT id)
{
const int nIndex = id - ID_SHORTCUT_1;//點選的是哪一個。連續ID定義的好處。
ASSERT( nIndex >=0 && nIndex < NUMVIEWS );
if ( nIndex < 0 || nIndex >= NUMVIEWS )
return;
if (!m_pViews)
return;
CView* pNewView = m_pViews[nIndex];
if (!pNewView)
return;
CView* pActiveView =GetActiveView();
if ( !pActiveView ) // No currently active view
return;
if ( pNewView == pActiveView ) // Already there
return;
m_nCurView = nIndex; // Store the new current view's index
// exchange view window ID's so RecalcLayout() works
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID,::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
// Display and update the new current view - hide the old one
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
SetActiveView(pNewView);
RecalcLayout();
pNewView->Invalidate();
//下面的這個是改變標題欄的內容,無關。
CString strCaption;
strCaption.Format (_T("View %d"), nIndex + 1);
m_wndCaptionBar.SetText (strCaption);
m_wndCaptionBar.RedrawWindow ();
}
大致就是這些。