Solved

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

Posted on 2001-09-13
13
378 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
[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
  • 4
  • 3
  • 3
  • +2
13 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 6481334
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
ID: 6481900
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
ID: 6482076
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Expert Comment

by:shilpa_Jb
ID: 6482268
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
ID: 6482517
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
ID: 6482538
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
 
LVL 9

Expert Comment

by:Pacman
ID: 6482628
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
ID: 6482651
... 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
ID: 6483245
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
ID: 6483871
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
ID: 6484124
What's one little NULL between friends... lol
Thanks.

-- Dan
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6485001
so shaun was on the right track - humph
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6485141
... but Dan derailed him...

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …

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