Click here to Skip to main content
Click here to Skip to main content

Using Multiview

By , 10 Jul 2004
 

Introduction

Have you ever want to build an aplication which have more than one view? You can implement it by using a splitter, or multiple views. This article with discuss about using mutiple views, how to use those views, and change between views. Implementation of this, is the html editor, which can change view from design view to html view. These views can have single document or more than one document. In this article, I only use single document.

Using the code

Step 1 Making a new view

Add a new view by inserting a new class with CView / CScrollView / CHtmlView / something else. as the base class. In this tutorial, I will name that class COtherView. Change the constructor and destructor access from protected to public, so that you can call it. Make two CView/CSrollView object, according the base class you created before, named m_pOtherView and m_pOtherView. m_pOtherView is used to store the new view and m_pFirstView to store the first view, so that you can go back to that view.

    CView m_pOtherView;
</CODE>    CView m_pFirstView;

Remember to write the above code and code in step 1 in your App header file. Create a CCreateContext variable to connect the view to the a document, in this case it`s the default document. You can use your own created document if you want, but it`s a bit complex, so i won`t discuss it here. Name the variable context. You will pass this variable as a parameter to create the view. The attribute which store the current document is m_pCurrentDoc.

    CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
    CCreateContext context;
    context.m_pCurrentDoc = pDoc;

Before creating the new view, create a new variable m_ID, which hold the new view ID. Set the m_ID base on the first view ID plus 1. AFX_IDW_PANE_FIRST is the first view ID, adding it by one will make sure there is no ID conflict.

    UINT m_ID = AFX_IDW_PANE_FIRST + 1;
Create the new view after ProcessShellCommand in InitInstance ( your App )
    m_pOtherView->Create(NULL, NULL, WS_CHILD, rect, 
      m_pMainWnd, m_ID, &context);

Step 2 Selecting and viewing the view

First exchange the view ID that we want to show with the previous view ID. You have to do this , so that RecalcLayout do it`s job to the right view, the view that we want to see. Use the SetWindowWord and GetWindowWord to work on the m_hWnd, which is 16-bit.

     UINT temp = ::GetWindowWord(m_pOtherView->m_hWnd, GWL_ID);
    ::SetWindowWord(m_pOtherView->m_hWnd, GWL_ID, 
         ::GetWindowWord(m_pFirstView->m_hWnd, GWL_ID));
    ::SetWindowWord(m_pFirstView->m_hWnd, GWL_ID, temp);

Hide the previous view and show the next view.

    m_pOtherView->ShowWindow(SW_HIDE);
    m_pFirstView->ShowWindow(SW_SHOW); 

Set the aplication active view with the view we`ve created. Call RecalcLayout to put things in their order.

    ((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pFirstView); 
    ((CFrameWnd*)m_pMainWnd)->RecalcLayout();
    m_pFirstView->Invalidate();
Step 3 Using and manipulate the view

To get access to the active document, change the code on COtherView::OnDraw. But first include the document header in your source file view. In COtherView add Member Function with function type CMultiViewDoc* and with the name GetDocument(). Write the code below to the function created.

    CMultiViewDoc* COtherView::GetDocument()
    {
        return (CMultiViewDoc*)m_pDocument;
    }
    void COtherView::OnDraw(CDC* pDC)
    {
        CMultiViewDoc* pDoc = GetDocument();
        pDC->TextOut(400,320,pDoc->m_str); 
                // m_str is a member of CMultiViewDoc
    }

Draw on the view as you draw with the usual view.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Yulianto.
CEO Odihost
Indonesia Indonesia
Member
Learned programming since elementry school with QBASIC. Until now have learned a bit about VB, java, html, php, asp, delphi. He is taking his master degree in finance. Currently working for a great company(desain web), and stock trading. Own various website about option strategy, lose weight, and Invest Money.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalproblem in switching between views.memberT.Ashish19 Feb '09 - 0:18 
I have resized first view using MoveWindow() function as shown in code below.But view resizes at alternate switching. Why is it so? Please fill different colors in each view to properly identify the problem.
 
void CMultiViewApp::OnViewFirstview()
{
// TODO: Add your command handler code here

UINT temp = ::GetWindowWord(m_pOtherView->m_hWnd, GWL_ID);
::SetWindowWord(m_pOtherView->m_hWnd, GWL_ID, ::GetWindowWord(m_pFirstView->m_hWnd, GWL_ID));
::SetWindowWord(m_pFirstView->m_hWnd, GWL_ID, temp);

m_pOtherView->ShowWindow(SW_HIDE);
m_pFirstView->ShowWindow(SW_SHOW);
 
m_pFirstView->MoveWindow(150,150,500,500);//newly added line
 
((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pFirstView);
((CFrameWnd*)m_pMainWnd)->RecalcLayout();
m_pFirstView->Invalidate();
 
}
 
T.ashish

QuestionHow about MDI applicationmemberFransiscus Herry27 Sep '08 - 14:55 
HI,
Whatabout if i want to implement this into MDI application. Cab you give some sample please?
AnswerRe: How about MDI applicationmemberauralius10 Jan '09 - 2:06 
why need to implement this to mdi?
on mdi,you can create many FormView and dispaly them all at the same time
but in sdi, only obe can be displayed... the rest will be hidden...
Smile | :)
 
From Indonesia with love..!!

GeneralNicemember_808625 Mar '07 - 18:53 
Well done friend. Thanks Smile | :)
 
----------------------------
286? WOWW!Blush | :O

GeneralRe: NicememberYulianto.26 Mar '07 - 0:46 
You're welcome..
 

Work hard, Work effectively.
Own business (desain web)
,Stock Pick Guide.

Generalabout CListViewmemberwayitech6 Jun '06 - 4:44 
I used your code to new a CListView,but in the
Listview ,the OnInitialupdate() function is not called.
how can I handle to this.thanks for your project.
GeneralCFormViewmemberalmasl16 Jul '05 - 5:29 
Is there a way to modify that so I can use CFormView views?
GeneralRe: CFormViewmemberYulianto.7 Jul '05 - 15:21 
You can add another view(CFormView). First insert new Dialog Resource. Next create a class with CFormView as the base class and Dialog ID with the Dialog you just create. If you want to modify it using CFormView, you can imitate the CFormView you create.
 

Work hard, Work effectively.
GeneralRe: CFormViewmemberkedypen26 Dec '05 - 4:11 
let 's try it
 
hello
QuestionMultiple Views - Is this correct?membersusso27 Dec '04 - 10:54 
Attached is my version of the View switch that you originally put in your tutorial. Currently I am having some scalar destructor issues in my view. I think they are unrelated, but do you see any problems with this implementation?
 
void CObjPlacerApp::SwitchView()
{
UINT temp;
CView * m_firstView;
CView * m_newView;
 
CObjPlacerDoc * doc = (CObjPlacerDoc*) ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
 
m_firstView = m_currentView;
// BUG FIX TO DO WITH the Windows ID
switch(doc->getPlainMode())
{
case CObjPlacerDoc::TRACK:
m_newView = m_objPlacerView;
break;

case CObjPlacerDoc::COLLISION:
m_newView = m_collisionView;
break;
case CObjPlacerDoc::DIRECTION:
m_newView = m_directionView;
break;
 
case CObjPlacerDoc::TRACKBUILDER:
m_newView = m_trackBuilderView;
break;
 
default:
ASSERT(FALSE);
break;
}
 
if (m_currentView != m_newView)
{
temp = ::GetWindowLong(m_newView->m_hWnd, GWL_ID);
::SetWindowLong(m_newView->m_hWnd, GWL_ID, ::GetWindowLong(m_firstView->m_hWnd, GWL_ID));
::SetWindowLong(m_firstView->m_hWnd, GWL_ID, temp);

m_firstView->ShowWindow(SW_HIDE);
m_newView->ShowWindow(SW_SHOW);

((CFrameWnd*)m_pMainWnd)->SetActiveView(m_newView);
((CFrameWnd*) m_pMainWnd)->RecalcLayout();

m_newView->Invalidate();

m_currentView = m_newView;
}Smile | :)
AnswerRe: Multiple Views - Is this correct?membergoodmast3r5 Jan '05 - 13:39 
It seems OK, where`s the problem?
 

Work hard and a bit of luck is the key to success.
You don`t need to be genius, to be rich.

GeneralON_INIT Eventmembersusso16 Dec '04 - 10:10 
The Oncreate event is being triggered when you add another view. But, the oninit event for that cview is not being triggered. Is there any reason for this?
GeneralRe: ON_INIT Eventmembergoodmast3r17 Dec '04 - 21:16 
Because when you create a view, it didn`t automatically call the event. You have to do it manually.
 

Work hard and a bit of luck is the key to success.
You don`t need to be genius, to be rich.

GeneralScrollingmembersusso11 Dec '04 - 1:18 
I am having 2 problems with the implementation.
 
1 - When I switch to the 2nd view in a pane, the resizing no longer works till I return the original view.
 
2 - IN the second view, I have no scrollbar visible or accessible. If I try to select where the scollbar It fails to find the pointer the HWnd and resource for that cview.
 
My current design is to use a number of views in a Pane. My property page drives the selection of the view. That is currently working. But the lack of scrollbars that work on any view but the original instantiation of my first view I get errors.
 
Andrew
GeneralRe: Scrollingmembergoodmast3r12 Dec '04 - 16:26 
I`ll try to figure it out when I have time.Smile | :)
 

Work hard and a bit of luck is the key to success.
You don`t need to be genius, to be rich.

GeneralRe: Scrollingmembergoodmast3r14 Dec '04 - 15:14 
I don`t quite understand your problem. If there is no scrollbar, you must first create the view with WS_HSCROLL and WS_VSCROLL style:
m_pOtherView->Create(NULL, NULL, WS_CHILD|WS_HSCROLL|WS_VSCROLL, rect, m_pMainWnd, m_ID, &context);
 
Then adds message for WM_VSCROLL and WM_HSCROLL. Hope this helps.
 

 

Work hard and a bit of luck is the key to success.
You don`t need to be genius, to be rich.

GeneralRe: Scrollingmembersusso14 Dec '04 - 18:32 
Problem has been solved. I've been making the problem harder than it should be.
 
I have been using the CSplitterwnd to control the views. When a Hscroll event is generated for a CView, the pscrollbar is populated with the pointer to the csplitterwnd scrollbar pointer. I was using this pointer to control the view. Which was my first mistake. I should not use that scrollbar and should of used the CView's scrollbar. I have since fixed this. I have also stopped using CSplitterwnd since to be honest, I dont need it for anything.
 
I've incorporated your code changes and its a lot more stable.
 
But please refer to my other post regarding a CView suggestion.
GeneralRe: Scrollingmembergoodmast3r17 Dec '04 - 21:13 
What suggestion?
 

Work hard and a bit of luck is the key to success.
You don`t need to be genius, to be rich.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 11 Jul 2004
Article Copyright 2004 by Yulianto.
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid