显示同一文档的多个同时视图
如何说服 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
子类表示某个描述的存档.
我想要一个 UI,其中该存档中所有条目的名称都显示在左侧窗格的 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 意思是Single Document Interface",它限制你一次只能有一个文档,但不限制查看次数您可以打开此文档.
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.
相关文章