C++ 如何通过单击大型机内的按钮更改MFC视图

C++ 如何通过单击大型机内的按钮更改MFC视图,c++,visual-c++,view,mfc,sdi,C++,Visual C++,View,Mfc,Sdi,我想通过单击窗口内的按钮来更改显示的视图 . 我的项目设置: 我制作了一个没有文档/视图支持的MFC项目(SDI) 我在Designer中又创建了两个视图,并向其中添加了类。新视图类派生自CFormView。我将新视图类的构造函数和析构函数更改为public 将它们添加为MainFrm.h的指针: CMainView*m_pMainView; CSecondView*m_pSecondView; 我更改了MainFrm.cpp的OnCreate()、OnSetFocus()和OnCmdMsg(

我想通过单击窗口内的按钮来更改显示的视图 . 我的项目设置:

  • 我制作了一个没有文档/视图支持的MFC项目(SDI)
  • 我在Designer中又创建了两个视图,并向其中添加了类。新视图类派生自
    CFormView
    。我将新视图类的构造函数和析构函数更改为public

  • 将它们添加为MainFrm.h的指针:

  • CMainView*m_pMainView;
    CSecondView*m_pSecondView;
    
  • 我更改了MainFrm.cpp的
    OnCreate()
    OnSetFocus()
    OnCmdMsg()
    方法,如下所示: (允许展示我与设计师制作的FormView)
  • int-CMainFrame::OnCreate(LPCREATESTRUCT-LPCREATESTRUCT)
    {
    if(CFrameWnd::OnCreate(lpCreateStruct)=-1)
    返回-1;
    //首先,构建视图上下文结构
    ccx;
    //指定要从中生成视图的类
    ccx.m_pNewViewClass=运行时类(CMainView);
    //使用该结构,创建一个视图
    m_pMainView=动态向下广播(CMainView,this->CreateView(&ccx));
    如果(!m_pMainView)
    {
    TRACE0(“创建视图失败”);
    }
    //重新设计布局
    RecalcLayout();
    //显示视图并进行初始更新
    m_pMainView->ShowWindow(SW_SHOW);
    m_pMainView->OnInitialUpdate();
    //将此视图设置为活动
    SetActiveView(m_pMainView);
    //命令它调整父窗口的大小以适应
    m_pMainView->resizeparentofit(FALSE);
    返回0;
    }
    ...
    void CMainFrame::OnSetFocus(CWnd*/*pOldWnd*/)
    {
    m_pMainView->SetFocus();
    }
    BOOL-CMainFrame::oncmdmdmgsg(UINT-nID、int-nCode、void*pExtra、AFX_-CMDHANDLERINFO*pHandlerInfo)
    {
    if(m_pMainView->oncmdmdmsg(nID、nCode、pExtra、pHandlerInfo))
    返回TRUE;
    返回CFrameWnd::oncmdmmsg(nID、nCode、pExtra、pHandlerInfo);
    }
    
    现在我的问题来了!我在第一个显示的视图上有一个按钮,如果你点击它,视图应该会改变。我使用设计器中的事件处理程序生成了以下函数:

    void CMainView::OnBnClickedButton1()
    {
    //在这里做什么?我想通过单击按钮将当前视图更改为另一个视图
    }
    
    如果我在MainFrm.cpp类中处理它,例如使用菜单按钮,它就没有问题。。。这很好:

    void CMainFrame::OnViewNextview()
    {
    ccx2;
    ccx2.m_pNewViewClass=运行时类(CSecondView);
    m_pSecondView=DYNAMIC_DOWNCAST(CSecondView,this->CreateView(&ccx2));
    RecalcLayout();
    m_pMainView->ShowWindow(SW_SHOW);
    m_pMainView->OnInitialUpdate();
    SetActiveView(m_pMainView);
    m_pMainView->resizeparentofit(FALSE);
    }
    
    我试图在
    CMainFrame
    中编写一个函数,并在
    CMainView::OnBnClickedButton1()
    中调用此函数,但我不知道如何获取当前的MainFrm对象。MainFrm上的指针或其成员在
    CMainView
    中不起作用

    为了解决我的问题,我搜索了好几天的红色教程。我还尝试了文档/视图支持,如下所示: 但是我不知道在哪里正确调用switchView()


    也许任何人都可以帮助…

    首先,你不应该真的重写
    oncmdmmsg
    ——相反,在头文件中使用
    声明消息映射
    ,在实现文件中使用
    开始消息映射
    /
    结束消息映射
    ,并在这两个宏之间插入处理程序消息

    我看到您的
    CMainView
    类中已经有了一个按钮单击的处理程序!从这里开始,您应该调用
    CMainFrame
    函数以切换到下一个视图-就像您在发出菜单命令时所做的那样(您说它有效)。将该函数设置为公共函数,并允许MainView类访问指向主框架的指针(或者使用
    AfxGetMainWnd()
    并将其强制转换为类的指针)。大概是这样的:

    void CMainView::OnBnClickedButton1()
    {
        AfxGetMainWnd()->PostMessage(WM_COMMAND, menuID); // ID of menu command that works!
    }
    

    热烈拥抱阿德里安,我成功了! 我还成功添加了第三个视图:)

    如果要实现更多视图,隐藏最后显示的窗口非常重要。你可以这样做:

    void CMainFrame::OnView3()
    {
    ccx3;
    ccx3.m_pNewViewClass=运行时类(CThirdView);
    m_pThirdView=DYNAMIC_DOWNCAST(CThirdView,this->CreateView(&ccx3));
    RecalcLayout();
    m_pSecondView->ShowWindow(SW_HIDE);//隐藏最后一个窗口
    m_pThirdView->ShowWindow(SW_SHOW);//显示新窗口
    mpthirdview->OnInitialUpdate();
    SetActiveView(m_pThirdView);
    //mpthirdview->ResizeParentToFit(FALSE);//如果调用此选项,则窗口的大小与设计器中的大小相同
    }
    
    PS:很抱歉将CMInframe和MainView混淆了!我会试试这个,让你知道它是否有效!谢谢,很高兴它成功了!但我要再次强调,您应该取消对OnCmdMsg的覆盖!据我所知,它没有任何用处,但可能会导致很多很多问题!用于MainView窗口的消息将由框架发送到该窗口;发送到(和接收到)大型机的消息都是针对它的,而且只有它一个!是的,我对void CMainFrame::OnSetFocus()方法有问题。我试图从view2切换到View3,但焦点没有正确更改。也许你可以在这里给我一个提示。测试GetActiveView(),如果它不是空的,那么如果(GetActiveView()!=NULL){GetActiveView()->SetFocus();}我在OnSetFocus()中尝试了这个方法,但似乎没有效果,可以在框架窗口类中放置一个“CFormView*current”成员,将其设置为NULL或任何您想要的值(当您制作并显示每个表单时),并使用:current->SetFocus()。不确定SDI,但MDI应用程序将使用MDIGetActive()返回活动窗口的“帧”。