代码之家  ›  专栏  ›  技术社区  ›  Rafal

如何在MFC中的CWnd中显示CFormView?

  •  2
  • Rafal  · 技术社区  · 7 年前

    我有一个SDI MFC应用程序,不支持文档/视图。我想在ChildView中嵌入CFormView和在资源编辑器中设计的控件。我该怎么做?

    MFC向导生成了3个文件:

    • 应用程序。cpp(源自 CWinApp )
    • 大型机。cpp(源自 CFrameWnd )
    • 儿童视图。cpp(源自 CWnd )

    现在,我已经生成了从 CFormView 哪里 IDD_MYVIEW 是资源GUI的生成ID。

    class MyFormView: public CFormView
    {
    public:
        enum { IDD = IDD_MYVIEW  };
    
        MyFormView(): CFormView(IDD) {};
        virtual ~MyFormView() {};
    }
    

    如何在ChildView中显示此MyFormView?

    当我再次尝试生成项目并在MFC向导中选中“文档/视图体系结构”复选框时,我将视图的基类更改为CFormView。我意识到应用程序初始化与最初生成的不同。

    目前,第一个应用程序的初始化如下:

    BOOL MfcApp::InitInstance() 
    {
        // (...)
    
        CMainFrame* pFrame = new CMainFrame;
        if (!pFrame)
            return FALSE;
        m_pMainWnd = pFrame;
        // create and load the frame with its resources
        pFrame->LoadFrame(IDR_MAINFRAME,
            WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
            NULL);
    
        // The one and only window has been initialized, so show and update it
        pFrame->ShowWindow(SW_SHOW);
        pFrame->UpdateWindow();
        return TRUE;
    }
    

    此外,大型机在OnCreate方法中初始化子视图。

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
    
        // create a view to occupy the client area of the frame
        if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
        {
            TRACE0("Failed to create view window\n");
            return -1;
        }
    }
    

    哪里 m_wndView ChildView . 我想我应该初始化 窗体视图 在里面 OnCreate 的方法 儿童视图 ,但我不知道如何做到这一点,也不知道如何“展示”它。因为 窗体视图 没有这些方法。

    另一方面,文档/视图体系结构的初始化如下所示。似乎自动涵盖了我想要实现的目标。

    BOOL MfcApp::InitInstance() 
    {
        // (...)
        CSingleDocTemplate* pDocTemplate;
        pDocTemplate = new CSingleDocTemplate(
            IDR_MAINFRAME,
            RUNTIME_CLASS(CMFCPlaygroundDoc),
            RUNTIME_CLASS(CMainFrame),       
            RUNTIME_CLASS(CMFCPlaygroundView)); // <-- derived from CFormView
        if (!pDocTemplate)
            return FALSE;
        AddDocTemplate(pDocTemplate);
        // (...)
    }
    

    问题是,我看到在第二个生成的项目中,CFormView被提供给SingleDocTemplate构造函数,我可以将控件放在那里。但在第一个生成的项目中,我不知道在哪里可以将CFormView连接到显示的子视图。我不知道如何以及在哪里连接我的新CFormView。

    我发现文档/视图体系结构对于我需要的应用程序来说是压倒性的和不必要的,我想继续它只是为了理解它。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Rafal    7 年前

    既然@RonTLV并没有发布他的链接作为答案,我将解释如何解决我的问题 Link @提供RonTLV。

    简而言之:我在CFormView类和大型机中缺少了DYNCREATE宏( CFrameWnd )需要有一个指向CFormView的指针而不是实例,在大型机的OnCreate方法中,CFormView必须降级(通过宏)。

    您可以在下面找到 CFormView 带有必要宏的类标题:

    class MyFormView : public CFormView
    {
        DECLARE_DYNCREATE(MyFormView)
    
    public:
        enum { IDD = IDD_RANGERCONTROLS  };
    
        MyFormView();// : CFormView(IDD) {};
        virtual ~MyFormView();
    
        DECLARE_MESSAGE_MAP()
    
    public:
    };
    

    在cpp文件中,我添加了 IMPLEMENT_DYNCREATE 宏如下所示:

    IMPLEMENT_DYNCREATE(MyFormView, CFormView)
    
    MyFormView::MyFormView()
        : CFormView(MyFormView::IDD)
    {
    };
    
    MyFormView::~MyFormView()
    {
    }
    
    BEGIN_MESSAGE_MAP(MyFormView, CFormView)
    END_MESSAGE_MAP()
    

    最后在 MainFrame::OnCreate 方法

    CCreateContext ccx;
    ccx.m_pNewViewClass = RUNTIME_CLASS(MyFormView);
    m_pMainView = DYNAMIC_DOWNCAST(MyFormView, this->CreateView(&ccx));
    
    if (NULL == m_pMainView)
    {
        TRACE0("Creation of View failed.\n");
    }
    
    RecalcLayout();
    m_pMainView->ShowWindow(SW_SHOW);
    m_pMainView->OnInitialUpdate();
    SetActiveView(m_pMainView);
    

    哪里 m_pMainView 被宣布为CMainFrame的私人会员:

    MyFormView* m_pMainView;