您现在的位置:首页 >> VCL >> VCL >> 内容

Delphi组件开发教程指南(六)实现一个模拟动画显示控件

时间:2011/9/3 16:22:46 点击:

  核心提示:由于最近几天有点小忙,是以没多少时间来继续这个教程指南的编写。好容易捡到一个周末,挤着这个周末,有兴趣的跟着我继续向前走!在走之前,我希望大家先回顾回顾前5章的内容,看看通过前面的5章内容,是否能够扩...
由于最近几天有点小忙,是以没多少时间来继续这个教程指南的编写。好容易捡到一个周末,挤着这个周末,有兴趣的跟着我继续向前走!在走之前,我希望大家先回顾回顾前5章的内容,看看通过前面的5章内容,是否能够扩充点简单的控件,并且能够注册到Delphi中使用了吧!如果还不会的请反复琢磨琢磨,多琢磨几次也就明白那么个理了,这些东西都不是啥难点,我本人觉得,只要你能够认字,没有啥东西是你学不会的!前面的基础讲过了之后,现在开始我想我会通过实现一些控件的编写实例入手来解说控件编写的始末,因为光讲理论,我实在不晓得如何讲,还是一切源于实践中来得快,然后我自己实现的控件,自己的思路也是瞑目了然,也能够更清晰的说出思路等,当然我实现的这些控件未必是我自己使用的组件,可能完全是心血来潮,即时想到的,未必会用于实际项目,同时也由于是临时起意的东西,目的在于教学,所以,在效率和完整度上,可能不会追求完美,有好思路的可以在帖子后面跟进写出自己的思路与实现方式。同时也可以让大家共同进步与学习。

    好了,废话不多说了,进入正题,这次,我没有继续在Edit编辑框上做文章,相反却是想要实现一个能够模拟一个能够显示运动效果的动画控件,这个动画效果,就是类似于Windows登录的那个滚动,以及QQ登录那个反复滚动的效果图那样的!这样的动态图实际上比较多,如果做好了就可以用来模拟实现GIF图片的动画效果了。

首先,我们来分析一下,这个控件的继承方式,这个根据个人需要,如果仅仅作为显示使用,不涉及到太多的消息以及事件响应消息的可以从TGraphicControl继承来实现,因为TGraphicControl就是专门用来实现仅仅显示效果的控件的,他的特性,我在前面的概述中有提到过,不明白的可以返回去查看;如果需要处理一些特殊消息以及句柄的处理的,那么请从TWinControl继承来实现。这里我选择直接从TGraphicControl来实现!

   其次,这个动画效果,我们通过什么来实现!这个很容易想到TImagelist,Delphi自己带有的一组图片集合控件,通过这个图片集合,我们可以设定一个延迟时间,每隔多少时间就从ImageList中取得一幅图片然后刷新到客户面前!那么不断的执行这个过程,不就实现了动画效果了哈!

  那好,现在就开始编写代码,在上回我们的控件包中添加一个新的单元,我取名为DxAnimateControl,然后打一个框架如下

unit DxAnimateControl;
interface
uses
  Windows,SysUtils, Classes, Controls,Graphics,ImgList;
type
  TDxAnimateControl = class(TGraphicControl)
  public
    constructor Create(AOwner: TComponent);override;
  end;
implementation

{ TDxAnimateControl }
constructor TDxAnimateControl.Create(AOwner: TComponent);
begin
  inherited;
end;
end.

这个框架中,我什么都没写,上面说了,动画通过一个ImageList来取图,所以新建一个ImageList的开放属性,能够在设计期间使用的,所以放在Published域中

property ImageList: TImageList;

另外,我们需要一个变量PicIndex,用来存储当前是哪一帧图片。至于那个取图片的重复过程,可以有两种方法来实现,方法一是采用Delphi自己的时钟控件,方法二是采用线程来模拟时钟的效果。我这里为了简单起见,就只用Delphi自己的时钟来实现了,所以需要一个Timer,然后Timer的时钟过程就是取得新的图片,然后通知刷新,这样显示给咱的就是动画效果了。时钟有了还需要一个属性,用来激活或者停止动画的开关,这个开关属性,咱设置为Active。属性定了,就可以写代码了,先实现ImageList赋值的过程

procedure TDxAnimateControl.SetImageList(const Value: TImageList);
begin
  if FImageList <> Value then
  begin
    FImageList := Value;
    if FImageList <> nil then
    begin
      Width := FImageList.Width;
      Height := FImageList.Height;
    end;
    DoTimer(nil);
  end;
end;

ImageList的设置过程中就会调用一次时钟过程进行一个初始设定,然后我们再看看时钟过程了

procedure TDxAnimateControl.DoTimer(Sender: TObject);
begin
  bmp.Canvas.Brush.Color := Color;
  bmp.Canvas.FillRect(ClientRect);
  if (FImageList <> nil) and (FImageList.Count <> 0) then
  begin
    inc(PicIndex);
    if PicIndex > FImageList.Count - 1 then
      PicIndex := 0;
    FImageList.GetBitmap(PicIndex,Bmp);
  end;
  Invalidate;
end;

时钟过程就是用来取得图片的一个过程,取到图片了之后就调用Invalidate通知刷新,然后就会触发Paint过程,Paint过程相当简单,仅仅就是将取得的图片绘制出来就完事了

procedure TDxAnimateControl.Paint;
begin
  if not bmp.Empty then
    Canvas.CopyRect(ClientRect,bmp.Canvas,bmp.Canvas.ClipRect)
  else inherited;
end;

这个代码目前实现的是相当的简单的。希望大家都能够看懂,其他代码请大家先自己补齐完成,等到下次的时候,再给出所有代码,同时请大家思考,除了ImageList的方式之外,还能通过什么方式来实现这个动画效果。下次我就讲通过另外一种方式来实现这个动画效果了!

作者:不得闲 来源:转载
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • 盒子文章(www.2ccc.com) © 2022 版权所有 All Rights Reserved.
  • 沪ICP备05001939号