• VS2010 单文档+多视图+Outlook风格


    先来个段子

    十年生死两茫茫,喜羊羊,灰太狼。舒克贝塔,蓝猫话凄凉。纵使相逢应不识,圣斗士,美猴王。老夫聊发少年狂,治肾亏,不含糖。锦帽貂裘,千骑用康王。为报倾城随太守,三百年,九芝堂。夜来幽梦忽还乡,学外语,新东方。相顾无言,洗洗更健康。
    

    ------------------调皮的分割线-----------------------

    Outlook风格在http://blog.csdn.net/wlsgzl/article/details/32083145中已经实现了,这里只搞一下多视图。

    =======好羡慕出双入对的分割线========

    先分析下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 ();
    }
    


    大致就是这些。




  • 相关阅读:
    python环境准备(2020-1-13)
    git知识
    toolbar的相关知识
    Android开发极光推送功能实现步骤
    Android开发分享功能实现步骤
    使用tablayout和viewpager实现简单的页面布局
    activity与fragment的交互(一个activity跳转到另一个fragment)
    java中堆区和栈区的区别
    WebView的基本使用
    final的用法
  • 原文地址:https://www.cnblogs.com/wlsandwho/p/4202109.html
Copyright © 2020-2023  润新知