支持HW团队,就支付宝领取下面的红包吧!(2018年3月31前,就几毛,也会几块,可以和其他红包叠加使用),你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

小伙伴们,给大家发红包喽!人人可领,领完就能用。祝大家领取的红包金额大大大!#吱口令#长按复制此消息,打开支付宝就能领取!er1OEj73Uj

登入 注册 | 验证
| 搜索
HelloWorld论坛 : > 计算机科学、技术、教学> HelloWorld团队自营项目> HW数据库模型> 【转载】MFC多文档应用程序同时显示两个视图
 
 
 
 
类别:VC MFC 阅读:4044 评论:0 时间:三月 4, 2015, 3:47 p.m. 关键字:

 

 来源:http://www.cppblog.com/cs-xiaolee/archive/2011/12/01/161292.html

本文是对网络上各种资料进行了梳理,并在VisualC++6.0下进行了实验测试。
需要解决的问题如下:
1. 在MFC多文档应用程序中同时显示两个视图,其中一个视图显示电路原理图,另外一个显示仿真结果。
2. 两个视图需要同时显示,但是并非分割显示,而是通过切换(切换功能尚未实现)

在多文档应用程序中,视图类是由CMultiDocTemplate来负责管理的。自动生成的MFC框架中在C**App类的InitInstance()函数中,有以下的语句:

1CMultiDocTemplate* pDocTemplate;
2pDocTemplate= new CMultiDocTemplate(
3  IDR_**TYPE,
4  RUNTIME_CLASS(C**Doc),
5  RUNTIME_CLASS(CChildFrame), // custom MDI child frame
6  RUNTIME_CLASS(C**View));
7 AddDocTemplate(pDocTemplate);
8


由于有两个视图需要显示,所以需要创建两个CMultiDocTemplate对象来管理,其中每个对象管理不同的View对象
为了方便在其他类中引用,我在C**App类中增

1public:
2    CMultiDocTemplate* m_pTemplateDataView;
3    CMultiDocTemplate* m_pTemplateSchematicView;


然后在InitInstance()函数替换原有创建CMultiDocTemplate对象指针的语句,这里我的代码是:

 1m_pTemplateSchematicView = new CMultiDocTemplate(
 2        IDR_TR_UWBTYPE,
 3        RUNTIME_CLASS(CTR_UWBDoc),
 4        RUNTIME_CLASS(CChildFrame), // custom MDI child frame
 5        RUNTIME_CLASS(CTR_UWBView));
 6    AddDocTemplate(m_pTemplateSchematicView);
 7
 8    m_pTemplateDataView = new CMultiDocTemplate(
 9        IDR_TR_UWBTYPE,
10        RUNTIME_CLASS(CTR_UWBDoc),
11        RUNTIME_CLASS(CChildFrame), // custom MDI child frame
12        RUNTIME_CLASS(CDataView));
13    AddDocTemplate(m_pTemplateDataView);


而此时就有了两个视图,而MFC应用程序默认是只打开一个视图的,所以这时运行程序就会出现一个要求选择显示哪个视图的对话框
为了自动显示,我们需要重写C**App类的OnFileNew()函数

1void CTR_UWBApp::OnFileNew()
2{
3    m_pTemplateSchematicView->OpenDocumentFile(NULL);
4}

注意:该函数无法用classwizard添加,只能使用member function添加

根据MSDN2001,需要在C**App类的消息响应中添加一句话才能使该函数被响应

1BEGIN_MESSAGE_MAP(CTR_UWBApp, CWinApp)
2    //{{AFX_MSG_MAP(CTR_UWBApp)
3    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
4    ON_COMMAND(ID_FILE_NEW, OnFileNew)
5        // NOTE - the ClassWizard will add and remove mapping macros here.
6        //    DO NOT EDIT what you see in these blocks of generated code!
7    //}}AFX_MSG_MAP

红色的是添加的那个句子。

注:MSDN2001:
CWinApp::OnFileNew

You must add an 
ON_COMMAND( ID_FILE_NEW, OnFileNew ) 
statement to your CWinApp class message map to enable this member function.

到目前为止,程序还只能显示一个view,另外一个view还没有被显示出来。
我们需要在C**Doc类中添加一些东西
在OnNewDocument()函数中我们添加如下

1CTR_UWBApp* p_app = (CTR_UWBApp*)AfxGetApp();
2CreateNewWindow(p_app->m_pTemplateDataView, this); 


然后添加成员函数:

 1CFrameWnd* CTR_UWBDoc::CreateNewWindow(CDocTemplate *pTemplate, CDocument *pDocument)
 2{
 3    ASSERT_VALID( pTemplate );   
 4    ASSERT_VALID( pDocument );   
 5    CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, NULL);
 6    if( pFrame == NULL )   
 7    {
 8        TRACE0( "Warning: failed to create new frame.\n" );   
 9        return NULL;   
10    }
   
11    CRect rect;
12    GetClientRect(pFrame->m_hWnd,&rect);
13    pFrame->MoveWindow(0,0,rect.Width(),rect.Height());
14    ASSERT_KINDOF( CFrameWnd, pFrame );   
15    pTemplate->InitialUpdateFrame( pFrame, pDocument );   
16    
17    return pFrame;  
18}

 

此时再运行则可以一下子显示两个view了,不是重叠的。但是原理图view显示不完整,因为不是全窗口大小。我把它设置了一下
在CChildFrame类中改写虚函数ActivateFrame(int nCmdShow) ,nCmdShow默认值就是-1

1void CChildFrame::ActivateFrame(int nCmdShow) 
2{
3    // TODO: Add your specialized code here and/or call the base class
4    if (nCmdShow == -1) {
5        nCmdShow = SW_SHOWMAXIMIZED;
6    }

7
8    CMDIChildWnd::ActivateFrame(nCmdShow);
9}

这样显示的窗口就最大化了
后面会继续更新,补充用tab键或其它方法在两个视图之间切换


本文参考的网址和文档:

http://topic.csdn.net/u/20111019/09/b54b0574-162d-4f80-8209-660070ac3feb.html

http://hi.baidu.com/liyy011/blog/item/150ce08080b449d2bd3e1e19.html

http://topic.okbase.net/200612/2006122710/2831427.html

http://blog.csdn.net/zhuimengzh/article/details/6976011

MSDN2001
侯捷著,《深入浅出MFC》

[挂载人]初学MPEG

个人签名--------------------------------------------------------------------------------

Please Login (or Sign Up) to leave a comment