?
Solved

Creating Multiple Views of different types in SDI

Posted on 2000-02-24
10
Medium Priority
?
504 Views
Last Modified: 2013-11-20
I have an SDI application. I am trying to have multiple views of different types (Classes) for the same document. I do not want to use CSplitterWnd since it forces me to have the multiple views within one main window. I would like to have the multiple views in different windows, as if they were child windows of the main windows so I would be able to make them overlap min.mximize, etc.
Please advise.
Thank you.
0
Comment
Question by:Zainal062797
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 
LVL 10

Accepted Solution

by:
RONSLOW earned 600 total points
ID: 2556214
Sounds like you want a hybrid SDI/MDI app.

There are examples of these at www.godeguru.com

I'll give you the addresses shortly
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2556254
go to

http://www.codeguru.com/doc_view/index.shtml

there are a number of articles there under the "View management" heading, including:

MultiSingle (MSDI) Document interface - Lanz Jean-Claude (1998/08/06)
MultiSingle (MSDI) Document interface with DAO doc - Lanz Jean-Claude (1998/08/06)
Multiple Views Using SDI - Richard Stringer (1998/12/02)
SDI Interface with Multi-Views and Multi-Splitters - Jean-Claude Lanz (1999/02/14)
Switching to other view in a doc-view application - Jorge Lodos (1999/03/02)
Multiple frame windows in SDI application - Ole Lennert (1999/04/03)

Good hunting !!

0
 
LVL 3

Expert Comment

by:V_Bapat
ID: 2557839
Do you want functionality like Outlook Express where you double click on the mail message and a new window open with the message?

If yes, then read on.

1. You have to create and maintain a pointer list of the windows. You should add FrameWnd pointer to the list when ever you open a new window and remove it is closed.
2. To create a new window, call CreateNewFrame(...).

These are two basic functionality you have to implement. Rest is not much. Feel free to ask if you have more queries.

All the best.

Vicky
0
Get proactive database performance tuning online

At Percona’s web store you can order full Percona Database Performance Audit in minutes. Find out the health of your database, and how to improve it. Pay online with a credit card. Improve your database performance now!

 
LVL 3

Expert Comment

by:V_Bapat
ID: 2557872
Take a look at this article from Microsoft Knowledge Base.
http://support.microsoft.com/support/kb/articles/Q100/9/93.ASP

To get this article by mail, send a blank mail to mshelp@microsoft.com with Q100993 in the subject line.

Vicky
0
 

Author Comment

by:Zainal062797
ID: 2558911
Thank you for your advice V_Bapat. However, I am using SDI, and when I try to create the second view, the program crashes. It seems like your solution works only for MDI. Please let me know if there is a way around this.

Thank you.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2560335
Did you check out the examples at codeguru? They all give SDI with multiple views.
0
 
LVL 4

Expert Comment

by:pagladasu
ID: 2562144
You can have multiple views in a SDI application. Create the other
views separately by inserting a new class. Make sure that this class is
derived from the appropriate view class. Assume that this view is called
CMyNewView.

Add the following protected instance variable and member function
in the CMainFrame class.

protected:
enum show {MYVIEW=1, DEFVIEW=2};
void SwitchView(show nView);

Add the following menu option : MyView  (mapped to OnMyView) and
DefaultView (mapped to OnDefView)

Write the following code for OnMyView
void CMainFrame::OnMyView()
{
// TODO: Add your command handler code here
SwitchView(MYVIEW);
}

Similarly this code goes for OnDefView
void CMainFrame::OnDefView()
{
// TODO: Add your command handler code here
SwitchView(DEFVIEW);
}

Here is the code for SwitchView
void CMainFrame::SwitchView(show nView){
CView * poldview=GetActiveView();
CView * pnewview=(CView *)GetDlgItem(nView);
if(pnewview==NULL){
switch(nView){
case MYVIEW:
pnewview=(CView *)new CMyNewView;
break;
case DEFVIEW:
pnewview=(CView *)new CMyAppView;
break;
}
CCreateContext context;
context.m_pCurrentDoc=poldview->GetDocument();
pnewview->Create(NULL,NULL,0L,CFrameWnd::rectDefault,this,nView,&context);
pnewview->OnInitialUpdate();
}
SetActiveView(pnewview);
pnewview->ShowWindow(SW_SHOW);
poldview->ShowWindow(SW_HIDE);
poldview->SetDlgCtrlID(poldview->GetRuntimeClass()==
RUNTIME_CLASS(CMyAppView)?DEFVIEW:MYVIEW);
pnewview->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
RecalcLayout();
}

Also add these handlers:
void CMainFrame::OnUpdateViewDefView(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!GetActiveView()->IsKindOf(RUNTIME_CLASS(CMyAppView)));
}

void CMainFrame::OnUpdateViewMyNewView(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!GetActiveView()->IsKindOf(RUNTIME_CLASS(CMyNewView)));
}

Hope this helps
pagladasu

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2562348
The above has one view window and simply changes the type of view displayed in that window.  This is not what is wanted (from what I understand of the question).

I have a more generalised method for this in my apps ... you only need to change (or add) a line for each view type to have as many views as you want.

My example works within a splitter, which is not in the specs of this app, but thought someone may find it useful.  It allows you to change the type of view in each splitter pane.

One day I'll add a lookup table from ID to runtime class to make it truly extensible and stick it in my utility library .. but here it is (a bit different from the above - mainly because of splitter support):

void CMainFrame::OnViewSelect(UINT id) {
  // work out the type of view required
  // from the ID given
  CRuntimeClass* pViewClass = NULL;
  switch (id) {
  // add to and/or change these lines
  // for additional classes
  case ID_VIEW_1: pViewClass = RUNTIME_CLASS(CView1); break;
  case ID_VIEW_2: pViewClass = RUNTIME_CLASS(CView2); 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;
  // if no old view, then cannot change
  CView* pOldView = GetActiveView();
  if (! pOldView) return;
  // get pointer to splitter (parent)
  // must be
  CSplitterWnd* pSplitter = static_cast<CSplitterWnd*>(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
    {
      BOOL bAutoDelete = pDoc->m_bAutoDelete;
      pDoc->m_bAutoDelete=false;    
      pOldView->DestroyWindow();
      pDoc->m_bAutoDelete=bAutoDelete;
    }
    // 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<CView*>(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();
    }
  }
}
0
 
LVL 3

Expert Comment

by:V_Bapat
ID: 2564229
Zainal:
>> It seems like your solution works only for MDI.

It is for SDI. What I missed out in my last post is that you have to create a DocTemplate.
I am using this method in my Project. This is a snippet from my CWinApp derived class.

      // Register the application's document templates.  Document templates
      //  serve as the connection between documents, frame windows and views.

// DocTemplate created by AppWizard

      CSingleDocTemplate* pDocTemplate;
      pDocTemplate = new CSingleDocTemplate(
            IDR_MAINFRAME,
            RUNTIME_CLASS(CNetpowerDoc),
            RUNTIME_CLASS(CNetpowerFrameWnd),       // main SDI frame window
            RUNTIME_CLASS(CNetpowerView));
      AddDocTemplate(pDocTemplate);

      {
            // BLOCK: doc template registration
            // Register the document template.  Document templates serve
            // as the connection between documents, frame windows and views.
            // Attach this form to another document or frame window by changing
            // the document or frame class in the constructor below.
            m_pPolicyEditorDocTemplate = new CSingleDocTemplate(
                  IDR_CHILDFRAME,
                  RUNTIME_CLASS(CPolicyEditorDoc),              // Document class
                  RUNTIME_CLASS(CPolicyEditorFrm),          // Child frame class
                  RUNTIME_CLASS(CPolicyEditorView));       // View class
            AddDocTemplate(m_pPolicyEditorDocTemplate);
      }

You have to create document, view and frame window classes derived from CDocument, CView(or what your requirement is) and CFrameWnd respectively.

It is a bit complicated and to understand it properly, you have to understand what and how CDocManager(undocumented class) class works.


Vicky
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2566985
Did you check out the examples at codeguru?

They all give SDI with multiple views.

Please check them out and let me know what you think.
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month10 days, 4 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question