|
随着计算机使用的普及以及计算机动画技术的飞速发展,人们对动画应用的要求也日益提高。所谓动画也就使一幅图像"活"起来的过程。使用动画可以清楚的表现出一个事件的过程,或是展现一个活灵活现的画面。如今电脑动画的应用十分广泛,让应用程序更加生动,增添多媒体的感官效果;还应用于游戏的开发,电视动画制作,创作吸引人的广告,电影特技制作,生产过程及科研的模拟等等。
1 动画实现原理
窗口标题栏上、工具条上、状态条上存在的都是一些较小的图像,我们可通过不同的相对连续的几幅静态画面按一定的时间间隔显示来实现动画的效果。在VC中有一个CImageList类(CImageList 类提供了Windows图像列表通用控件功能),可以以图像列表的方式管理图像,图像列表中的图像大小相同,索引以0为开始,每个图像都可以单独引用。接着,利用Draw函数在一定的时间间隔播放出来。Microsoft Win32 的API提供了一系列的函数,可以利用这些函数创建、销毁图像列表,可以显示图像、增加和删除图像,替代、合并和拖动图像。
2 主要函数介绍
(1)BOOL Create( int cx, int cy, UINT nFlags, int nInitial, int nGrow )。 该函数用于创建一个图像列表。 cx,cy 每个图像的宽度和高度;nFlags图像列表的类型,其值仅可包含一个ILC_COLOR值。nInitial 图像列表最初含有的图像数目;nGrow 当图像数量需要改变时,每次动态增长的图像数。
(2)BOOL Draw( CDC* pdc, int nImage, POINT pt, UINT nStyle )。 该函数用于显示一个图像。pdc 目标设备上下文的指针;nImage 要显示的图像索引;pt 图像显示的位置;nStyle图像显示风格。
(3)HICON ExtractIcon( int nImage )。 利用该函数可以得到一函数的句柄。
(4)int Add( HICON hIcon )。 该函数把一个图像加入图像列表。 在程序中声明一个CImageList类,调用Create函数创建该类,然后以一定的时间用Draw函数循环显示图像,就可以形成动画效果。Create类有几个重载函数,可以根据不同的资源调用不同的函数,为了简便其间,本文只采用图标资源。
3 具体实现
首先,建立图表资源。在VC++6.0中利用资源编辑器,建立几幅图表,IDI_ICON1、IDI_ICON2、IDI_ICON3....,在编辑图标时选者Custom,将图标设置成大小为64X32。由于Windows的各个部件不完全相同,其实现方法也不完全相同,下面对在窗口不同位置显示动画的方法分别介绍。
3.1 状态条上显示动画 状态条也是窗口,所以也可以在其上显示动画。状态条时主窗口的子窗口,在CMainFrame类中可以看到下列代码: protected: // control bar embedded members CStatusBar m_wndStatusBar; 所以为了在状态条上显示动画,其编程代码应在CMainFrame类中加入。首先创建资源文件和图像列表类。 在类的定义文件中加入下列变量: POINT pt1;//图像显示的位置 int m_Play; //将要显示图像的索引 void CreateImageList();//创建图像列表的函数 CImageList m_ImageList1;//图像列表对象 int m_ImageNumber; //图像列表中图像的总数目 首先在创建函数时初始化pt1,m_Play,m_ImageNumber: CImageView::CImageView() { // TODO: add construction code here pt1.x =1; pt1.y =1; m_Play=0; m_ImageNumber=0; } CreateImageList()的实现如下: void CImageView::CreateImageList() { m_ImageList1.Create (64,32,ILC_COLOR,5,2); HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1)); m_ImageList1.Add(hIcon); m_ImageNumber++; hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON2)); m_ImageList1.Add(hIcon); m_ImageNumber++; hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON3)); m_ImageList1.Add(hIcon); m_ImageNumber++; .........//要播放的所有资源加入图像列表。 } 在OnCreate函数中设置计时器,并创建图像列表: int CImageView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here CreateImageList(); SetTimer(1,500,NULL); return 0; } 响应ON_TIMER消息,显示动画: void CMainFrame::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(m_Play>m_ImageNumber) m_Play=0;//如果图画为最后一个,显示第一幅图片 CDC *pDC=this->m_wndStatusBar.GetDC(); ASSERT(pDC!=NULL); pt1.x=1; pt1.y =1; m_ImageList1.Draw(pDC,m_Play,pt1,ILD_TRANSPARENT); ReleaseDC(pDC); m_Play++; CFrameWnd::OnTimer(nIDEvent); } 上述代码将在状态条左上方播放动画。 3.2 工具栏上显示动画 由于工具栏的性质与状态条差不多,其播放动画的方法也相似。 ON_TIMER的响应函数: void CMainFrame::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(m_Play>m_ImageNumber) m_Play=0;//如果图画为最后一个,显示第一幅图片 CRect rect; CDC *pDC; pDC=this->m_wndToolBar.GetDC(); ASSERT(pDC!=NULL); this->m_wndToolBar.GetClientRect(&rect);//获得显示有效区域 pt1.x =rect.right -64; //将显示位置定在最右边 pt1.y=1; m_ImageList1.Draw(pDC,m_Play,pt1,ILD_TRANSPARENT); ReleaseDC(pDC); m_Play++; CFrameWnd::OnTimer(nIDEvent); } 上述代码将在工具栏右上方播放动画。但如仔细观察,动画的位置并不是靠近窗口 最右边,这是因为工具栏的窗口有边界,采用如下方法,可以把画面移到窗口右边: pDC=GetDC ();//获得CMainFrame的画图设备指针 ASSERT(pDC!=NULL); this->GetClientRect(&rect); pt1.x =rect.right-64 ; pt1.y=rect.top+3 ; m_ImageList1.Draw(pDC,m_Play,pt1,ILD_TRANSPARENT); ReleaseDC(pDC); 这是因为工具栏占据的位置属于CMainFrame的客户区。 3.3 窗口标题栏上动画 在CWnd类中有一个函数: HICON SetIcon( HICON hIcon, BOOL bBigIcon ); 可以改变窗进口的图标,所以您可以通过使用该函数不断的改变图标使图标动起来。 在OnTimer函数中加入下列代码: SetIcon(m_ImageList1.ExtractIcon(m_Play),FALSE); 就可以使图标动起来。当然为了使程序工作的更好,最好重建一套图标资源。
4 结束语
在开发程序时,程序的界面设计是一个非常重要的方面。随着计算机信息表示及实现的多媒体化,在许多学习软件、游戏软件,以及多媒体课件制作软件中,经常使用各种动画显示技巧,这样使画面变得更为生动活泼,更能吸引用户,也为更好地发挥软件的功能奠定了基础。若要进一步友好应用程序,您可依据本文思想结合鼠标移入、移出时的消息处理函数使Windows标准按钮显示动画效果。
参考文献 1 清汉计算机工作室.Visual C++ 6.0多媒体开发实例.机械工业出版社 2 Marshall Brain,Lance Lovette.MFC开发人员指南.机械工业出版社 |