如何在 MFC 的 CWnd 中显示 CFormView?
Posted
技术标签:
【中文标题】如何在 MFC 的 CWnd 中显示 CFormView?【英文标题】:How to show CFormView in CWnd in MFC? 【发布时间】:2018-01-31 11:17:55 【问题描述】:我有一个不支持文档/视图的 SDI MFC 应用程序。我想在 ChildView 的资源编辑器中嵌入带有控件的 CFormView。我该怎么做?
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 的基类更改为 CFormView。我意识到 App 初始化与最初生成的不同。
目前第一个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_wndView
是ChildView
。我认为我应该在ChildView
的OnCreate
方法中初始化CFormView
,但我不知道该怎么做,也不知道如何“显示”它。因为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 架构对于我需要的应用程序来说是压倒性的和不必要的,我想继续使用它只是为了理解它。
【问题讨论】:
在设计项目时,您可以选择 SDI 或 MDI 项目。单文档或多文档界面。您的文档与视图相关联。在项目设计时,您决定要使用哪种类型的视图。因此,该项目将为您提供一个骨架表单,供您添加控件。我不太明白你的问题是什么? 为什么要创建没有文档/视图的 SDI?你让自己很难受。如果你想要的只是一个对话框,那么为什么不创建一个基于对话框的项目呢。 Can a MFC dialog resource be attached to a CChildView?的可能重复 在这里试试:codeproject.com/Articles/5445/… @RonTLV:您可以发布链接作为答案吗?链接中的内容很重要,帮助我理解了我的问题。 【参考方案1】:由于@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 的私有成员:
MyFormView* m_pMainView;
【讨论】:
以上是关于如何在 MFC 的 CWnd 中显示 CFormView?的主要内容,如果未能解决你的问题,请参考以下文章
创建单独的 MFC GUI 线程,不能移动/调整大小/最大化 CWnd