|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article shows how to animate child view transitions on a WTL 8.0 Windows Mobile application. BackgroundThe idea for researching the code for this article came after reading Tim Brook's article on how to switch views in a WTL SDI application. This technique is quite useful for Windows Mobile applications because the platform does not support MDI (although you can use tabbed views). After testing Tim's idea, I thought about animating the child view transitions. This would be a bit better than just replacing the old view with the new one. Why not add a bit of FX and make it a bit more interesting to the eye? Also, the developer may want to use the child transition animations to convey the idea of spatial navigation to the user: the new view might be shown scrolling up when the user drills-down to more detailed information, and scrolling up when returning to the previous level. Using the codeFor the developer's convenience, I put all the required code into mix-in classes that must be listed in the public inheritance list of both the main frame and all the animated child view windows that will be hosted by the frame. Main frame codeCoding the main frame is quite easy. Start by adding the class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>, public CChildViewAnimate<CMainFrame>, public CMessageFilter, public CIdleHandler Next, you need to make a small change to your virtual BOOL PreTranslateMessage(MSG* pMsg) { if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg)) return TRUE; return ChildPreTranslateMessage(pMsg); } The call to Finally, you must initialize the current view pointer on the frame's ... m_hWndClient = m_viewForm.Create(m_hWnd); m_pView = &m_viewForm; ... The Child view codeOn the child view class, you only need to add the class CSlideFormView : public CDialogImpl<CSlideFormView>, public CChildView<CSlideFormView> { public: enum { IDD = IDD_SLIDEVIEW_FORM }; virtual BOOL PreTranslateMessage(MSG* pMsg) { if(!::IsWindow(m_hWnd)) return FALSE; return CWindow::IsDialogMessage(pMsg); } BEGIN_MSG_MAP(CSlideFormView) END_MSG_MAP() }; Animating child viewsChild view transitions are animated by scrolling left, right, up, or down. The old view and the new one are scrolled together to give the user an idea of continuous movement. Before we can scroll a new view into position, we must first create it. When the new view is created, it is very important not to show it immediately, so I opted to give every new view a rectangle of the same size as the current view, but offset to the right so it does not show on top of the current view. You can see how this is done in the sample application when both the tree and the list views are created: CWindow wndView(*m_pView); wndView.GetClientRect(&rc); nWidth = rc.Width(); rc.left += nWidth; rc.right += nWidth; hWnd = m_viewList.Create(m_hWnd, &rc, NULL, dwStyle); After successfully creating the new child view, you can then animate it into view by calling: SwitchToView(&m_viewList, m_nAnimate); The enum ViewAnimation { None, // Don't animate the child transitions ScrollLeft, // Scroll the views to the left ScrollRight, // Scroll the views to the right ScrollUp, // Scroll the views up ScrollDown // Scroll the views down }; When ImplementationChild view animation is implemented in the protected Also, while the new child window is moved into position, the code makes sure only to invalidate the new portion of the window that is displayed at any given scrolling step. This also helps making the whole process smoother. Finally, there is a method worth mentioning: void ScrollWait(DWORD dwTickIni, DWORD dwTickEnd) { DWORD dwTickDel = dwTickEnd - dwTickIni; if(dwTickDel > m_dwMaxTick) { m_dwMaxTick = dwTickDel; } else { // Preserve original timing (yes, this burns the CPU) while(GetTickCount() - dwTickIni < m_dwMaxTick) ; } } The Points of interestAs you can see from the sample, there are three different views that you can animate: a form, a list, and a tree. If you look at the tree implementation, you will see that it is very different from the list's: the tree is hosted in another window. While the list view window is the child view, the tree view had to be hosted in another window for a very strange reason: it would not paint correctly when scrolled into view. Why? I actually don't know... Finally, you might be interested in looking at the included History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||