WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程Win Mobile程序开发创建基于 Microsoft .NET Framework 精简版的动画控件

创建基于 Microsoft .NET Framework 精简版的动画控件
作者:Alex Yakhnin  来源:Microsoft  发布时间:2005-12-21 17:36:09
 

Alex Yakhnin
IntelliProg, Inc.
2003年3月

适用于:
    Microsoft® .NET Framework 精简版
    Microsoft Visual Studio® .NET 2003
    Microsoft Windows® CE .NET

摘要:学习如何创建基于 .NET Framework 精简版的动画控件。

下载 AnimationControl.msi(英文)。(请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者理解。)

 

简介

在最近的项目中,有一项要求是在 Microsoft® .NET Framework 精简版的 Windows® 窗体中显示动画 GIF。.NET Framework 精简版的 1.0 版没有显示动画 GIF 文件的功能,也不包含 .NET Framework 完整版中的 ImageAnimator 辅助类。通过 ImageAnimator 类可以为基于时间帧的图像制作动画。

尽管可以编写 C# 代码读取 GIF86a 格式的动画 GIF,但是我在程序中选择了一种更简单直观的方法来显示动画。

创建情节

如果您在选定的 GIF 编辑器中打开一个动画 GIF,将会看到此文件是由相互衔接的多个图像(帧)组成的:

图 1:动画帧

这些图像以压缩格式存储,并附带有关大小、数量和帧之间的延迟时间的信息。这些信息由显示动画的程序读取。

许多 GIF 编辑器允许您将图像帧提取到顺序排列的“故事板”中:

图 2:故事板

我将故事板保存在一个位图文件中,后来将此文件转换为 GIF 格式,因为此格式的文件在 .NET Framework 精简版中占用的内存较少。现在我要向您演示如何使用此图像创建基于 .NET Framework 精简版的“动画”控件。

让我们动起来

我们所使用的让此位图动起来的方法相当简单。它基于这样一个事实,当您在 .NET Framework 精简版中使用图像时,不必显示载入内存的整个图像。graphics.DrawImage 方法的一个重载方法将 Rectangle 对象作为参数接受。我们就用这个矩形将故事板位图中的每个图像作为帧来处理。通过移动帧矩形的位置,我们可以动态载入要在窗体中显示的位图的不同部分。

我们向 .NET Framework 精简版项目中添加一个新类 AnimateCtl,并从 System.Windows.Forms.Control 派生这个类:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;

public class AnimateCtl : System.Windows.Forms.Control
{
   // 在此添加类的实现
}

向这个类中添加一个公共的 Bitmap 属性,用于从客户端传递位图。不要忘记为这个位图声明一个私有成员,以便在类中使用:

private Bitmap bitmap;
public Bitmap Bitmap
{
   get
   {
return bitmap;
   }
   set
   {
      bitmap = value;
   {
{

我们创建的这个控件将使用在其中检索的 Graphics 对象的 DrawImage 方法来绘制这些帧:

private void Draw(int iframe)
{
      //计算图形框的左边位置
      int XLocation = iframe * frameWidth;

      Rectangle rect = new Rectangle(XLocation, 0, frameWidth, 
        frameHeight);

      //绘制图像
      graphics.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel);
}

此方法接受需要绘制的当前帧号。然后计算图形框的左边位置以创建矩形。

为了实现该控件的循环逻辑,我选择使用 System.Windows.Forms.Timer

还有不少其他选项可以提供同样的功能,例如使用 System.Threading.Timer 或是创建一个单独的线程也可以达到相同的目的;但是使用 System.Windows.Forms.Timer 更简单方便。在控件的构造函数中添加以下代码:

public AnimateCtl()
{
   //缓存 Graphics 对象
   graphics = this.CreateGraphics();
   //实例化 Timer
   fTimer = new System.Windows.Forms.Timer();
   //与 Timer 的 Tick 事件挂钩
   fTimer.Tick += new System.EventHandler(this.timer1_Tick);
}

在构造函数中,我们从控件的实例中缓存 Graphics 对象并创建一个新的 Timer 实例,然后将其与 Timer 的 Tick 事件挂钩。现在已经可以插入 StartAnimation 方法,以便实际启动动画:

public void StartAnimation(int frWidth, int DelayInterval, int LoopCount)
{

      frameWidth = frWidth;
      //循环次数
      loopCount = LoopCount;
//重置循环计数器
      loopCounter = 0;
      //计算 frameCount
      frameCount = bitmap.Width / frameWidth;
      frameHeight = bitmap.Height;
      //调整控件的大小
      this.Size(frameWidth, frameHeight);
      //向计时器指定延迟间隔
      fTimer.Interval = DelayInterval;
      //启动计时器
      fTimer.Enabled = true;
}

此方法接受一些非常重要的动画参数:帧宽度、延迟间隔和循环次数。

另外,不要忘记循环逻辑:

private void timer1_Tick(object sender, System.EventArgs e)
{
         if (loopCount == -1) //不停地循环
         {
            this.DrawFrame();
         }
         else
         {
            if (loopCount == loopCounter) //停止动画
               fTimer.Enabled = false;   
            else
               this.DrawFrame();
         }
}

private void DrawFrame()
{
      if (currentFrame < frameCount-1)
      {
         //移到下一个帧
currentFrame++;
      }
      else
      {
         //递增 loopCounter
         loopCounter++;
         currentFrame = 0;
      }
      Draw(currentFrame);
}

在上面代码的 timer1_Tick 事件中,我们检查 loopCount 以跟踪已绘制的循环次数,并将其与调用 StartAnimation 方法时捕获的 loopCounter 相比较。

演出开始!

我们已经完成了 AnimateCtl,现在可以进行测试。第一步,必须将带有“故事板”的图像文件添加到您的项目中。可以通过将此文件变为嵌入的资源或仅通知 Visual Studio .NET 2003 将此文件作为项目的一部分进行复制来完成此任务。在 Solution Explorer(解决方案资源管理器)中的项目上单击鼠标右键,并在

[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码