原文
一个如影随形的小精灵会令到你的安装程序更加人性化. 就是这样一个功能的插件, 希望大家喜欢. ^_^
Ver2.0 版本: 采用 GDI+ 来处理图片, 所以支持多种类型(bmp, jpg, gif, png, tiff, emf)图片. 并且插件大小缩小为 49KB.
注:插件在 Win2000 以上系统有效.
引用来自 fairy.iss
;精灵插件 ver 2.0[Files]Source: "fairy.dll"; Flags: dontcopy[code]type TAddingFinishCallbackProc = procedure(FrameCount: Integer); TPlayFinishCallbackProc = procedure();function InitFairy(hParentWnd: HWND; RelativePos: Integer; Interval: Cardinal): Boolean;external 'InitFairy@files:fairy.dll stdcall';// 初始化精灵插件:// hParentWnd: 需要粘附的窗口句柄, 精灵会跟随这个窗口移动.// RelativePos: 精灵跟随窗口移动的相对位置.// 0: 以窗口左上角为原点, 所有制定的 X, Y 坐标都是相对于该原点的距离.// 1: 以窗口右上角为原点.// 2: 以窗口左下角为原点.// 3: 以窗口右下角为原点.// Interval: 每个图片更新的速度(时间间隔, 单位: ms). 用来微调动作的快慢. 但是动作演示的快慢主要还是由制定图片序列的时候处理,// 例如 100ms 下的更新速度是比较合理的, 也就是 1 秒钟更新 10 张图片. 所以在制定动作的时候以这个作为参考就好处理了.function AddImgsToList(BmpFiles: AnsiString; FinishCallback: TAddingFinishCallbackProc): Boolean;external 'AddImgsToList@files:fairy.dll stdcall';// 添加图片到精灵插件中.// BmpFiles: 批量图片处理的序列.// 格式: X1|Y1|BlendAlpha1|TransparentColor1|ImgFile1|X2|Y2|BlendAlpha2|TransparentColor2|ImgFile2|X3|Y3|BlendAlpha3|TransparentColor3|ImgFile3|.........// X: 相对于原点的水平坐标.// Y: 相对于原点的垂直坐标.// BlendAlpha: 精灵的整体透明程度. 不同于图片自身的透明通道, 即使图片有自身的 Alpha 通道,// 不透明的部分仍然会受 BlendAlpha 的影响.// TransparentColor: 透明颜色. 当图片没有 Alpha 通道的时候, 就会由该颜色定义透明部分.// ImgFile: 图片文件. 因为改用 GDI+ 作为精灵的图片引擎, 所以将会支持多种(bmp, gif, tiff, emf, jpg)图片格式.// 当图片带有 Alpha 通道的时候, 将会按照通道来调整图片透明度, 当没有 Alpha 通道的时候, 就会按照 TransparentColor// 来定义透明部分. 另外, 对于 GIF, 如果属于动画的多帧图片, 精灵将会在载入时自动把图片分帧载入.// 所以将会非常方便精灵的制作.// FinishCallback: 因为批量添加大量图片可能会引起程序假死, 所以我采用线程处理, 所以在载入图片的过程中, 安装程序仍然可以同步运行.// 所以 FinishCallback 就是添加图片过程完成的时候调用的回调函数, 通常都是在这个函数中调用 AnimateFairy 来运行精灵.function AddImgToList(X, Y: Integer; BlendAlpha: Byte; TransparentColor: Integer; ImgFile: AnsiString): Integer;external 'AddImgToList@files:fairy.dll stdcall';// 添加图片到精灵插件中.// 属于单图片添加, 基本上这个函数只是给用户在程序中灵活运用而已, 上一函数已能完成此任务.// 参数请参看上一函数中的解释.function ClearImgList(): Boolean; external 'ClearImgList@files:fairy.dll stdcall';// 清除图片序列中的所有图片.// 因为图片是顺序添加到序列中的, 所以如果需要重新排列图片, 必须清除所有图片, 重新添加.function AnimateFairy(IndexList: AnsiString; FinishCallback: TPlayFinishCallbackProc): Boolean;external 'AnimateFairy@files:fairy.dll stdcall';// 运行精灵, 也就是相当于序列图片的连续显示.// IndexList: 播放序列, 具体的使用方法请看以下几个例子.// 例子:// 0-53,(54-79)// 解释: 0 到 53 帧, 然后 54 到 79 帧循环播放, 无限循环, 不会结束, 也就是说不会触发 FinishCallback 事件.// 0-53,3(54-79)// 解释: 具体跟上一例子的差别是 54 到 79 帧循环播放 3 次后结束, 并调用 FinishCallback 回调函数.// 10-2,13,45,60,54,2(70-0),(50-70)// 解释: 10 到 2 帧倒序播放, 然后顺序显示 13,45,60,54 帧, 然后倒序循环播放 2 次 70 到 0 帧, 再然后无限循环播放 50 到 70 帧.// FinishCallback: 如果播放序列没有无限循环, 则在结束播放后, 就会调用这个回调函数.function StopFairy(): Boolean; external 'StopFairy@files:fairy.dll stdcall';// 停止播放.function ResumeFairy(): Boolean; external 'ResumeFairy@files:fairy.dll stdcall';// 显示并恢复播放.function HideFairy(): Boolean; external 'HideFairy@files:fairy.dll stdcall';// 隐藏并停止播放.function ShowFairy(): Boolean; external 'ShowFairy@files:fairy.dll stdcall';// 显示精灵.function ShowFairyEx(ImgIndex: Integer): Boolean; external 'ShowFairyEx@files:fairy.dll stdcall';// 显示某一帧的精灵.procedure UninitFairy(); external 'UninitFairy@files:fairy.dll stdcall';// 解除精灵插件.// 精灵虽然会显示在主窗口的上面, 但是并不会遮挡鼠标的操作, 即使精灵下有一个按钮, 鼠标仍然可以穿透精灵点击后面的按钮.// 但是对于非主窗口的其他窗口, 鼠标操作并不能穿透.
引用来自 Example.iss
#include "fairy.iss"// 这是一个令到你的安装程序更加人性化的插件.// 注释或取消注释下面的 ImgType 定义, 可以选择不同的图片类型作为精灵插件的显示.// 具体图片处理的区别请参阅 fairy.iss 函数定义中的解释.#define ImgType 0//#define ImgType 1//#define ImgType 2[Setup]AppName=fairyAppVerName=fairy Ver 2.0DefaultDirName={pf}\fairyDefaultGroupName=fairyOutputDir=userdocs:Inno Setup Examples OutputOutputBaseFilename=setupSolidCompression=yes[Files]#if ImgType == 0; 带 Alpha 通道的 32bit 位图 BitmapSource: "bmp_32bit_Alpha\*.bmp"; Flags: dontcopy#elif ImgType == 1; 普通位图 BitmapSource: "bmp\*.bmp"; Flags: dontcopy#elif ImgType == 2; PNGSource: "png\*.png"; Flags: dontcopy#endif[code]function GetSysColor(nIndex: Integer): DWORD; external 'GetSysColor@user32.dll stdcall';function GetSystemMetrics(nIndex: Integer): Integer; external 'GetSystemMetrics@user32.dll stdcall';const SM_CYBORDER = 6; SM_CYDLGFRAME = 8;function ColorToRGB(Color: TColor): Longint;begin if Color < 0 then Result := GetSysColor(Color and $000000FF) else Result := Color;end;procedure FinishPlayCallback();begin MsgBox('FinishPlay', mbInformation, MB_OK);end;procedure PlayListCallback2(FrameCount: Integer);begin AnimateFairy('0-53,2(54-79)', @FinishPlayCallback);end;procedure PlayListCallback(FrameCount: Integer);begin// ShowFairyEx(10); AnimateFairy('0-53,(54-79)', nil);end;procedure BtnOnClick(Sender: TObject);var i, BAlpha, TransparentColor: Integer; x, y: Integer; ImgFile: AnsiString; S: AnsiString; BH: Integer;begin ClearImgList; InitFairy(WizardForm.Handle, TNewButton(Sender).Tag, 100); S := ''; BH := GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYDLGFRAME); if TNewButton(Sender).Caption = '4' then begin x := 180; y := -88-BH; end else case TNewButton(Sender).Tag of 0: begin x := 80; y := -88; end; 1: begin x := -170; y := -88; end; 2: begin x := 80; y := -88-BH; end; 3: begin x := -170; y := -88-BH; end; end; BAlpha := 30; TransparentColor := ColorToRGB(clFuchsia); for i := 0 to 7 do begin#if ImgType == 2 ImgFile := format('%.2d',[i+1])+'.png';#else ImgFile := format('%.2d',[i+1])+'.bmp';#endif if S <> '' then S := S + '|'; S := S + IntToStr(x) + '|' + IntToStr(y) + '|' + IntToStr(BAlpha) + '|' + IntToStr(TransparentColor) + '|' + ExpandConstant('{tmp}\'+ImgFile); BAlpha := BAlpha + 30; end; for i := 8 to 79 do begin#if ImgType == 2 ImgFile := format('%.2d',[i+1])+'.png';#else ImgFile := format('%.2d',[i+1])+'.bmp';#endif if S <> '' then S := S + '|'; S := S + IntToStr(x) + '|' + IntToStr(y) + '|' + IntToStr(255) + '|' + IntToStr(TransparentColor) + '|' + ExpandConstant('{tmp}\'+ImgFile); end; if TNewButton(Sender).Caption = '4' then AddImgsToList(S, @PlayListCallback2) else AddImgsToList(S, @PlayListCallback);end;procedure InitializeWizard();var Btn: TNewButton; ImgFile: AnsiString; i: Integer;begin for i := 0 to 79 do begin#if ImgType == 2 ImgFile := format('%.2d',[i+1])+'.png';#else ImgFile := format('%.2d',[i+1])+'.bmp';#endif ExtractTemporaryFile(ImgFile); end; WizardForm.BorderIcons := [biSystemMenu,biMinimize,biMaximize]; WizardForm.BorderStyle := bsSizeable; WizardForm.WelcomeLabel2.Caption := '尝试改变窗口大小, 可以测试精灵插件对于窗口的相对位置的效果.'+#13#10 '按钮0: 以窗口左上角做原点. 0-53,(54-79) 无限循环.'+#13#10 '按钮1: 以窗口右上角做原点. 0-53,(54-79) 无限循环.'+#13#10 '按钮2: 以窗口左下角做原点. 0-53,(54-79) 无限循环.'+#13#10 '按钮3: 以窗口右下角做原点. 0-53,(54-79) 无限循环.'+#13#10 '按钮4: 以窗口左下角做原点. 0-53,2(54-79) 循环 2 次结束.'; with TNewButton.Create(WizardForm) do begin Parent := WizardForm.WelcomePage; SetBounds(ScaleX(216), ScaleY(207), ScaleX(19), ScaleY(23)); Caption := '0'; Tag := 0; OnClick := @BtnOnClick; end; Btn := TNewButton.Create(WizardForm); with Btn do begin Parent := WizardForm.WelcomePage; SetBounds(ScaleX(240), ScaleY(207), ScaleX(19), ScaleY(23)); Caption := '1'; Tag := 1; OnClick := @BtnOnClick; end; with TNewButton.Create(WizardForm) do begin Parent := WizardForm.WelcomePage; SetBounds(ScaleX(264), ScaleY(207), ScaleX(19), ScaleY(23)); Caption := '2'; Tag := 2; OnClick := @BtnOnClick; end; with TNewButton.Create(WizardForm) do begin Parent := WizardForm.WelcomePage; SetBounds(ScaleX(288), ScaleY(207), ScaleX(19), ScaleY(23)); Caption := '3'; Tag := 3; OnClick := @BtnOnClick; end; with TNewButton.Create(WizardForm) do begin Parent := WizardForm.WelcomePage; SetBounds(ScaleX(368), ScaleY(207), ScaleX(19), ScaleY(23)); Caption := '4'; Tag := 2; OnClick := @BtnOnClick; end; BtnOnClick(Btn);end;procedure DeinitializeSetup();begin HideFairy; WizardForm.Hide; UninitFairy;end;
下载地址: