More on multi-view, single-doc
Paul E. Rosen -- prosen@fte.com
Friday, October 04, 1996
Environment: Win 95, VC 4.0
The recent discussion on multiple views with one document has been very
interesting to me because I am trying to architect a similar program. I too
want a single document, but multiple views. The views work like this:
The user should be able to open as many windows (within reason) as he wants,
and each window should be any of my views (there are 9 different ones). Also,
there will be buttons on each window to allow the user to change the view of
that window on the fly. Also, the windows will be splitter windows so that
each can have more than one view in it.
I looked at the VSWAP sample, but that appears to allocate all the views at
window creation whether they are used or not. Since I have 9 different views
and multiple windows, would this eat up resources unnecessarily? In other
words, it is reasonable to assume the user may want 6 windows open at a time
in this application. That means I would create 6x9=54 views.
So far I have the following plan:
* I will use MDI, but limit the number of open documents to one using
m_pDocTemplate->GetFirstDocPosition(), as suggested recently by John Bundgaard
* Change the "New Window" menu item to nine items: "New View1", "New View2",
etc.
* put a toolbar on each view (and each page of the splitter) with 9 buttons to
switch views.
This is the question:
Should I create one view class, and put a variable m_whichView in it that is
used in OnDraw to affect the look, or create 9 classes and somehow swap them?
How would I swap them?
I'm leaning towards 9 view classes. If the view changes, I would allocate the
new view class with context from the old view, and swap the view like in VSWAP
, then delete the old view class.
Does any of this sound like a reasonable approach?
Thanks in advance,
Paul Rosen, Frontline Test Equipment, Inc.
Internet: prosen@fte.com, http://www.fte.com, ftp.fte.com
Voice: 804-984-4500, Fax: 804-984-4505, BBS: 804-984-4503
Real Mail: PO Box 7507, Charlottesville, VA 22906-7507, USA
Location: 2114 Angus Road, Suite 228, Charlottesville, VA 22901
Dave_Rabbers@Quinton-Eng.CCMAIL.CompuServe.COM
Monday, October 07, 1996
[Mini-digest: 2 responses]
I suggest when you create each new window, create just the single view
initially requested, but allow for a total of nine views to be created
per window. Then, within a window, if a not-yet-created view is
requested, create it but keep the old one around. That way if the
user reselects a former view, it gets drawn very rapidly, without the
additional overhead of view creation.
In summary, each frame window should be constructed with nine
initially NULL view pointers. During frame creation, construct and
save the pointer to the initially requested view. If a new view is
requested and its pointer is NULL, construct it and swap it into the
frame. Otherwise, just swap it in.
I think you will find this to give snappy, user pleasing performance.
______________________________ Reply Separator _________________________________
Subject: More on multi-view, single-doc
Author: INTERNET:prosen@fte.com at CSERVE
Date: 10/6/96 4:31 PM
Sender: owner-mfc-l@majordomo.netcom.com
Received: from majordomo.netcom.com (listless.netcom.com [206.217.29.105]) by
hil-img-5.compuserve.com (8.6.10/5.950515)
id QAA04517; Sun, 6 Oct 1996 16:29:26 -0400
Received: by majordomo.netcom.com (8.7.5/8.7.3/(NETCOM MLS v1.01)) id
MAA24808; Sun, 6 Oct 1996 12:47:54 -0700 (PDT)
From: prosen@fte.com (Paul E. Rosen)
Date: Fri, 4 Oct 1996 11:33:00
Subject: More on multi-view, single-doc
X-Mailer: Internet Series for Microsoft Mail ( V2.0.1G )
Mime-Version: 1.0
To: "'inet:mfc-l@netcom.com'"
Message-ID: <19961004154056.AAA24724@Dialin1.cstone.net>
Sender: owner-mfc-l@majordomo.netcom.com
Errors-To: owner-mfc-l@majordomo.netcom.com
Precedence: bulk
Reply-To: mfc-l@netcom.com
Environment: Win 95, VC 4.0
The recent discussion on multiple views with one document has been very
interesting to me because I am trying to architect a similar program. I too
want a single document, but multiple views. The views work like this:
The user should be able to open as many windows (within reason) as he wants,
and each window should be any of my views (there are 9 different ones). Also,
there will be buttons on each window to allow the user to change the view of
that window on the fly. Also, the windows will be splitter windows so that
each can have more than one view in it.
I looked at the VSWAP sample, but that appears to allocate all the views at
window creation whether they are used or not. Since I have 9 different views
and multiple windows, would this eat up resources unnecessarily? In other
words, it is reasonable to assume the user may want 6 windows open at a time
in this application. That means I would create 6x9=54 views.
So far I have the following plan:
* I will use MDI, but limit the number of open documents to one using
m_pDocTemplate->GetFirstDocPosition(), as suggested recently by John Bundgaard
* Change the "New Window" menu item to nine items: "New View1", "New View2",
etc.
* put a toolbar on each view (and each page of the splitter) with 9 buttons to
switch views.
This is the question:
Should I create one view class, and put a variable m_whichView in it that is
used in OnDraw to affect the look, or create 9 classes and somehow swap them?
How would I swap them?
I'm leaning towards 9 view classes. If the view changes, I would allocate the
new view class with context from the old view, and swap the view like in VSWAP
, then delete the old view class.
Does any of this sound like a reasonable approach?
Thanks in advance,
Paul Rosen, Frontline Test Equipment, Inc.
Internet: prosen@fte.com, http://www.fte.com, ftp.fte.com
Voice: 804-984-4500, Fax: 804-984-4505, BBS: 804-984-4503
Real Mail: PO Box 7507, Charlottesville, VA 22906-7507, USA
Location: 2114 Angus Road, Suite 228, Charlottesville, VA 22901
-----From: Roger Onslow/Newcastle/Computer Systems Australia/AU
>This is the question:
>
>Should I create one view class, and put a variable m_whichView in it that is
>used in OnDraw to affect the look, or create 9 classes and somehow swap them?
>How would I swap them?
You can dynamically create the views -- they do need to exist beforehand to
swap view class in a pane.
Here is (hacked) code from my app. View classes are CView0 and CView1 both
derived from CView. There are toolbar/menu ID's for selecting these called
ID_VIEW_0 and ID_VIEW1 (these are sequenial in id number so I can use
ON_COMMAND_RANGE). This is very easily be extended to more views (basically
add extra case statements to switch)
Hope this helps you.
ON_COMMAND_RANGE(ID_VIEW_0, ID_VIEW_1, OnViewPlanSelect)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_0, ID_VIEW_1, OnUpdateViewSelect)
void CMainFrame::OnViewSwapSelect(UINT id) {
CRuntimeClass* pViewClass = NULL;
switch (id) {
case ID_VIEW_0: pViewClass = RUNTIME_CLASS(CView0); break;
case ID_VIEW_1: pViewClass = RUNTIME_CLASS(CView1); break;
}
// don't know what class to create
if (! pViewClass) return;
// Get pointer to CDocument object so that it can be used in the creation
// process of the new view
CDocument* pDoc = GetActiveDocument();
if (! pDoc) return;
CView* pOldView = GetActiveView();
if (! pOldView) return;
// get pointer to splitter (parent)
CSplitterWnd* pSplitter = static_cast(pOldView->GetParent());
if (! pSplitter || ! pSplitter->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) return;
// find which pane
int row,col;
if (pSplitter->IsChildPane(pOldView,&row,&col)) {
int w,h,minw,minh;
pSplitter->GetColumnInfo(col,w,minw);
pSplitter->GetRowInfo(row,h,minh);
// set flag so that document will not be deleted when view is destroyed
pDoc->m_bAutoDelete=FALSE;
pOldView->DestroyWindow();
pDoc->m_bAutoDelete=TRUE;
// Create new view
CCreateContext context;
context.m_pNewViewClass=pViewClass;
context.m_pCurrentDoc=pDoc;
context.m_pNewDocTemplate=NULL;
context.m_pLastView=NULL;
context.m_pCurrentFrame=NULL;
if (! pSplitter->CreateView(row,col,pViewClass,CSize(w,h),&context)) {
::AfxMessageBox("Could not create view");
} else {
CView* pNewView = static_cast(pSplitter->GetPane(row,col));
SetActiveView(pNewView);
pNewView->SendMessage(WM_INITIALUPDATE,0,0);
pSplitter->SetColumnInfo(col,w,minw);
pSplitter->SetRowInfo(row,h,minh);
pSplitter->RecalcLayout();
pNewView->UpdateWindow();
}
}
}
void CMainFrame::OnUpdateViewSelect(CCmdUI* pCmdUI) {
CView* pView = GetActiveView();
if (! pView) {
pCmdUI->Enable(FALSE);
return;
}
CRuntimeClass* pViewClass = pView->GetRuntimeClass();
switch (pCmdUI->m_nID) {
case ID_VIEW_0: pCmdUI->SetRadio(pViewClass == RUNTIME_CLASS(CView2)); break;
case ID_VIEW_1: pCmdUI->SetRadio(pViewClass == RUNTIME_CLASS(CView1)); break;
}
}
WnDBSoft@aol.com
Thursday, October 10, 1996
What you want to do is have the user be able to create extra views from a
previous view.
First make multiple doc templates for each view, i.e.
// m_pDocTempl1, m_pDocTempl2, and m_pDocTempl3 are member variables of
// the application class. The variables are pointers of type
CMultiDocTemplate*
BOOL CMyApp::InitInstance( )
{
//...
//...
//...
m_pDocTempl1 = new CMultiDocTemplate(
IDR_DOCTYPE1,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CMyView1));
AddDocTemplate(m_pDocTempl1);
m_pDocTempl2 = new CMultiDocTemplate(
IDR_DOCTYPE2,
RUNTIME_CLASS(CMyDoc), // same doc class as prev template
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CMyView2));
AddDocTemplate(m_pDocTempl2);
m_pDocTempl3 = new CMultiDocTemplate(
IDR_DOCTYPE3,
RUNTIME_CLASS(CMyDoc), // still, the same doc as prev. templates
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CMyView3));
AddDocTemplate(m_pDocTempl3);
//... rest of init code ...
return TRUE;
}
// below, N on the end of a class name or variable represents any number
// i.e. CMyViewN could be = CMyView1, or CMyView2, etc.
// i.e. m_pDocTemplN could be = m_pDocTempl1, or m_pDocTempl2, etc.
// below A on the end of a class or variable name is any number other than N
// in MyViewN, handler for a function New ViewA (NOTE: to create a new copy
of
// this view for the same doc, use the default Window->New command handler
// ID_WINDOW_NEW
void CMyViewN::OnWindowNewViewA( )
{
// get a pointer to the app class
CMyApp* pApp = (CMyApp*)AfxGetApp( );
CMDIChildWnd* pFrame =
(CMDIChildWnd*)pApp->m_pDocTemplA->CreateNewFrame(GetDocument( ), NULL);
if (pFrame == NULL) return; // an error occurred
m_pDocTemplA->InitialUpdateFrame(pFrame, GetDocument( ), TRUE);
// to access CMyViewA,
CMyViewA* pMyViewA = (CMyViewA*)pFrame->GetActiveView( );
pMyViewA->Func( );
return;
}
Good Luck!
Sincerely,
Brian Hart
WnDBSoft Software International
| Вернуться в корень Архива
|