本演练介绍如何将基本动画对象添加到 Visual C++,Microsoft基础类库 (MFC) 项目。
本演练演示如何完成以下任务:
创建 MFC 应用程序。
添加菜单,然后添加命令以启动和停止动画。
为启动和停止命令创建处理程序。
向项目添加动画对象。
将动画对象居中。
验证结果。
注释
计算机可能会在以下说明中显示某些 Visual Studio 用户界面元素的不同名称或位置。 你拥有的 Visual Studio 版本以及所使用的设置决定了这些元素。 有关更多信息,请参阅 自定义 IDE。
先决条件
若要完成本演练,必须具有 Visual Studio。
创建 MFC 应用程序
使用 MFC 应用程序向导 创建 MFC 应用程序。 请参阅 指南:使用新的 MFC Shell 控件,了解如何在您的 Visual Studio 版本中打开向导。
在 “名称 ”框中,键入 MFCAnimationWalkthrough。 单击 “确定” 。
在 “MFC 应用程序向导” 对话框中,验证 应用程序类型 是否为 多个文档, 项目样式 为 Visual Studio,并且已选择 “文档/视图体系结构支持 ”选项。 单击“完成”。
添加菜单,然后添加命令以启动和停止动画
在 “视图 ”菜单上,指向 “其他 Windows ”,然后单击“ 资源视图”。
在 “资源视图”中,导航到 “菜单” 文件夹并打开它。 双击 IDR_MFCAnimationWalkthroughTYPE 资源将其打开以供修改。
在菜单栏的“ 键入此处” 框中,键入 A&nimation 以创建动画菜单。
在 “动画”下,在“ 键入此处” 框中,键入 “开始”和“转发 ”以创建“开始转发”命令。
在 “开始向前”下,在 “键入此处” 框中,键入 “开始”和“向后”。
在“ 开始向后”下,在 “键入此处” 框中,键入 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 ”框中,选择 “ID_ANIMATION_STARTFORWARD”,然后在“ 消息 ”框中选择 “COMMAND”。 单击“ 添加处理程序”。
在“ 添加成员函数 ”对话框中,单击“ 确定”。
在 “对象 ID ”框中,选择 ID_ANIMATION_STARTBACKWARD,然后在 “消息 ”框中,选择 “命令”。 单击“ 添加处理程序”。
在“ 添加成员函数 ”对话框中,单击“ 确定”。
在 “对象 ID ”框中,选择 ID_ANIMATION_STOP,然后在 “消息 ”框中选择 “COMMAND”。 单击 “添加处理程序 ”,然后单击“ 确定”。
在“ 添加成员函数 ”对话框中,单击“ 确定”。
在 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; }
将
> 的实现 替换为以下代码。 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;
保存文件并将其关闭。
验证结果
- 生成并运行应用程序。 在 “动画 ”菜单上,单击“ 开始前进”。 应显示一个矩形,然后填充中心区域。 单击“ 向后开始”时,动画应反转,单击“ 停止”时,动画应停止。 随着动画的进行,矩形的填充颜色应发生变化,当前颜色应显示在动画窗口顶部。