TBzAniBackground component by Vladimir Kladov (C) 1999
version 1.5 for Delphi3
------------------------------------------------------
(To read about TBzBackground read BzBackground_readme.txt)
TBzAniBackground component is intended to provide owner-
drawn visual controls with background. It is possible to
use as background an image of any standard graphic format
registered under Delphi (Bitmap, Icon, Metafile, JPEG
are original and other can be added by custom packages).
It is also possible to use any format image as a sequence
of frames (laying horizontally one by one) to create
animated background (You may use my component TBzConvGIF2Bmp
component to translate GIF to such sequence of bitmaps
ready to use with BzAniBackground). Indeed it is possible
to use background color instead image. In future version
I plan to add gradient effect between two colors in given
direction.
As this component is a part of my fast growing Bonanzas
Graphics Delphi Library of components it uses 
TBzImgCollection/TBzImgCache components to store an image
invited to be background. Be sure You have these two
components installed before use TBzAniBackground. 
For more detailed explanation why these two above components
are intended read info on my page and in readme files 
accompanied with them. In short it can be said that first
is to reduce application requirements in GDI resources 
(under Win95/98), second is mainly to cache images if 
application uses a lot of external images from hard disk. 
Also these allow for TBzAniBackground by very simple
way to support stretching and blending (with given color)
of background and work faster.
Style of background can be adjusted by property BkColor and
property Options : Set of TBzBackgroundOption (boTiled,
boCenter, boStretch, boKeepRatio, boTransparent, boBlending25,
boBlending50, boAnimate); (Stretching and centering has
effect if BzAniBackgound know for what control it is applied
- by setting ViewControlProperty or at least by setting
ViewRectProperty; options boBlending25 and boBlending50 are
exclusive; option boKeepRatio extends boStretch and has effect
only if boStretch is in options, and so on - see below).
   Remember: to use GIF (including animated) as background You
also have to obtain TBzConvGIF2Bmp component and TBzGIFImage
object from my WEB page.

How it works? It exports for You two procedures:
FillRectWithBackground( ACanvas : TCanvas; ARect : TRect;
   XStrt, YStrt : Integer );
FillImgRectWithBackground( ImgIdx : Integer; ARect : TRect;
   XStrt, YStrt : Integer );
XStrt, YStrt - is a top left corner of ARect rectangle on
destination control (not on ACanvas or on image ImgIdx in 
collection- this can temporary off-screen buffer bitmap).
Also it provides an event OnChange which occures after changing
image or frame. In handler of this event You usually repaint
control with background. And in paint procedure You use
FillRectWithBackground or FillImgRectWithBackground method
for temporary off-sceen bitmap/buffer image in collection
to fill rectangle with portion of background before painting
all what You need to paint over it.

When BzAniBackground is activated by setting property ImgIndex,
it allocates buffer image with appropriate size in collection 
for storing frames. So be careful when use stretching option for
large controls - this may require to create VERY LARGE buffer...

To reduce painting operations You may use exported procedure
InvalidateControl( Erase : Boolean ) to invalidate only changed
parts of ViewControl client area when image (frame) changed.
And then more accurately implement paint procedure for this
control to avoid painting of areas, which did not changed.
This is only for advanced developers who fills him(her)self
sufficiently close to low-level painting in Windows.

Here is the cutter of declarations part of this module:
>>>---------------------------------------------------------------
//===================================================
// TBzAniBackground Delphi component by Vladimir Kladov.
// version 1.5 (C) 1999
//
// Bonanzas' TBzAniBackground component is to show any
// control with its own background including animated.
// For background to be animated it must be a bitmap
// with sequence of frames on one horizontal line.
// Drawing occures to off-screen bitmap canvas to avoid
// flickering. Several effects are possible: TILED,
// STRETCHED, CENTERED, TRANSPARENT, BLENDING and so on.
// Following formats are supported immediately:
// BMP, ICO, WMF, EMF, JPG. GIF (including animated can
// be supported additionally using my TBzConvGIF2Bmp
// component to translate GIF to bitmap frames sequence
// using RxLib's TGIFImage class).
//====================================================

unit BzAniBackground;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, BzImgCach, BzImgCollection;

type
  TBackgroundOption = ( boTiled, boCenter, boStretch, boKeepRatio,
                    boTransparent, boBlending25, boBlending50, boAnimate );
  TBackgroundOptions = Set of TBackgroundOption;

  TBzAniBackground = class(TComponent)
  private
    { Private declarations }
    fCache : TBzImgCache;  // BzImgCache through which images from BzImgCollection accessed
    fImgIndex : Integer;   // Index of picture in TBzImgCache & TBzImgCollection
    fOptions : TBackgroundOptions; // Options
    fTimer : TTimer;       // Timer to animate GIF
    fRate : Integer;       // Relative speed of GIF animation in percents
    fViewCtl : TControl;   // Control to use background
    fViewRect: TRect;      // Rectangle to use background
    fPrevOutRect : TRect;  // Previous rect to out background image
    fBkColor : TColor;     // Background color (when is not transparent)
    fOnChange : TNotifyEvent; // Event to notify when changed or next frame income
    fChanging : Boolean;      // To prevent recurse...
    fInvalidAll : Boolean;    // True, if refresh all (after changing of stretch, bkcolor and other)
    fBlendColor : TColor;     // Color to blend;
    fFramesInfo : TList; // of PBzAniFrameInfo - Delay and Rect for every frame of animated image
    fFrameIdx : Integer;      // Index of current frame in animated image
    fStdFrameInfo : Boolean;  // Frames info is stored as ImgData[ ImgIdx ] in BzImgCollection
    fBufferIdx : Integer;          // Index of buffer rect in fCache.ImgCollection
    fBufferW, fBufferH : Integer;  // Size of buffer allocated in fCache.ImgCollection
    fLastW1, fLastH1 : Integer;    // Size of last stretched [& blended] image
    fLastBlendFactor : TBlendStyle;// Last blendidng buffer parameter (None, 25, 50)
    fLastBlendColor : TColor;      // Last blending buffer color
    fStretchDirectly : Boolean;    // Create stretched/blended buffer image directly
    procedure SetImgCache( Cache : TBzImgCache );
    procedure SetImgIndex( Idx : Integer );
    procedure SetOptions( Op : TBackgroundOptions );
    procedure SetBkColor( Bk : TColor );
    procedure SetViewCtl( WCtl : TControl );
    procedure SetViewRect( R : TRect );
    procedure TimerTick( Sender : TObject );
    procedure Changed;
    procedure CalculateDestSize( var W1, H1 : Integer );
    function GetWidth : Integer;
    procedure SetWidth( W : Integer );
    function GetHeight : Integer;
    procedure SetHeight( H : Integer );
    procedure SetRate( R : Integer );
    procedure SetBlendColor( BC : TColor );
    procedure FrameChanged;
    function GetFrameCount : Integer;
    procedure SetFrameCount( FC : Integer );
    function GetFrameDelays( Idx : Integer ) : Integer;
    procedure SetFrameDelays( Idx, Delay : Integer );
    function GetFrameRects( Idx : Integer ) : TRect;
    procedure SetFrameRects( Idx : Integer; R : TRect );
    procedure SetFrameIndex( Idx : Integer );
    procedure ClearFramesInfo;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create( AOwner : TComponent ); override;
    destructor Destroy; override;
    procedure Clear;
    procedure InvalidateControl( Erase : Boolean );
    procedure FillRectWithBackground( Canvas : TCanvas; ARect : TRect;
                                      XStrt, YStrt : Integer );
    procedure FillImgRectWithBackground( DstIdx : Integer; ARect : TRect;
                                      XStrt, YStrt : Integer );
    property FrameDelays[ Idx : Integer ] : Integer read GetFrameDelays write SetFrameDelays;
    property FrameRects[ Idx : Integer ] : TRect read GetFrameRects write SetFrameRects;
    property FrameCount : Integer read GetFrameCount write SetFrameCount;
    property FrameIndex : Integer read fFrameIdx write SetFrameIndex;
  published
    { Published declarations }
    property ImgCache : TBzImgCache read fCache write SetImgCache;
    property ImgIndex : Integer read fImgIndex write SetImgIndex;
    property Options : TBackgroundOptions read fOptions write SetOptions;
    property BkColor : TColor read fBkColor write SetBkColor;
    property ViewControl : TControl read fViewCtl write SetViewCtl;
    property ViewRect : TRect read fViewRect write SetViewRect;
    property Width : Integer read GetWidth write SetWidth;
    property Height : Integer read GetHeight write SetHeight;
    property OnChange : TNotifyEvent read fOnChange write fOnChange;
    property Rate : Integer read fRate write SetRate;
    property BlendColor : TColor read fBlendColor write SetBlendColor;
    property StdFrameInfo : Boolean read fStdFrameInfo write fStdFrameInfo;
    property StretchDirectly : Boolean read fStretchDirectly write fStretchDirectly;
  end;

procedure Register;

implementation
<<<-------------------------------------------------------------------

Brief description of certain properties and methods:
* procedure InvalidateControl( Erase : Boolean );
	Use it in OnChange event handler to invalidate only changed parts
	of control when image (frame) changed. You also need to set ViewControl
	property and have to take in consideration which areas are invalid
	when painting control. If it is too hard for You just invalidate the
	whole client area of control in OnChange event handler.

* procedure FillRectWithBackground( Canvas : TCanvas; ARect : TRect;
                                      XStrt, YStrt : Integer ); <<<KEY>>>
	Key procedure. Fills given rectangle with part of background taking
	into considerations all Options (boTiled, boCenter, and so on),
	BkColor, ViewControl (if it is set), ViewRect (if it is set), and
	considering Point( XStrt, YStrt ) as top left corner of correspondent
	rectangle in DESTINATION control with the same size as ARect.
	For example if You draw a cell of TStringGrid (it must be owner draw),
	You first draw a portion of background onto off-screen bitmap, then
	paint over it content of the cell, and last copy this bitmap onto
	grid canvas. This procedure is not too easy but it allows to avoid
	flickering.

* procedure FillImgRectWithBackground( DstIdx : Integer; ARect : TRect;
                                      XStrt, YStrt : Integer );
	Key procedure. Fills given rectangle of image DstIdx in collection.
	Works faster then FillRectWithBackground procedure. All other is
	the same as for FillRectWithBackground.

* property FrameDelays[ Idx : Integer ] : Integer;
	If backround image is a sequence of frames (boAnimate option can take
	effect in that case), You may use this property to read or change
	delay time for every of frames (0..FrameCount-1). If You write
	FrameDelays[ I ] with index I greater or equal to FrameCount then
	number of frames is set to (I + 1) value (growths). This is the way to
	tell to BzAniBackground that image is animated and has a number of
	frames.

* property FrameRects[ Idx : Integer ] : TRect;
	All said above for FrameDelays is true for FrameRects. This allows
	You to read or change rectangular areas in frames, which are differ
	from previous. Usually You need not to change it. If You use my
	TBzRxGIF2Bmp component to translate GIF to bitmap containing a
	sequence of frames, just leave property StdFramesInfo = True (default)
	and all info about frames will be received by BzAniBackground from
	image stored in BzImgCache when You set property ImgIndex.

* property FrameCount : Integer;
	Read it to knew how many frames are in image. Write it to divide image
	onto certain number of frames (image really not divided, it just
	considered as a sequense of frames).

* property FrameIndex : Integer;
	Read it to knew what frame (0..FrameCount-1) is current. Write it to
	change current frame.

DESIGN-TIME PROPERTIES:
* property ImgCache : TBzImgCache;		<<<KEY>>>
	You have to set it (may be at run time) to start using TBzAniBackground.
	Also BzImgCache must have property ImgCollection set to certain
	TBzImgCollection component to work right. If You change property
	ImgCache [at run time], image used in previous ImgCache (if any) is
	unlocked and property ImgIndex is reset to -1 (no image).

* property ImgIndex : Integer;			<<<KEY>>>
	Set it to use certain image stored in ImgCache : TBzImgCache as
	background image. You may store image to BzImgCache by several ways,
	for example by using StoreImage method of TBzImgCache component.
	For more detailes look info for TBzImgCache component.

* property Options : TBackgroundOptions = Set of TBackgroundOption =
	(boTiled, boCenter, boStretch, boKeepRatio, boTransparent,
	boBlending25, boBlending50, boAnimate);
	- if boTiled is in Options then boCenter, boStretch, boKeepRatio
	  have no effect;
	- if boStretch is not in Options, boKeepRatio has no Effect;
	- if boStretch is in Options and boKeepRatio not, boCenter has no
	  effect;
	- boBlending25 and boBlending50 are exclusive. If not boBlending25
	  and not boBlending50 in Options then there are no blending even
	  BlendColor <> clNone.
	Default value is [ boTiled, boCenter, boStretch, boKeepRatio, 	boTransparent, boAnimate ]; (This equal to [ boTiled, boTransparent,
	boAnimate ], because boTiled cancels stretching and centering).
	You can change these options any time You wish.

* property BkColor : TColor;
	Set it to certain color to fill transparent areas of image used as
	background (if it was stored in cache as transparent). To avoid
	dirty output You have to use non-transparent images as background or
	set BkColor to other value then clNone (default).

* property ViewControl : TControl read fViewCtl write SetViewCtl;
	You can set it to simplify calculation of destination client area
	when work with BzAniBackground. You have to set it or at least set
	ViewRect property (see below) to use boCenter and boStretch options.
	Also if it is set, BzAniBackground does not generate OnChange events
	when given control is not visible.

* property ViewRect : TRect;
	If by some reasons You do not want to set ViewControl property but
	therefore want to use stretching and centering options, You have to
	provide this rectangle as alternative. If VewRect is set, it defines
	the destination area on client of certain control.

* property Width : Integer;
	Read it to knew image width (or frame width if image has frames).

* property Height : Integer;
	Read it to knew image height.

* property OnChange : TNotifyEvent;
	If set to custom event handler it will be called when image or frame
	is changed. Usually You use it to provide animation.

* property Rate : Integer;
	Animation speed rate. Default is 100. Change it (to 1..1000) to
	change animation speed for the whole set of frames.

* property BlendColor : TColor;
	Set it to draw image blended with given color (using blending style,
	defined by boBlending25, boBlending options). If neither boBlending25
	nor boBlending50 are in Options, there are no blending any way.

* property StdFrameInfo : Boolean;
	Tells to BzAniBackground to use standard info about frame (provided
	with my TBzRxGIF2Bmp component). Default value is True. If You set
	it to False, You have to use properties FrameDelays[], FrameRects[]
	to set such info for every frame in sequence. The "standard" is follow:
	pointer ImgData[], returened from BzImgCache, points to TBzAniFrames
	structure (defined in BzImgCach.pas unit):

   TBzAniFrameInfo = packed Record
      FrameDelay : Integer;
      FrameLeft, FrameTop, FrameWidth, FrameHeight : Integer;
   end;
   PBzAniFrameInfo = ^TBzAniFrameInfo;
   TBzAniFramesArray = array[ 0..{MaxInt}1 ] of TBzAniFrameInfo;
   PBzAniFramesArray = ^TBzAniFramesArray;

   TBzAniFrames = packed Record
      FramesCount : Integer;
      FramesInfo : TBzAniFramesArray;
   end;
   PBzAniFrames = ^TBzAniFrames;


-------------------------------------------------------------------------
Disclaimer of Warranty
----------------------

THIS SOFTWARE AND THE ACCOMPANYING FILES ARE PROVIDED "AS IS" AND
WITHOUT WARRANTIES OF ANY KIND WHETHER EXPRESSED OR IMPLIED.

In no event shall the author be held liable for any damages whatsoever,
including without limitation, damages for loss of business profits,
business interruption, loss of business information, or any other loss
arising from the use or inability to use  the software.
-------------------------------------------------------------------------

INSTALLATION.

I do not provide package to leave zip smaller. Create it by yourself or
use package containing TBzImgCollection and TBzImgCache component, add
BzAniBackgroundReg.pas there and compile/install it.

This component is FREE to use by any way. But if You want to get source
You may get it (and source of TBzConvGIF2Bmp, TBzImgCache, TBzImgCollection
together with this) by purchasing it. How to purhcase - look info for
TBzImgCollection component.

Mail: bonanzas@online.sinor.ru
Web: http://members.xoom.com/mr_bonanzas
