Inno Setup 自定义界面心得

Stella981
• 阅读 1396

因为项目需要,需要打 windows 安装包,要求安装界面完全按照需求来。作为没接触过这块儿的服务端宝宝,在此期间踩了很多坑。

坑不提也罢,最终结果圆满,记录下与大部分网上PO出来的做法不太一样的小心得,备忘。

网上搜到的自定义界面,都用的 botva2.dll ,我没用。应该说,用过,但遇到了图片变形的问题,短时间内没解决,所以最后全都用的 Inno Setup 原生类。Inno Setup 官方文档很详细,而且开源,所以原生用起来还是很顺利的。此前没接触过 Pascal 语言,但影响不大。

加载透明图片或按钮

网上多用 botva2.dll 来加载 png 图片,以达到圆角效果。由于遇到图片变形,我开始在官方文档里找替代方案。

Inno Setup 本身提供一个类 TBitmapImage 来支持带 alpha 通道的bmp 图片,也就是 32 位的 bmp 图片,支持透明效果。PhotoShop 中可通过添加 alpha 通道来生成 32 位 bmp 图。

显示图片方法:

val BmpImg : TBitmapImage;

BmpImg := TBitmapImage.Create(WizardForm); // 卸载时将 WizardForm 换为 UninstallProgressForm 即可
with BmpImg do
begin
    Parent := WizardForm;                  // 卸载时将 WizardForm 换为 UninstallProgressForm 即可
    Bitmap := TAlphaBitmap.Create;  
    Bitmap.AlphaFormat := afDefined;       // 须设置此值,才能读取图片的 alpha 通道,应在加载图片文件前设置
    Bitmap.LoadFromFile(ExpandConstant('{tmp}\xxx.bmp'));
    BackColor := clNone;                   // 背景色应设置为 clNone,否则默认透明处为白色    OnClick := @some_procedure;            // 按钮的点击回调,非按钮图片不需要
end;

按钮的点击回调形如:procedure some_procedure(sender: TObject);

设置 BmpImg.Enabled := False 可使图片的点击事件失效。

富文本

Inno Setup 的类 TRichEditViewer 支持 .rtf 格式的富文本内容,可用于显示许可协议或其他说明文档,使用如下:

val RichViewer : TRichEditViewer;    RichText : AnsiString;
LoadStringFromFile(ExpandConstant('{tmp}\xxx.rtf'), RichText);  // 读取文件内容至 RichText
RichViewer := TRichEditViewer.Create(WizardForm); // 卸载时将 WizardForm 换为 UninstallProgressForm 即可
with RichViewer do
begin
    Parent := WizardForm;                         // 卸载时将 WizardForm 换为 UninstallProgressForm 即可    ReadOnly := true;                             // 只读    SCROLLBARS := ssVertical;                     // 滚动条类型    BorderStyle := bsNone;                        // 边框类型    RTFText := licenseText;                       // 内容    UseRichEdit := True;                          // 须设置此值为 True,才会按照富文本方式读取内容
end;

获取磁盘空间

界面上需要显示所需磁盘空间和剩余磁盘空间。

所需磁盘空间,WizardForm.DiskSpaceLabel 中有对所需磁盘的描述,可以将此描述通过 [Messages] 段设置 "DiskSpaceMBLabel=[mb]" 使之只剩下所需磁盘大小。然后通过 WizardForm.DiskSpaceLabel.Caption 可获得所需磁盘大小,字符串类型(如 "10.3" ),单位MB。

剩余磁盘空间,调用 Inno Setup 提供的 GetSpaceOnDisk 函数即可,将第一个参数设置为安装所在磁盘号,如 "C:" 。

例子:

[Messages]
DiskSpaceMBLabel=[mb][Code]function GetSpaceNeeded();     // 返回所需磁盘空间,字符串类型 "10.3",单位MB  begin    Result := WizardForm.DiskSpaceLabel.Caption;  end;function GetSpaceLeft();       // 返回剩余空间大小,整数类型,单位MB  var freeDiskSpace, totalDiskSpace : Cardinal;  begin    GetSpaceOnDisk(Copy(WizardForm.DirEdit.text, 1, 2), true, freeDiskSpace, totalDiskSpace)    Result := freeDiskSpace  end;

进度条

引入了外部依赖 user32.dll 的 SetTimer 来设置定时器,InnoCallback.dll 的 wrapcallback 来封装函数。其中 user32.dll 为操作系统自带,InnoCallback.dll 需要自行下载。

在安装或卸载进度变化的时候,WizardForm.ProgressGauge 和 UninstallProgressForm.ProgressBar 中的值会相应变化,定时读取其中的值即可实现实时进度变化。

例子:

type
  TTimerProc = procedure(h:longword; msg:longword; idevent:longword; dwTime:longword);
      
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall delayload';function TimerCallBack(P: TTimerProc; ParamCount: integer):LongWord; external 'wrapcallback@{%TEMP}\InnoCallback.dll stdcall delayload'; procedure RefreshProgressBar(h, AMsg, IdEvent, dwTime: LongWord);  // 刷新进度条  var    i1, i2 : integer;  begin     i1 := WizardForm.ProgressGauge.Position - WizardForm.ProgressGauge.Min;     // 卸载时 WizardForm.ProgressGauge 应替换为 UninstallProgressForm.ProgressBar    i2 := WizardForm.ProgressGauge.Max - WizardForm.ProgressGauge.Min;          // 卸载时 WizardForm.ProgressGauge 应替换为 UninstallProgressForm.ProgressBar    ProgressImg.Width := Round(i1 * TotalWidthOfProgressImg / i2);  end;procedure CurPageChanged(CurPageID: Integer);  begin    if CurPageID = wpInstalling then                        // 安装时在 wpInstalling 页面调用定时器      begin        SetTimer(0, 0, 10, TimerCallBack(@TimerProc, 4));      end;  end;procedure InitializeUninstallProgressForm();                // 卸载时在 InitializeUninstallProgressForm 中调用定时器  begin    SetTimer(0, 0, 10, TimerCallBack(@TimerProc, 4));  end;

其他

1、安装界面中要用到的图片和资源,在 [Files] 段中应放到前面,因为安装程序读取资源时会先解压排在该资源前的所有文件。如果安装包界面资源在应用文件后面,安装界面打开会很慢很慢很慢很慢。

2、去掉关闭安装程序的二次确认框:

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
  begin               
    Confirm := False;   
  end;

3、手动触发下一步

WizardForm.NextButton.OnClick(WizardForm)
点赞
收藏
评论区
推荐文章
捉虫大师 捉虫大师
2年前
大厂偏爱的Agent技术究竟是个啥
搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。hello大家好,我是小楼,今天给大家分享一个关于Agent技术的话题,也是后端启示录的第3篇文章。通过本文你可以了解到如下内容:什么是Agent技术为了解释什么是Agent技术,我在网上搜了一圈,但没有找到想要的结果。反倒是搜到了不少JavaAgent技术,
九路 九路
3年前
iOS 图片和文字一起上传
最近在忙着开发公司的一个项目,中间遇到很多坑,对于图片的上传在这里我也不做太多的介绍,网上各种大神的资料都有的,今天我主要说一下我再上传图片和文字的时候遇到的一些坑(图文上传我们很多时候都会遇到,遇到多了网上找的各种博客,解决了图文一起上传的问题)废话不多说,直接上代码:/上传图文/(void)upLoadImageViewToS
九路 九路
3年前
Swift版UITextView自定义占位词,最大长度
最近这段时间在搞一个Swift的项目,算是帮朋友做的吧,虽然有点累但是自己也是从中学到了很多东西,其中自己也封装了一些常用的控件,最近忙完公司的项目以后就整理一下自己的心得。。希望大家一起学习!最近项目需要,很多的地方都用到了UITextView来实现一些需求,需要设置占位词和最大的长度,这里我是简单的封装了一下,希望大家多多指正,话不多说,上代码:
Wesley13 Wesley13
3年前
C# 调用C++的dll 那些事
    之前从来没搞过C,最近被安排的任务需要调用C的接口,对于一个没用过Dependency的小白来说,原本以为像平时的Http接口那样,协议,端口一定义,方法参数一写就没事,结果踩了无数的坑。现在从0基础开始记录。A发了一个SDK文件夹过来,先不管cpp、h、lib五花八门的后缀文件,直接看文档说明,表明需要调哪些方法。网上简单的查阅下
Stella981 Stella981
3年前
Egret白鹭开发小游戏之自定义load加载界面
刚接触不久就遇到困难自定义loading。想和其他获取图片方式一样获取加载界面的图片,结果发现资源还没加载就需要图片,在网上百度了许多,都没有找到正确的方式,通过自己的摸索,终于,,,我成功了。。。下面介绍一下主要思想:首先,我们需要使用异步加载的方式,在加载界面之前加载loading界面需要的素材,然后再loadingUI中就可以大胆使
Stella981 Stella981
3年前
Groovy防PermOOM与OldOOM心得
作为Groovy重度用户,踩了新版本因为无法unloadclass导致permoom的坑,踩了classLoader.parallelLockMap不断添加新锁导致oldoom的坑。本文的意图就是记录一点埋坑心得。踩坑详情可见:https://my.oschina.net/chenxiaojie/blog/835934(https://my.o
Stella981 Stella981
3年前
CentOS上安装配置Python3.7
其实安装python3.7本身很容易,并没有什么困难,主要是安装pip的时候遇到了好多问题。下面就说一下我具体踩过的坑,以及解决的办法。具体的安装步骤网上有非常非常多。参考:https://blog.csdn.net/u013214212/article/details/81540840完全照着这个里面的步骤做,就一点问题没有。不过为了防止意外情况,
Stella981 Stella981
3年前
Eureka管理界面自定义(Greenwich版)
Eureka管理界面自定义开发工具:SpringToolSuite4Springcloud版本:Greenwich.SR2,近来公司用Eureka来做服务管理,要把服务端的界面增加些自己公司的属性上去,我简单的记录下修改的过程,过程如:构建Eureka项目创建Eureka
Wesley13 Wesley13
3年前
Java避坑宝典《Java业务开发常见错误100例》上线了
写这个专栏的缘起之前我写过一篇博客:《朱晔的互联网架构实践心得S2E2:写业务代码最容易掉的10种坑》,引起的关注还是挺多的。后来和极客时间的编辑一拍即合决定以这个为题写一个专栏。其实所谓坑就是容易忽略但是不容易发现的问题,大部分生产事故都是发布、运维相关的配置引起,真正代码中的问题上线后产生问题的坑并不多,虽然我接触过很多生产事故,但
IDEA工具第二篇:自定义Java方法注释模板 | 京东云技术团队
网上搜索类似的文章有很多,但是一味的复制粘贴总会出现各种奇葩问题,最后然并卵!今天特意自己研究琢磨一下,将最终结果分享给大家,100%亲测可用。一、说明想必大家都用过Eclipse的方法注释生成,方法上输入/,回车走你,巴拉巴拉如下的注释便生成了,今天就悄