Solved

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

Posted on 2001-09-13
13
373 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
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
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
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

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Turn a spreadsheet into a vba executable. 2 87
Detect CR LF to each line 12 161
maxBlock challenge 30 129
java ^ examples 8 67
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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…
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 shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

803 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