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

MFC向导生成了3个文件:

  • App.cpp(源自CWinApp)
  • MainFrame.cpp(源自CFrameWnd)
  • ChildView.cpp(源自CWnd)

  • 现在,我生成了从CFormView派生的自定义类,其中IDD_MYVIEW是资源GUI的生成ID。
    class MyFormView: public CFormView
    {
    public:
        enum { IDD = IDD_MYVIEW  };
    
        MyFormView(): CFormView(IDD) {};
        virtual ~MyFormView() {};
    }
    

    如何在ChildView中显示此MyFormView?

    当我尝试再次生成项目并在MFC向导中选中“文档/ View 架构”复选框时,将“ View ”的基类更改为CFormView。我意识到App初始化不同于最初生成的初始化。

    当前,第一个应用程序初始化如下:
    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;
    }
    

    此外,MainFrame在OnCreate方法中初始化ChildView。
    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_wndViewChildView。我认为我应该在CFormViewOnCreate方法中初始化ChildView,但是我不知道该怎么做,也不知道如何“显示”它。因为CFormView没有这些方法。

    另一方面,使用Doc / View体系结构进行初始化看起来像这样。并且似乎自动涵盖了我想要实现的目标。
    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连接到显示的ChildView。我不知道如何以及在何处可以连接新的CFormView。

    我发现Doc / View体系结构不堪重负,对于我需要的应用程序来说是不必要的,并且仅出于理解目的而着手进行。

    最佳答案

    由于@RonTLV并未将他的链接发布为答案,因此我将解释如何使用提供的Link @RonTLV解决我的问题。

    简而言之:我缺少CFormView类的DYNCREATE宏,并且在MainFrame(CFrameWnd)中需要一个指针而不是CFormView的实例,该指针在MainFrame的OnCreate方法中必须向下转换(通过宏)。

    在下面,您可以找到带有必要宏的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的私有(private)成员:
    MyFormView* m_pMainView;
    

    10-06 02:34