?
Solved

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

Posted on 2001-09-13
13
Medium Priority
?
379 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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 800 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: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone 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: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

771 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