Re: Switching views : season 2
On May 18, 10:14 am, mosfet <john....@anonymous.org> wrote:
Hi,
In my SDI application I have defined a CBaseFrame deriving from
CFrameWnd and that allow me to switch between view dynamically
created.Here is the code I suse
//CREATE_ONCE means view is create once and never deleted when switching
//CREATE_AND_DESTROY means views are deleted/recreated on switch
CBaseFrame::stViewInfo CBaseFrame::m_ViewInfo[] =
{
{ IDD_MAIN_FORM, CBaseFrame::CREATE_ONCE, AFX_IDW_PANE_FIRST + 0, NULL },
{ IDD_WELCOME_DLG, CBaseFrame::CREATE_AND_DESTROY,
AFX_IDW_PANE_FIRST + 1, NULL },
{ IDD_WIZZARD_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST
+ 2, NULL },
{ IDD_OPTIONS_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST
+ 3, NULL },
{ IDD_CNX_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST +
4, NULL },
{ IDD_SCHEDULE_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST
+ 5, NULL },
{ IDD_HISTORY_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST
+ 6, NULL },
{ IDD_ABOUT_DLG, CBaseFrame::CREATE_AND_DESTROY, AFX_IDW_PANE_FIRST +
7, NULL },
};
LRESULT CBaseFrame::OnSwitchView( WPARAM wParam, LPARAM lParam )
//CView* CBaseFrame::SwitchView( UINT a_ViewId )
{
int iCurViewIdx = 0;
int iNewViewIdx = 0;
CView* pCurView = NULL;
CView* pNewView = NULL;
BOOL bDestroyOldView = FALSE;
UINT ViewId = (UINT) wParam;
//Get current active view
pCurView = m_pFrame->GetActiveView();
TRACE( _T("CViewMgr::SwitchView : pCurView = 0x%x\r\n"), pCurView );
if ( pCurView == NULL)
return 0L;
//Get Curview and NextView index
iCurViewIdx = GetIndexFromView( pCurView );
iNewViewIdx = GetIndexFromId( wParam );
if ((iCurViewIdx == -1) || (iNewViewIdx == -1))
return 0L;
pNewView = m_ViewInfo[iNewViewIdx].pView;
// View is already displayed
if ( pNewView == pCurView ){
return 0L/*pCurView*/;
}
// New view is NULL - we must create it
if ( pNewView == NULL ){
pNewView = CreateView( ViewId, iNewViewIdx);
TRACE( _T("pNewView = 0x%x\r\n"), pNewView );
if (pNewView != NULL){
// Save new created view
m_ViewInfo[iNewViewIdx].pView = pNewView;
}
}//pView == NULL
//Make sure that the document won't be destroyed when the view is
destroyed.
//m_bAutoDelete is a public, but non-documented member of CDocument.
CDocument* pCurrentDoc = m_pFrame->GetActiveDocument();
pCurrentDoc->m_bAutoDelete = FALSE;
// exchange view window ID's so RecalcLayout() works
UINT temp = ::GetWindowLong(pCurView->m_hWnd, GWL_ID);
::SetWindowLong(pCurView->m_hWnd, GWL_ID,
::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
// Hide Old view
pCurView->ShowWindow(SW_HIDE);
//OnInitialUpdate() is not called as a result of calling CreateView()
above.
//It is not always called by the framework, so it is called here:
pNewView->OnInitialUpdate();
// Now show the new view
pNewView->ShowWindow(SW_SHOW);
m_pFrame->SetActiveView(pNewView);
m_pFrame->RecalcLayout();
pNewView->Invalidate();
// try to destroy old view
if ( m_ViewInfo[iCurViewIdx].eCreationMode == CREATE_AND_DESTROY){
pCurView->DestroyWindow();
m_ViewInfo[iCurViewIdx].pView = NULL;
}
return 0L/*pNewView*/;
}
The problem happens when I try to destroy the old view :
// try to destroy old view
if ( m_ViewInfo[iCurViewIdx].eCreationMode == CREATE_AND_DESTROY){
pCurView->DestroyWindow();
m_ViewInfo[iCurViewIdx].pView = NULL;
}
I have the following assert :
Assert wincore.cpp(windows CE) 442
LRESULT CALLBACK
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
// special message which identifies the window as using AfxWndProc
if (nMsg == WM_QUERYAFXWNDPROC)
return 1;
// all other messages route through message map
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
ASSERT(pWnd != NULL && pWnd->m_hWnd == hWnd);
...
}
Too much code to comprehend whats going on. It would appear that your
view is not valid. How did you create the view? Also, dont call
DestroyWindow on the view. Use PostMessage(WM_CLOSE). Is it MDI or
SDI?
---
Ajay