November 5th, 2010, 05:26 PM
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, ...).
5 - In the String Table, copy the IDR_MAINFRAME entry and paste it again into the String Table to
pDocTemplate1 = new CSingleDocTemplate(
RUNTIME_CLASS(CMainFrame), // main SDI frame window
pDocTemplate2 = new CSingleDocTemplate(
RUNTIME_CLASS(CMainFrame), // main SDI frame window
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:
Simple to Use, Yet Powerful Graphics Classes by By Yuantu Huang - July 23, 2000 http://www.codeguru.com/article.php/c2231
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.
POSITION curTemplatePos = GetFirstDocTemplatePosition();
while(curTemplatePos != NULL)
CDocTemplate* curTemplate =
if(str == _T("Vistas"))
AfxMessageBox("Can not create the View2 frame window!");
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:
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).
Cannot create the ViewN frame window!
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'.
Oh yes, anyone interested in this problem should consult the article:
IDR_TYPE_STDVIEW | Vistas\n\nVistas\nVistas Files (*.txt)\n.txt\nVistas.Document\nVistas.Document
IDR_TYPE_RICHVIEW | Vistas\n\nVistas\nVistas Files (*.txt)\n.txt\nVistas.Document\nVistas.Document
Multiple Views Using SDI by Richard Stringer, December 1998
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.
Click Here to Expand Forum to Full Width
This is a CodeGuru survey question.