Solved

How to switch to MyView2 by clicking on Button in MyView1?

Posted on 2001-09-13
13
364 Views
Last Modified: 2013-11-20
Hello, I have 2 Views.  I have been trying, unsuccessfully, to switch to
MyView2 by clicking on a button in MyView1.


void MyView1::OnButton7()
{
CChildFrame  pChildFrame;
 pChildFrame.GuiRv(RUNTIME_CLASS(MyView2));
}


This is the Switch View code:

BOOL CChildFrame::ReplaceView(CRuntimeClass * pViewClass)
{
  CCreateContext context;
  CView * pCurrentView;
 if ((pCurrentView=GetActiveView())==NULL)
   return FALSE;
if ((pCurrentView->IsKindOf(pViewClass))==TRUE)
     return TRUE;
   CDocument * pDoc= pCurrentView->GetDocument();
    BOOL bAutoDelete=pDoc->m_bAutoDelete;
   pDoc->m_bAutoDelete=FALSE;
   pCurrentView->DestroyWindow();
    pDoc->m_bAutoDelete=bAutoDelete;
   context.m_pNewViewClass=pViewClass;
   context.m_pCurrentDoc=pDoc;
   context.m_pNewDocTemplate=NULL;
   context.m_pLastView=NULL;
   context.m_pCurrentFrame=this;
   CView * pNewView = (CView *) pViewClass->CreateObject();
   if (pNewView == NULL)
 {
     TRACE1("Warning: Dynamic create of view type %Fs failed\n",
    pViewClass->m_lpszClassName);
  return FALSE;
 }
    if (!pNewView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST, &context))
  {
      TRACE0("Warning: couldn't create view for frame\n");
   return FALSE;
  }
 pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);
   RecalcLayout();
   pNewView->UpdateWindow();
   SetActiveView(pNewView);
   return TRUE;
}

I hope someone can help.  Thanks!



0
Comment
Question by:binstar
  • 4
  • 3
  • 3
  • +2
13 Comments
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
What does
   GuiRv( RUNTIME_CLASS(MyView2) );
do?
What is the current behavior? (crash, not show the view, ASSERT, show msg in the trace window... ???

-- Dan

0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
this is a replace view I use in my splitters with success

BOOL CUsefulSplitterWnd::ReplaceView(int row, int col,CRuntimeClass * pViewClass,SIZE size)
{
  CCreateContext context;
  BOOL bSetActive;
           
   
  if ((GetPane(row,col)->IsKindOf(pViewClass))==TRUE)
       return FALSE;
                       
   
   // Get pointer to CDocument object so that it can be used in the creation
   // process of the new view
   CDocument * pDoc= ((CView *)GetPane(row,col))->GetDocument();
   CView * pActiveView=GetParentFrame()->GetActiveView();
   if (pActiveView==NULL || pActiveView==GetPane(row,col))
      bSetActive=TRUE;
   else
      bSetActive=FALSE;

    // set flag so that document will not be deleted when view is destroyed
     pDoc->m_bAutoDelete=FALSE;    
    // Delete existing view
   ((CView *) GetPane(row,col))->DestroyWindow();
    // set flag back to default
    pDoc->m_bAutoDelete=TRUE;
 
    // Create new view                      
   
   context.m_pNewViewClass=pViewClass;
   context.m_pCurrentDoc=pDoc;
   context.m_pNewDocTemplate=NULL;
   context.m_pLastView=NULL;
   context.m_pCurrentFrame=NULL;
   
   CreateView(row,col,pViewClass,size, &context);
   
   CView * pNewView= (CView *)GetPane(row,col);
   
   if (bSetActive==TRUE)
      GetParentFrame()->SetActiveView(pNewView);
   
   RecalcLayout();
   GetPane(row,col)->SendMessage(WM_PAINT);
   
   return TRUE;
}
0
 
LVL 9

Expert Comment

by:Pacman
Comment Utility
binstar,

your function for replacing the view is not the problem.
I'm using exactly the same function in an application (it's from MSDN, right?).

So there's going something wrong outside the function.
It would help to see the code which calls the replace function.

I don't understand this lines of code:

CChildFrame  pChildFrame;
pChildFrame.GuiRv(RUNTIME_CLASS(MyView2));

is it only a snippet and should pChildFrame be a POINTER which is somewhere else assigned by something like pChildFrame = GetChildFrame()
???


0
 
LVL 2

Expert Comment

by:shilpa_Jb
Comment Utility
Hi
here i have mentioned the steps to swtich betwn two views OnClick of toolbar button.
It would be better if u go for splitter windows.
Say u have two view  CFirtsView and CSecondView ;
CCreateContext *m_pcContext; //in header file

Assume that pViewClass = CFirstView;
BOOL CChildFrame::ReplaceView(CRuntimeClass * pViewClass)
{
      CView *pCurrentView =GetActiveView();
     CSecondView *pSecondView = (CSecondView *) pViewClass->CreateObject();
     CDocument *pDocument = pCurrentView->GetDocument();
      m_pcContext = new CCreateContext;
     if((pViewClass == NULL )|| (m_pcContext == NULL))
          return;
     if(pViewClass->IsKindOf( RUNTIME_CLASS(CFirstView) ) )
          m_pcContext->m_pNewViewClass = RUNTIME_CLASS(CSecondView);
     m_pcMainSplitter = new CSplitterWnd;    
     m_pcContext->m_pCurrentDoc = ;
     m_pcContext->m_pNewDocTemplate = NULL;
     m_pcContext->m_pLastView = NULL;
     m_pcContext->m_pCurrentFrame = NULL;
     this->CreateView(m_pcContex, AFX_IDW_PANE_FIRST );
     pSecondView->OnInitialUpdate();
     pDocument->UpdateAllViews();
     SetActiveView( pSecondView);
     return TRUE;

}
And one more suggestion if u use splitter windows switching would be more easier. Try out.
Hope it helps u.
-Shilpa    

0
 

Author Comment

by:binstar
Comment Utility
The ReplaceView code works fine if I select the View I want to switch to from the Menu bar, but the same code does not work if I am calling it from the Button in the View (which is what I want to do).

The pChildFrame.GuiRv(RUNTIME_CLASS(MyView2));
calls
BOOL CChildFrame::GuiRV(CRuntimeClass * pViewClass)
which is identical to
BOOL CChildFrame::ReplaceView(CRuntimeClass * pViewClass)
the only difference is GuiRV is called from a button in the view:

void MyView1::OnButton7()
{
CChildFrame  pChildFrame;
pChildFrame.GuiRv(RUNTIME_CLASS(MyView2));
}

while ReplaceView is called from the Menu bar. The ReplaceView works GuiRV called from the button does not.  When I trace both I notice that the this value is different in the ReplaceView (menu bar where it works)from
the GuiRV (button in View the value is 0x12f7e0 {CChildFrame hWnd=0x000000}.

It jumps to the end of the fuction in GuiRv after:
if ((pCurrentView=GetActiveView())==NULL.

Thanks
 


0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
is it because you are deleting the class/window that is handling the message - try posting a message from your button handler to the other handler in a different window to switch the views
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 9

Expert Comment

by:Pacman
Comment Utility
Sorry, but I'm really confused now ...

1. why do you have two functions for switching the view ??
2. I still don't understand these lines:

CChildFrame  pChildFrame;
pChildFrame.GuiRv(RUNTIME_CLASS(MyView2));

You make a new local CChildFrame-object on the stack.
Then you call GuiRv() to switch the view. But the child-frame window is never CREATED (means there is no phyisical window there) !!??!!

I expected code like this:

CChildFrame *pChildFrame;
pChildFrame = (CChildFrame*)GetParent();
pChildFrame->GuiRv(RUNTIME_CLASS(MyView2));

0
 
LVL 9

Expert Comment

by:Pacman
Comment Utility
... a better way would be to place the handler in CChildFrame and store the view-type:

void CChildFrame::OnButton7()
{
    GuiRv(RUNTIME_CLASS(MyView2));
}
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
Comment Utility
I think Shaun is on the right track.  Even without knowing the details of exactly what convolutes steps MFC invokes,  it seems dangerous for a piece of code (a member fn of a window object) to start a cascade of operations that eventually ends up deleting itself.

You have a menu handler that switches views right?  And it works correctly, right?  So just use it!  

In the outgoing view, post a WM_COMMAND message to the frame window.  It will be something like:

void MyView1::OnButton7()
{
   AfxGetMainWnd()->PostMessage( WM_COMMAND, IDM_SwitchToView2, 0,0);
}

-- Dan
0
 

Author Comment

by:binstar
Comment Utility
Thank You DanRollins. That is exactly what I needed.

AfxGetMainWnd()->PostMessage(WM_COMMAND,IDM_SwitchToView2, 0);  (you added one extra zero).

binstar
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
What's one little NULL between friends... lol
Thanks.

-- Dan
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
so shaun was on the right track - humph
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
... but Dan derailed him...

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

728 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now