逐步解說:將動畫加入至 MFC 專案
本逐步解說會教導如何將基本動畫物件新增至 Visual C++、Microsoft Foundation Class Library (MFC) 專案。
本逐步解說示範如何完成這些工作:
建立 MFC 應用程式。
新增功能表,然後新增命令以啟動和停止動畫。
建立啟動和停止命令的處理程式。
將動畫物件新增至專案。
將動畫物件置中視窗。
確認結果。
注意
在下列指示的某些 Visual Studio 使用者介面項目中,您的電腦可能會顯示不同的名稱或位置: 您所擁有的 Visual Studio 版本以及使用的設定會決定這些項目。 如需詳細資訊,請參閱將 Visual Studio IDE 個人化。
必要條件
若要完成這個逐步解說,您必須具有 Visual Studio。
建立 MFC 應用程式
使用 MFC 應用程式精靈建立 MFC 應用程式。 如需如何開啟 Visual Studio 版本的精靈的指示,請參閱 逐步解說:使用新的 MFC 殼層控制件 。
在 [ 名稱] 方塊中,輸入 MFCAnimationWalkthrough。 按一下 [確定]。
在 [MFC 應用程式精靈] 對話框中,確認 [應用程式類型] 為 [多個檔],[項目樣式] 為 Visual Studio,並選取 [檔案/檢視架構支援] 選項。 按一下完成。
若要新增功能表,然後新增命令以啟動和停止動畫
在 [ 檢視] 功能表上,指向 [ 其他 Windows ],然後按兩下 [ 資源檢視]。
在 [資源檢視] 中,流覽至 [功能表 ] 資料夾,然後開啟它。 按兩下 IDR_MFCAnimationWalkthroughTYPE 資源,將其開啟以進行修改。
在功能表欄的 [輸入這裡] 方塊中,輸入 A&nimation 以建立動畫功能表。
在 [動畫] 底下的 [輸入這裡] 方塊中,輸入 [開始] 和 [轉寄] 以建立 [開始轉寄] 命令。
在 [開始向前] 底下,於 [輸入這裡] 方塊中,輸入 Start &Backward。
在 [回溯開始] 下方的 [輸入這裡] 方塊中,輸入 S&top 以建立 Stop 命令。
儲存 MFCAnimationWalkthrough.rc 並關閉它。
在 方案總管 中,按兩下MainFrm.cpp將其開啟以進行修改。 在方法中
CMainFrame::OnCreate
,找出具有數個呼叫 的lstBasicCommands.AddTail
區段。 在該區段之後,新增下列程序代碼。lstBasicCommands.AddTail(ID_ANIMATION_STARTFORWARD); lstBasicCommands.AddTail(ID_ANIMATION_STARTBACKWARD); lstBasicCommands.AddTail(ID_ANIMATION_STOP);
儲存並關閉檔案。
建立啟動和停止命令的處理程式
在 [ 專案] 功能表上,按兩下 [ 類別精靈]。
在 [MFC 類別精靈] 的 [類別名稱] 下,選取 [CMFCAnimationWalkthroughView]。
在 [命令] 索引卷標的 [物件標識符] 方塊中,選取 [ID_ANIMATION_STARTFORWARD],然後在 [訊息] 方塊中,選取 [命令]。 按兩下 [ 新增處理程式]。
在 [ 新增成員函式 ] 對話框中,按兩下 [ 確定]。
在 [ 對象識別碼] 方塊中,選取 [ID_ANIMATION_STARTBACKWARD],然後在 [ 訊息 ] 方塊中,選取 [命令]。 按兩下 [ 新增處理程式]。
在 [ 新增成員函式 ] 對話框中,按兩下 [ 確定]。
在 [對象識別碼] 方塊中,選取 [ID_ANIMATION_STOP],然後在 [訊息] 方塊中,選取 [命令]。 按兩下 [ 新增處理程式 ],然後按兩下 [ 確定]。
在 [ 新增成員函式 ] 對話框中,按兩下 [ 確定]。
在 [ MFC 類別精靈] 中,按兩下 [ 確定]。
儲存在編輯器中開啟的 MFCAnimationWalkthroughView.cpp,但不關閉它。
將動畫物件新增至專案
在 方案總管 中,按兩下 MFCAnimationWalkthroughView.h 以開啟它以進行修改。 在類別定義
CMFCAnimationWalkthroughView
之前,新增下列程式代碼來建立自定義動畫控制器,以處理與動畫物件的排程衝突。class CCustomAnimationController : public CAnimationController { public: CCustomAnimationController() { } virtual BOOL OnHasPriorityTrim(CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect) { return TRUE; } };
在類別的
CMFCAnimationWalkthroughView
結尾,新增下列程序代碼。CCustomAnimationController m_animationController; CAnimationColor m_animationColor; CAnimationRect m_animationRect;
在行
DECLARE_MESSAGE_MAP()
之後,新增下列程序代碼。void Animate(BOOL bDirection);
儲存並關閉檔案。
在 MFCAnimationWalkthroughView.cpp 中,在 語句之後
#include
的檔案頂端,但在任何類別方法之前,新增下列程式代碼。static int nAnimationGroup = 0; static int nInfoAreaHeight = 40;
在 的
CMFCAnimationWalkthroughView
建構函式結尾,新增下列程序代碼。m_animationController.EnableAnimationTimerEventHandler(); m_animationController.EnablePriorityComparisonHandler(UI_ANIMATION_PHT_TRIM); m_animationColor = RGB(255, 255, 255); m_animationRect = CRect(0, 0, 0, 0); m_animationColor.SetID(-1, nAnimationGroup); m_animationRect.SetID(-1, nAnimationGroup); m_animationController.AddAnimationObject(&m_animationColor); m_animationController.AddAnimationObject(&m_animationRect);
找出 方法,
CAnimationWalthroughView::PreCreateWindow
然後將它取代為下列程序代碼。BOOL CMFCAnimationWalkthroughView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs m_animationController.SetRelatedWnd(this); return CView::PreCreateWindow(cs); }
找出 方法,
CAnimationWalkthroughView::OnDraw
然後將它取代為下列程序代碼。void CMFCAnimationWalkthroughView::OnDraw(CDC* pDC) { CMFCAnimationWalkthroughDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: add draw code for native data here CMemDC dcMem(*pDC, this); CDC& dc = dcMem.GetDC(); CRect rect; GetClientRect(rect); dc.FillSolidRect(rect, GetSysColor(COLOR_WINDOW)); CString strRGB; strRGB.Format(_T("Fill Color is: %d; %d; %d"), GetRValue(m_animationColor), GetGValue(m_animationColor), GetBValue(m_animationColor)); dc.DrawText(strRGB, rect, DT_CENTER); rect.top += nInfoAreaHeight; CBrush br; br.CreateSolidBrush(m_animationColor); CBrush* pBrushOld = dc.SelectObject(&br); dc.Rectangle((CRect)m_animationRect); dc.SelectObject(pBrushOld); }
在檔案結尾處,新增下列程序代碼。
void CMFCAnimationWalkthroughView::Animate(BOOL bDirection) { static UI_ANIMATION_SECONDS duration = 3; static DOUBLE dblSpeed = 35.; static BYTE nStartColor = 50; static BYTE nEndColor = 255; BYTE nRedColorFinal = bDirection ? nStartColor : nEndColor; BYTE nGreenColorFinal = bDirection ? nStartColor : nEndColor; BYTE nBlueColorFinal = bDirection ? nStartColor : nEndColor; CLinearTransition* pRedTransition = new CLinearTransition(duration, (DOUBLE)nRedColorFinal); CSmoothStopTransition* pGreenTransition = new CSmoothStopTransition(duration, (DOUBLE)nGreenColorFinal); CLinearTransitionFromSpeed* pBlueTransition = new CLinearTransitionFromSpeed(dblSpeed, (DOUBLE)nBlueColorFinal); m_animationColor.AddTransition(pRedTransition, pGreenTransition, pBlueTransition); CRect rectClient; GetClientRect(rectClient); rectClient.top += nInfoAreaHeight; int nLeftFinal = bDirection ? rectClient.left : rectClient.CenterPoint().x; int nTopFinal = bDirection ? rectClient.top : rectClient.CenterPoint().y; int nRightFinal = bDirection ? rectClient.right : rectClient.CenterPoint().x; int nBottomFinal = bDirection ? rectClient.bottom : rectClient.CenterPoint().y; CLinearTransition* pLeftTransition = new CLinearTransition(duration, nLeftFinal); CLinearTransition* pTopTransition = new CLinearTransition(duration, nTopFinal); CLinearTransition* pRightTransition = new CLinearTransition(duration, nRightFinal); CLinearTransition* pBottomTransition = new CLinearTransition(duration, nBottomFinal); m_animationRect.AddTransition(pLeftTransition, pTopTransition, pRightTransition, pBottomTransition); CBaseKeyFrame* pKeyframeStart = CAnimationController::GetKeyframeStoryboardStart(); CKeyFrame* pKeyFrameEnd = m_animationController.CreateKeyframe(nAnimationGroup, pBlueTransition); pLeftTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd); pTopTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd); pRightTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd); pBottomTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd); m_animationController.AnimateGroup(nAnimationGroup); }
在 [ 專案] 功能表上,按兩下 [ 類別精靈]。
在 [MFC 類別精靈] 的 [類別名稱] 下,選取 [CMFCAnimationWalkthroughView]。
在 [訊息] 索引標籤的 [訊息] 方塊中,選取 [WM_ERASEBKGND],按兩下 [新增處理程式],然後按兩下 [確定]。
在 MFCAnimationWalkthroughView.cpp 中,將 的
OnEraseBkgnd
實作取代為下列程式代碼,以在重新繪製動畫物件時減少動畫物件中的閃爍。BOOL CMFCAnimationWalkthroughView::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; }
以下列程序代碼取代、
CMFCAnimationWalkthroughView::OnAnimationStartbackward
和CMFCAnimationWalkthroughView::OnAnimationStop
的CMFCAnimationWalkthroughView::OnAnimationStartforward
實作。void CMFCAnimationWalkthroughView::OnAnimationStartforward() { Animate(TRUE); } void CMFCAnimationWalkthroughView::OnAnimationStartbackward() { Animate(FALSE); } void CMFCAnimationWalkthroughView::OnAnimationStop() { IUIAnimationManager* pManager = m_animationController.GetUIAnimationManager(); if (pManager != NULL) { pManager->AbandonAllStoryboards(); } }
儲存並關閉檔案。
將動畫物件置中視窗
在 方案總管 中,按兩下 MFCAnimationWalkthroughView.h 以開啟它以進行修改。 在類別的
CMFCAnimationWalkthroughView
結尾,在定義m_animationRect
之後,新增下列程序代碼。BOOL m_bCurrentDirection;
儲存並關閉檔案。
在 [ 專案] 功能表上,按兩下 [ 類別精靈]。
在 [MFC 類別精靈] 的 [類別名稱] 下,選取 [CMFCAnimationWalkthroughView]。
在 [訊息] 索引標籤的 [訊息] 方塊中,選取 [WM_SIZE],按兩下 [新增處理程式],然後按兩下 [確定]。
在 MFCAnimationWalkthroughView.cpp 中,將的程式代碼
CMFCAnimationWalkthroughView::OnSize
取代為下列程式代碼。void CMFCAnimationWalkthroughView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); CRect rect; GetClientRect(rect); rect.top += nInfoAreaHeight; CRect rectAnim = m_animationRect; m_animationRect = CRect(CPoint(rect.CenterPoint().x - rectAnim.Width() / 2, rect.CenterPoint().y - rectAnim.Height() / 2), rectAnim.Size()); if (m_animationController.IsAnimationInProgress()) { Animate(m_bCurrentDirection); } }
在 的
CMFCAnimationWalkthroughView
建構函式開頭,新增下列程序代碼。m_bCurrentDirection = TRUE;
在方法的
CMFCAnimationWalkthroughView::Animate
開頭,新增下列程序代碼。m_bCurrentDirection = bDirection;
儲存並關閉檔案。
確認結果
- 建置並執行應用程式。 在 [動畫] 功能表上,按兩下 [開始轉寄]。 矩形應該會出現,然後填滿中心區域。 當您按兩下 [ 開始向後] 時,動畫應該反轉,而當您按兩下 [停止] 時,它應該會停止。 當動畫進行時,矩形的填滿色彩應該會變更,而目前的色彩應該會顯示在動畫視窗頂端。