文章目录
-
-
- 一、前言
- 二、最终效果
- 三、GitHub工程
- 四、实现原理
- 五、界面美化逻辑实现
-
- 1、资源目录
- 2、创建文本
- 3、创建按钮
- 4、创建背景图
- 5、启动定时器
- 6、创建输入编辑框
- 7、设置UI对象显示与隐藏
- 8、监听安装进度
- 六、Demo工程具体使用
-
- 1、中文支持
- 2、放exe程序文件
- 3、放界面图片素材
- 4、使用
- 七、补充:iss脚本基础知识
-
- 1、[Setup]
- 2、[Languages]
- 3、[Tasks]
- 4、[Files]
- 5、[Icons]
- 6、[Run]
- 7、[Registry]
- 8、[Code]
- 八、补充2:Pascal语法简单介绍
-
- 1、数据类型
-
- 1.1、整型数据
- 1.2、实型数据
- 1.3、字符类型
- 1.4、布尔类型
- 1.5、CONST常量
- 2、赋值语句
- 3、if语句
- 4、case语句
- 5、for循环语句
- 6、while循环语句
- 7、引用其他脚本
- 8、define常量与应用
-
一、前言
之前我写过一篇《Unity发布PC版,使用Inno Setup制作安装程序》,建议先看那一下那篇文章。今天,我要讲讲通过
二、最终效果
如下,效果还可以吧,觉得不错的可以点个赞~

三、GitHub工程
本文的

四、实现原理
首先,你需要安装
界面的美化,主要是调用两个美化插件动态库:
点击下载InnoCallback.dll
点击下载botva2.dll
五、界面美化逻辑实现
美化界面用到了
1 | #include "DllsImport.iss" |
1、资源目录
界面资源放在

2、创建文本
接口:
1 | function TLabel.Create(hParent:HWND):TLabel |
例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var lblWelcome:TLabel; begin lblWelcome := TLabel.Create(WizardForm); with lblWelcome do begin Parent := WizardForm; Caption := '欢迎安装XXX应用程序'; Transparent := true; Font.Size:= 20 Font.Name:='黑体' Font.Color:=$ffffff Left := DpiScale(190); Top := DpiScale(195); end; end; |
3、创建按钮
接口
1 2 3 4 5 | function BtnCreate(hParent:HWND; Left,Top,Width,Height:integer; FileName:PAnsiChar; ShadowWidth:integer; IsCheckBtn:boolean):HWND; |
例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | var btnOneKey:HWND; BtnOneKeyFont:TFont; begin // 创建按钮 btnOneKey:=BtnCreate(WizardForm.Handle,DpiScale(240),DpiScale(260),DpiScale(177), DpiScale(43), ExpandConstant('{tmp}\btnOneKeyInstall.png'), 1, False); //设置按钮文字 BtnSetText(btnOneKey, '一键安装'); //文字字体 BtnOneKeyFont:= TFont.Create; with BtnOneKeyFont do begin Size := 20; Name:='黑体'; Color:=$ffffff; end; //应用字体 BtnSetFont(btnOneKey, BtnOneKeyFont.Handle); BtnSetFontColor(btnOneKey,$FAFAFA,$FFFFFF,$FFFFFF,$FFFFFF); //设置按钮点击函数 BtnSetEvent(btnOneKey, BtnClickEventID, WrapBtnCallback(@btnOneKey_OnClick,1)); end; // 按钮点击回调 procedure btnOneKey_OnClick(hBtn:HWND); begin WizardForm.NextButton.OnClick(WizardForm); WizardForm.NextButton.OnClick(WizardForm); end; |
4、创建背景图

1 2 3 4 5 6 7 8 9 10 11 12 13 | var imgBg1:Longint; winW:integer; winH:integer; begin //窗口宽高 winW:=DpiScale(660) winH:=DpiScale(480) //创建背景图 imgBg1 := ImgLoad(WizardForm.Handle, ExpandConstant('{tmp}\bg.png'), (0), (0), winW, winH, True, True); //设置背景图的隐藏 //ImgSetVisibility(imgBg1, false); end |
5、启动定时器
接口
1 | function SetTimer(hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; |
例:
通过定时器轮播背景图
1 2 3 4 5 6 | SetTimer(0, 0, 50, WrapTimerProc(@PageInstall_TimerProc, 4)); procedure PageInstall_TimerProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord); begin //轮播背景图逻辑 end |
6、创建输入编辑框

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | begin edtSelectDir1 := TEdit.Create(WizardForm); with edtSelectDir1 do begin Parent:= WizardForm; Text := WizardForm.DirEdit.Text; Font.Size:= 10 Font.Color:=$555555 Left:= DpiScale(132); Top := DpiScale(189); Width:= DpiScale(311); Height:= DpiScale(24); BorderStyle:=bsNone; TabStop := false; OnChange:=@EdtSelectDir1_EditChanged; end; end |
7、设置UI对象显示与隐藏
1 2 3 4 5 6 7 | //隐藏按钮 BtnSetVisibility(btn, false); //隐藏图片 ImgSetVisibility(imgBig, false); //隐藏文本TLabel、隐藏输入框TEdit TconSetVisible(lbl, false); TconSetVisible(edt, false); |
8、监听安装进度
用到了
1 2 | function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external '[email protected] stdcall'; |
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //设置监听 PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4, PBCallBack(@PBProc,4)); //回调 function PBProc(h:hWnd;Msg, wParam,lParam:Longint):Longint; var pr, pos,total: Longint; w : integer; begin // CallWindowProc是将消息信息传送给指定的窗口过程的函数 Result:=CallWindowProc(PBOldProc, h, Msg, wParam,lParam); if (Msg=$402) and (WizardForm.ProgressGauge.Position > WizardForm.ProgressGauge.Min) then begin pos:=WizardForm.ProgressGauge.Position-WizardForm.ProgressGauge.Min; total:=WizardForm.ProgressGauge.Max-WizardForm.ProgressGauge.Min; pr:=pos*100/total; //更新进度条 PageInstall_SetProgress(pr); Notify_DoNotifyProgress(pos, total); end; end; |
六、Demo工程具体使用
1、中文支持
为了支持
点击查看ChineseSimplified.isl
需将

2、放exe程序文件
将要打包的程序文件放在

1 2 | #define MyAppPkgDir ".\pkgs\v1" #define MyAppExeName "我的应用.exe" |
3、放界面图片素材
界面素材放在

在
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 将tmp的资源, 解压到安装运行时搞出来的临时目录 ExtractTemporaryFile('bg.png'); ExtractTemporaryFile('bg2.png'); ExtractTemporaryFile('btclose.png'); ExtractTemporaryFile('btmin.png'); ExtractTemporaryFile('btn.png'); ExtractTemporaryFile('btnOneKeyInstall.png'); ExtractTemporaryFile('check.png'); ExtractTemporaryFile('progress.png'); ExtractTemporaryFile('progressBg.png'); for i := 1 to InsBgAni_ImgCount do ExtractTemporaryFile(Format('pic%d.png',[i]) ); |
4、使用
用

执行脚本(按

生成的

七、补充:iss脚本基础知识
我们通过上一篇的教程(点击查看),可以生成一个
建议过程中可以翻翻
我们的
1 2 3 4 5 6 7 8 | [Setup] [Languages] [Tasks] [Files] [Icons] [Run] [Registry] [Code] |
1、[Setup]
这个段包含用于安装程序和卸载程序的全局设置。
例
1 2 3 4 5 6 7 | [Setup] AppId=123456789 AppName="我的应用" AppVersion=1.5 AppPublisher="公司名" DefaultDirName={<!-- -->autopf}\My Program DefaultGroupName=My Program |
2、[Languages]
语言文件是

然后在脚本中指明语言文件。
1 2 | [Languages] Name: "chs"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" |
哪里下载这个
3、[Tasks]
它定义安装程序在执行安装期间所有由用户定制的任务。这些任务以选项框和单选项形式在附加任务向导页中出现。
例:
1 2 3 | [Tasks] Name: "desktopicon"; Description: "创建桌面快捷方式"; GroupDescription: "添加快捷方式:"; Flags: checkedonce Name: "quicklaunchicon"; Description: "创建快速运行栏快捷方式"; GroupDescription: "添加快捷方式:"; Flags: checkedonce |
4、[Files]
定义安装程序要安装在用户系统上的任何文件。
例:
1 2 3 4 5 | [Files] Source: "CTL3DV2.DLL"; DestDir: "{sys}"; Flags: onlyifdoesntexist uninsneveruninstall Source: "MYPROG.EXE"; DestDir: "{app}" Source: "MYPROG.CHM"; DestDir: "{app}" Source: "README.TXT"; DestDir: "{app}"; Flags: isreadme |
5、[Icons]
定义所有创建在开始菜单或其它位置 (比如桌面) 的快捷方式。
例:
1 2 3 | [Icons] Name: "{group}\My Program"; Filename: "{app}\MYPROG.EXE"; WorkingDir: "{app}" Name: "{group}\Uninstall My Program"; Filename: "{uninstallexe}" |
6、[Run]
用来指定程序完成安装后要执行的程序。
例:
1 2 | [Run] Filename: "{app}\MYPROG.EXE"; Description: "Launch application"; Flags: postinstall nowait skipifsilent unchecked |
7、[Registry]
定义安装程序在用户系统上创建、修改或删除的任何注册表项/值。
例:
1 2 3 4 | [Registry] Root: HKLM; Subkey: "Software\My Company"; Flags: uninsdeletekeyifempty Root: HKLM; Subkey: "Software\My Company\My Program"; Flags: uninsdeletekey Root: HKLM; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" |
其中
1 2 3 4 5 | HKCU (HKEY_CURRENT_USER) HKLM (HKEY_LOCAL_MACHINE) HKCR (HKEY_CLASSES_ROOT) HKU (HKEY_USERS) HKCC (HKEY_CURRENT_CONFIG) |
8、[Code]
最重头的部分来了,
八、补充2:Pascal语法简单介绍
1、数据类型
1.1、整型数据
| 类型 | 数值范围 | 占字节数 | 格式 |
|---|---|---|---|
| shortint | -128 ~ 128 | 1 | 带符号 8 位 |
| inteter | -32768 ~ 32767 | 2 | 带符号 16 位 |
| longint | -2147483648 ~ 2147483647 | 4 | 带符号 32 位 |
| byte | 0 ~ 255 | 1 | 带符号 8 位 |
| word | 0 ~ 65535 | 2 | 带符号 16 位 |
例:
1 2 3 4 5 | var age:shortint; begin age:=18; end; |
1.2、实型数据
| 类型 | 占字节数 | 有效位数 |
|---|---|---|
| single | 4 | 7~8 |
| real | 6 | 11~12 |
| double | 8 | 15~16 |
| extended | 10 | 19~20 |
| comp | 8 | 19~20 |
例:
1 2 3 4 5 | var a:single; begin a:=1.3; end; |
1.3、字符类型
例:
1 2 3 4 5 6 7 | var a:String; b:String; begin a:="hello world"; b:=format('字符串拼接:%s', a); end; |
1.4、布尔类型
例:
1 2 3 4 5 | var a:boolean; begin a:=true; end; |
1.5、CONST常量
例:
1 2 3 | const pi=3.14159; zero=0; |
2、赋值语句
变量名:=表达式;
例:
1 | a:="hello world"; |
3、if语句
例:
1 2 3 4 | if x>y then a:="big" else a:="small"; |
4、case语句
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var month,days:integer; begin write('Input month:'); readln(month); case month of 1,3,5,7,8,10,12: days:=31; 4,6,9,11: days:=30; 2: days:=28; else days:=0; end; end; |
5、for循环语句
例:
求
1 2 3 4 5 6 7 8 9 10 11 | var n,i:integer; s:longint; begin write('Enter n='); readln(n); s:=1; for i:=2 to n do s:=s*i; writeln(n, '的阶乘为:', s); end; |
6、while循环语句
例:
1 2 3 4 5 6 7 8 9 | var a,:integer; begin a:=10; while a>0 do begin a:=a-1; end; end; |
7、引用其他脚本
1 | #include "DllsImport.iss" |
8、define常量与应用
1 2 3 | #define MyAppName "我的应用名" [Setup] AppName={<!-- -->#MyAppName} |