15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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


     
         





| Вернуться в корень Архива |