|
|
|
Win
CE Switching CFormView Problems

Suppose you want to be able to switch among various form views in
Windows CE, either in a CMainFrm window or in a CSplitterFrame Pane.
This would seem to be an easy task, and there are various example codes to
do this for regular desktop windows, i.e. VSwap32.exe. However, if
you try this in Pocket PC you may get unpredictable crashes when you
create the form views or switch to them. It turns out that the
resource that the form is based on must be specified as follows to avoid
crashes:
style: child
border: none
center: checked
All else is unchecked.
Here's some source code to swap CFrom Views:
void CMainFrame::CreateAlternateViews() {
// This code was taken from the MS sample VSwap32.exe.
// Make sure that the view is a view and not a dialog,
If based on a resource form, make sure that
// it is not set to visible!
m_nCurView = 0; // Save index of the currently active
view class
// Keep array of views as member of WinApp
CView* pActiveView = GetActiveView();
m_pViews[0] = pActiveView;
// view created by doctemplate
m_pViews[1] = (CView*) new CForm1;
m_pViews[2] = (CView*) new CForm2;
m_pViews[3] = (CView*) new CForm3;
m_pViews[4] = (CView*) new CForm4;
// Initialize a CCreateContext to point to the active
document.
// With this context, the new view is added to the
document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = GetActiveDocument();
CRect rect(0, 0, 0, 0); // gets resized later
// Need to cast pointers to have correct Create
functions called
// CForm2 is CFormView::Create
// Create the new view. In this example, the view
persists for
// the life of the application. The application
automatically
// deletes the view when the application is closed.
for(int i=1;i<NUM_VIEWS;i++) {
// The ID of the initial active
view is AFX_IDW_PANE_FIRST.
// Incrementing this value by
one for additional views works
// in the standard
document/view case but the technique cannot
// be extended for the
CSplitterWnd case.
m_pViews[i]->Create(NULL,
NULL,(AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE),rect, this,
AFX_IDW_PANE_FIRST+i, &newContext);
// views are created with the
style of AFX_WS_DEFAULT_VIEW
// In MFC 4.0, this is (WS_BORDER
| WS_VISIBLE | WS_CHILD)
}
// When a document template creates a view, the
WM_INITIALUPDATE
// message is sent automatically. However, this code
must
// explicitly send the message, as follows.
for(i=1;i<NUM_VIEWS;i++) {
m_pViews[i]->OnInitialUpdate();
}
}
CView* CMainFrame::SwitchView(UINT nIndex) {
ASSERT( nIndex >=0 && nIndex < NUM_VIEWS
);
CView* pNewView = m_pViews[nIndex];
CView* pActiveView = GetActiveView();
if (!pActiveView) return NULL; // No currently active
view
if ( pNewView == pActiveView ) return pActiveView; //
Already there
// Update Doc's data if needed
// Don't change view if data
valiation fails
// if ( ! SaveActiveViewsData()
) {
// return pActiveView;
// }
m_nCurView = nIndex; // Store the new current view's
index
// exchange view window ID's so RecalcLayout() works
UINT temp = ::GetWindowLong(pActiveView->m_hWnd,
GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd,
GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
// Display and update the new current view - hide the
old one
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
SetActiveView(pNewView);
RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}
Daycounter specializes in contract
electronics design. Do you need some help on your project? Contact
us to get a quote.
[Employment]
[Downloads][Articles]
[Contact Us]
Call us now at
801-523-8444 - 136 E. Steep Mountain Dr. Draper, UT 84020
© Copyright 2004 Daycounter, Inc. All rights Reserved.
|
|