SDI with multiple views - an old problem revisited
Some time ago I had developed an SDI application that allowed switching to different views, one a CView and the other a CRichEditView. I did this with the help of an old text by Brain and Lovette, 'Developing Professional Applications...Prentice Hall, 1996 ISBN 0-13-616343-2 (see pp 398, Handling Multiple Views on One Document. Regretably, I have lost the code for this application and no longer can remember the tricks involved in accomplishing this. I have gotten so far as to get an application that does most of what I want, but cannot get the views to switch during runtime.
One can proceed as follows:
1 - Use the Wizard to create an SDI app
2 - Add Class (s) CView1, CView2, ... using desired base classes
3 - Include the header files for each of the new views to the application _App.cpp file
4 - In the _App::InitInstance() function, redesign the document templates so that
they look something like this, noting that each view has it's own unique CSingleDocTemplate
class pointer (pDocTemplate1, pDocTemplate2, ...), unique menu ID (IDR_TYPE_STDVIEW,
IDR_TYPE_RICHVIEW, ...), while in this case the views are sharing the same document class
(CVistasDoc), and Main Frame class (CMainFrame), each view template has it's unique
RUNTIME_CLASS designation (CView1, CView2, ...).
Code:
CSingleDocTemplate* pDocTemplate1;
pDocTemplate1 = new CSingleDocTemplate(
IDR_TYPE_STDVIEW,
RUNTIME_CLASS(CVistasDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CView1));
if (!pDocTemplate1)
return FALSE;
AddDocTemplate(pDocTemplate1);
CSingleDocTemplate* pDocTemplate2;
pDocTemplate2 = new CSingleDocTemplate(
IDR_TYPE_RICHVIEW,
RUNTIME_CLASS(CVistasDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CView2));
if (!pDocTemplate2)
return FALSE;
AddDocTemplate(pDocTemplate2);
5 - In the String Table, copy the IDR_MAINFRAME entry and paste it again into the String Table to
produce IDR_MAINFRAME1, IDR_MAINFRAME2, ..., then rename these new entries according to what
you named the unique doc template IDs (IDR_TYPE_STDVIEW, IDR_TYPE_RICHVIEW, ...)
6 - In the Menu resources, copy IDR_MAINFRAME and paste it again into the Menus to produce
IDR_MAINFRAME1, IDR_MAINFRAME2, ..., then rename these menus to correspond to the new
doc templates (IDR_TYPE_STDVIEW, IDR_TYPE_RICHVIEW, ...) Note that these menus do not have
to be identical and can be edited at a later time as desired.
7 - To each of the new view menus, add items to select the other views (you could omit the item
for it's own view). Then add an event handler for each of the menu view items to the _App,
as well as an update command handler.
8 - You may delete permanently the original IDR_MAINFRAME menu and String Table entries and
the associated original _View.h and _View.cpp files without causing any problems.
This works quite nicely. Now the trick is to be able to switch views during runtime. Some clue might be had by exmining the beautiful interface presented in an article by Yuantu Huang:
Using this approach (bearing in mind that Huang's interface is MDI and not SDI), I tried using this on my SDI app Vistas with two views cleverly named View1 and View2, a CView derived view and a CRichEditView derived view respectively. Each view has the other view as a choice in it's menu. The menu handlers are handled in the Vistas.cpp (the App file) which looks like this:
which shows the routine that is supposed to bring up View2 from the menu selection in View1.
It all compiles and runs but always with the little dialog box giving you a choice of selecting one or the other view. Once you select a view, the menu selection of the other view fails with the warning:
Cannot create the ViewN frame window!
Searching Codeguru for 'SDI Mulitiple Views' elicits 231 hits, most of which seem not to understand the question at hand and tend to be quite critical of the questioner. It is said elsewhere that there is an old Microsoft example called 'CheckBook'. Try Googling that. Nor can I find it in the current batch of MSDN samples (though it could be hidden in there somewhere).
Since I beleive that I have solved a portion of the problem, what remains is
1 - how to get rid of the initial choice dialog
2 - how to call the various views from menu selections
I should mention that my String Table entries for the two views are identical (unlike those of Huang). I am not sure whether or not that is the problem, but the template doc strings in my app are the same, namely 'Vistas'.
I and others cannot get Stringer's code to work, but the discussion is interesting and I particularly like the statement Stringer makes which I have included to counter Victor's comment about 'reinventing the wheel when MDI does just that' ---
There are many advantages to using a CView derived class over a dialog based application. Many times however there is more information than screen space or the program just needs logical seperation of elements. MDI ( Multiple Document Interface) is the standard method of achiving this but many designers do not care for it. It tends to get messy quickly. Most of the time what is needed is a generalized easy way to have a SDI ( Single Document Interface) framework and the ability to switch the active view when needed. This article describes such a method.
I have appended my sample app in the hope that someone will find it interesting and useful enough to post a solution to the problem.
Last edited by Mike Pliam; November 5th, 2010 at 06:15 PM.
VSWAP32 demonstrates methods of switching between multiple views on a single document in a single-document interface (SDI) application. VSWAP32 displays two form views and a normal view that displays the list of data collected in the two form views.
Your ViewEx sample from MSDN is a MDI example and I have been trying to avoid using the MDI framework.
Although the following has had some bad review and uses a different approach completely, the following sample uses both CFormView and CView with a single CDocument.
Multiple Views Using SDI By Richard_Stringer December 2, 1998 http://www.codeguru.com/cpp/w-d/doc_...icle.php/c3341
uses only CFormView views with a single document.
I would like to create a dual interface that allows the user to quickly switch back and forth from a grid view (modified CView) to the CRichEditView
that facilitates data input and editing. The central problem seems to be that these two views require different document configurations. When we get into multiple views using multiple documents, things get quite a bit more complicated. -- how are the view and document connected. CView document is derived from CDocument. CRichEditView document is derived from CRichEditDoc. The latter requires a document control class linkage derived from CRichEditCntrItem.
Using Stringer's approach, I have built a simple SDI interface that allows switching between a CView and CRichEditView, each with their own document classes (derived from CDocument and CRichEditDoc respectively). However, I have not figured out how to switch the documents with their respective views.
I have attached a sample of my approach demonstrating the problem. You will see that the program compiles and runs OK in Release config, but will violate an assertion related to the CRichEditDoc class when attempting to switch from the CRichEditView back to the CView. (You can choose to 'Ignore' this assertion violation without adverse consequences).
The key to the problem is somewhere in the CMainFrame::SwitchToView(int nView). Any suggestions as to how to fix this greatly appreciated.
Note that View1 is CView derived and uses CDoc (CDocument derived) whereas View2 is CRichEditView derived and uses CDoc2 (CRichEditDoc derived).
Re: SDI with multiple views - an old problem revisited
Originally Posted by Mike Pliam
Note that View1 is CView derived and uses CDoc (CDocument derived) whereas View2 is CRichEditView derived and uses CDoc2 (CRichEditDoc derived).
SDI implies the same document. What you have is MDI. You might only have one doc open at a time, but it's still multidoc because you have a CDocument and a CRichEditDoc. Therefore, search for MDI samples that allow you to switch between docs (and their associated views).
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.