SDI with multiple views - an old problem revisited
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums
Results 1 to 7 of 7

Thread: SDI with multiple views - an old problem revisited

Hybrid View

  1. #1
    Join Date
    May 2002

    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, ...).

    	CSingleDocTemplate* pDocTemplate1;
    	pDocTemplate1 = new CSingleDocTemplate(
    		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    	if (!pDocTemplate1)
    		return FALSE;
    	CSingleDocTemplate* pDocTemplate2;
    	pDocTemplate2 = new CSingleDocTemplate(
    		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    	if (!pDocTemplate2)
    		return FALSE;
    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:

    Simple to Use, Yet Powerful Graphics Classes by By Yuantu Huang - July 23, 2000

    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:
    BEGIN_MESSAGE_MAP(CVistasApp, CWinApp)
    	// ..
    	ON_COMMAND(ID_VIEW1, &CVistasApp::OnView1)
    	ON_COMMAND(ID_VIEW2, &CVistasApp::OnView2)
    	ON_UPDATE_COMMAND_UI(ID_VIEW1, &CVistasApp::OnUpdateView1)
    	ON_UPDATE_COMMAND_UI(ID_VIEW2, &CVistasApp::OnUpdateView2)
    void CVistasApp::OnView2()
    	POSITION curTemplatePos = GetFirstDocTemplatePosition();
    	while(curTemplatePos != NULL)
    		CDocTemplate* curTemplate = 
    		CString str;
    		curTemplate->GetDocString(str, CDocTemplate::docName);
    		if(str == _T("Vistas"))
    	AfxMessageBox("Can not create the View2 frame window!");
    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'.

    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
    Oh yes, anyone interested in this problem should consult the article:
    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.

    Attached Files Attached Files
    Last edited by Mike Pliam; November 5th, 2010 at 07:15 PM.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004

    Re: SDI with multiple views - an old problem revisited

    Take a look at the ViewEx sample in msdn.

    Another one to look at is the VSwap32 sample:
    Last edited by Arjay; November 5th, 2010 at 07:27 PM.

  3. #3
    Join Date
    May 2002

    Re: SDI with multiple views - an old problem revisited

    Thanks Arjay. Those links have been very enlightening. But they do not solve my problem completely.

    Development Notes for VSWAP32 - a Microsoft Sample of
    SDI With Multiple Views

    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
    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).

    Attached Files Attached Files

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004

    Re: SDI with multiple views - an old problem revisited

    Quote Originally Posted by Mike Pliam View Post
    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).

  5. #5
    Join Date
    Dec 2012

    Re: SDI with multiple views - an old problem revisited


    I have the complete solution to the problems listed in this Thread.
    Interested people may add and contact me on my skype name x_liquid_snake_x

    Liquid Snake

  6. #6
    Join Date
    Nov 2000
    Voronezh, Russia

    Re: SDI with multiple views - an old problem revisited

    Of course you must not create/delete view objects explicitly.
    A solution was immediately found here:
    Attached Files Attached Files
    Last edited by Igor Vartanov; December 26th, 2012 at 04:09 AM.
    Best regards,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Windows Mobile Development Center

Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


HTML5 Development Center