问题描述
如何说服MFC Doc/View体系结构,让我同时显示同一文档的两个不同视图?
How do I persuade the MFC Doc/View architecture to let me simultaneously display two different views of the same document?
例如,假设我的CDocument
子类表示一些描述的存档.
我想要一个用户界面,其中该归档文件中所有条目的名称都显示在左侧窗格的CListView
子类中,而当前所选条目的详细信息显示在窗口中的CEditView
子类中右窗格.
For example, say my CDocument
sub-class represents an archive of some description.
I want a UI where the names of all the entries in that archive are presented in a CListView
sub-class in the left hand pane, while the details of the currently selected entry are displayed in a CEditView
sub-class in the right hand pane.
CSingleDocTemplate
似乎仅允许连接一个文档,一帧和一个视图.我仍然想要一个SDI应用程序,但是我想要一个文档和两个不同的视图-这不是一个好的Doc/View体系结构的全部重点吗?
The CSingleDocTemplate
only seems to allow for connecting up one document, one frame and one view. I still want an SDI application, but I want one document and two different views - isn't that the whole point of a good Doc/View architecture?
推荐答案
SDI的意思是单个文档接口",它一次只能将一个文档限制为一个文档,而视图数量则不受限制您可以打开该文档.
SDI means "Single Document Interface", it restricts you to only one single document at a time but not in the number of views you can open for this document.
在SDI应用程序中打开多个视图的最常见的方法是 Splitter Windows .
The probably most common approach to open multiple views in an SDI application are Splitter Windows.
您在CSingleDocTemplate
中添加了一个视图(与哪个视图无关)
You add one view to the CSingleDocTemplate
(it doesn't matter which one)
pDocTemplate = new CSingleDocTemplate(
IDR_MYRESOURCEID,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMyFrameWnd),
RUNTIME_CLASS(CMyListView));
您的框架窗口获取CSplitterWnd m_wndSplitter
的实例,并且您重载了OnCreateClient
虚函数:
Your frame window gets an instance of a CSplitterWnd m_wndSplitter
and you overload the OnCreateClient
virtual function:
BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
VERIFY(m_wndSplitter.CreateStatic(this,1,2)); // one row / two columns
VERIFY(m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyListView),
CSize(300,300),pContext));
VERIFY(m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMyEditView),
CSize(300,300),pContext));
return TRUE;
}
此示例创建一个包含一行和两列的拆分器窗口.拆分器的左侧是CMyListView
类型的视图,右侧是CMyEditView
类型的视图.
This example creates a splitter window with one row and two columns. On the left side in the splitter is a view of type CMyListView
and on the right side is a view of type CMyEditView
.
您甚至可以将多个拆分器窗口彼此嵌套以在框架窗口中创建任意复杂的视图集合.
You can even nest multiple splitter windows one in each other to create arbitrary complex view collections in the frame window.
这是一个小教程,展示了如何在SDI应用程序中使用拆分器窗口:
Here is a small tutorial which shows how to work with splitter windows in a SDI application:
http://www.codeproject.com/KB/splitter/splitterwindowtutorial.aspx
修改
使用文档对添加到拆分器中的视图进行接线会在内部进行MFC:传递到OnCreateClient
的CCreateContext* pContext
包含对当前文档的引用m_pCurrentDoc
(Framewindow知道此文档). MFC在CView::OnCreate
(ViewCore.cpp)中使用此控件将视图添加到文档:m_pCurrentDoc->AddView(this)
并在视图中设置文档指针m_pDocument
.
Wiring up of the views you add to the splitter with the document does MFC internally: CCreateContext* pContext
which is passed into OnCreateClient
contains a reference m_pCurrentDoc
to the current document (the Framewindow knows about this document). MFC uses this in CView::OnCreate
(ViewCore.cpp) to add the View to the Document: m_pCurrentDoc->AddView(this)
and to set the document pointer m_pDocument
in the View.
因此,随后对文档UpdateAllViews
的调用将同时处理这两种视图.
Therefore subsequent calls of UpdateAllViews
of your document will take care of both views.
这篇关于同时显示同一文档的多个视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!