一、前言
之前我写过一篇《Unity发布PC版,使用Inno Setup制作安装程序》,建议先看那一下那篇文章。今天,我要讲讲通过InnoSetup
如何实现Setup
安装程序的界面美化。
二、最终效果
如下,效果还可以吧,觉得不错的可以点个赞~
@H_502_133@
三、GitHub工程
本文的Demo
我已上传到GitHub
,感兴趣的同学可以下载下来学习,觉得不错的话,记得给个星星~GitHub
工程地址:https://github.com/linxinfa/Beautiful-InnoSetup-Demo
四、实现原理
首先,你需要安装InnoSetup
。InnoSetup
下载地址:https://jrsoftware.org/isinfo.php
InnoSetup
通过 Pascal Scripting: Event Functions
这种事件机制,把流程节点的控制交给Pascal Script
,使其可以控制上一步、下一步等等的操作。
界面的美化,主要是调用两个美化插件动态库:botva2.dll
和 InnoCallback.dll
。用其来控制贴图的位置和样式,和给按钮绑定相应的事件等等的。
点击下载InnoCallback.dll
点击下载botva2.dll
五、界面美化逻辑实现
美化界面用到了botva2.dll
。需要引入DllsImport.iss
。
#include "DllsImport.iss"
1、资源目录
界面资源放在res/tmp
目录中,包括我们引用的两个dll
:botva2.dll
、InnoCallback.dll
2、创建文本
接口:
function TLabel.Create(hParent:HWND):TLabel
例:
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、创建按钮
接口
function BtnCreate(hParent:HWND;
Left,Top,Width,Height:integer;
FileName:PAnsiChar;
ShadowWidth:integer;
IsCheckBtn:boolean):HWND;
例:
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);
//设置按钮点击函数
BtnSetEvent(btnOneKey, BtnClickEventID, WrapBtnCallback(@btnOneKey_OnClick,1));
end;
// 按钮点击回调
procedure btnOneKey_OnClick(hBtn:HWND);
begin
WizardForm.NextButton.OnClick(WizardForm);
WizardForm.NextButton.OnClick(WizardForm);
end;
4、创建背景图
var
imgBg1:Longint;
winW:integer;
winH:integer;
begin
//窗口宽高
winW:=DpiScale(660)
winH:=DpiScale(480)
//创建背景图
imgBg1 := ImgLoad(WizardForm.Handle, ExpandConstant('{tmp}\bg.png'), (0), winW, winH, True, True);
//设置背景图的隐藏
//ImgSetVisibility(imgBg1,false);
end
5、启动定时器
接口
function SetTimer(hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord;
例:
通过定时器轮播背景图
SetTimer(0, 0, 50, WrapTimerProc(@PageInstall_TimerProc, 4));
procedure PageInstall_TimerProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
//轮播背景图逻辑
end
6、创建输入编辑框
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对象显示与隐藏
//隐藏按钮
BtnSetVisibility(btn, false);
//隐藏图片
ImgSetVisibility(imgBig, false);
//隐藏文本TLabel、隐藏输入框TEdit
TconSetVisible(lbl, false);
TconSetVisible(edt, false);
8、监听安装进度
用到了Windows
的API
。
function SetwindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint;
external 'Setwind[email protected] stdcall';
例:
//设置监听
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,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、中文支持
为了支持setup
程序显示中文,需要配置中文语言文件:ChineseSimplified.isl
点击查看ChineseSimplified.isl
需将ChineseSimplified.isl
放在InnoSetup
安装目录中的Languages
目录中。
2、放exe程序文件
将要打包的程序文件放在pkgs
目录中,如下放在pkgs/v1
目录中,我用的是Unity
发布了一个windows
平台的包。
iss
脚本中指明路径,并指明主程序文件,即.exe
文件
#define MyAppPkgDir ".\pkgs\v1"
#define MyAppExeName "我的应用.exe"
3、放界面图片素材
界面素材放在res/tmp
目录中
在
iss
中需要执行解压拷贝
// 将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、使用
用InnoSetup
打开MakePCSetup.iss
执行脚本(按
F9
),即可生成setup
程序生成的
setup
文件在output
目录中。七、补充:iss脚本基础知识
我们通过上一篇的教程(点击查看),可以生成一个iss
脚本,我们需要看懂这个脚本,然后对他进行修改和新增代码,实现我们的界面美化功能。
建议过程中可以翻翻Inno Setup
帮助说明文档:https://jrsoftware.org/ishelp/index.php
我们的iss
脚本的结构是这样的:
[Setup]
[Languages]
[Tasks]
[Files]
[Icons]
[Run]
[Registry]
[Code]
1、[Setup]
这个段包含用于安装程序和卸载程序的全局设置。
例
[Setup]
AppId=123456789
AppName="我的应用"
AppVersion=1.5
AppPublisher="公司名"
DefaultDirName={autopf}\My Program
DefaultGroupName=My Program
2、[Languages]
InnoSetup
制作的安装程序,支持多种语言设置,默认是英文的,如果要设置中文,需要配置对应的中文语言。
语言文件是.isl
格式的,将其放在InnoSetup
安装目录中的Languages
目录中。
然后在脚本中指明语言文件。
[Languages]
Name: "chs"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
哪里下载这个ChineseSimplified.isl
呢?点我下载。
3、[Tasks]
它定义安装程序在执行安装期间所有由用户定制的任务。这些任务以选项框和单选项形式在附加任务向导页中出现。
例:
[Tasks]
Name: "desktopicon"; Description: "创建桌面快捷方式"; GroupDescription: "添加快捷方式:"; Flags: checkedonce
Name: "quicklaunchicon"; Description: "创建快速运行栏快捷方式"; GroupDescription: "添加快捷方式:"; Flags: checkedonce
4、[Files]
[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]
定义所有创建在开始菜单或其它位置 (比如桌面) 的快捷方式。
例:
[Icons]
Name: "{group}\My Program"; Filename: "{app}\MYPROG.EXE"; WorkingDir: "{app}"
Name: "{group}\Uninstall My Program"; Filename: "{uninstallexe}"
6、[Run]
用来指定程序完成安装后要执行的程序。
例:
[Run]
Filename: "{app}\MYPROG.EXE"; Description: "Launch application"; Flags: postinstall Nowait skipifsilent unchecked
7、[Registry]
定义安装程序在用户系统上创建、修改或删除的任何注册表项/值。
例:
[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}"
其中Root
的值简写对照表如下
HKCU (HKEY_CURRENT_USER)
HKLM (HKEY_LOCAL_MACHINE)
HKCR (HKEY_CLASSES_ROOT)
HKU (HKEY_USERS)
HKCC (HKEY_CURRENT_CONfig)
8、[Code]
最重头的部分来了,[Code]
部分使用的是Pascal
语言编写的。我们的界面美化,就是在这里实现的。
八、补充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 位 |
例:
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 |
例:
var
a:single;
begin
a:=1.3;
end;
1.3、字符类型
例:
var
a:String;
b:String;
begin
a:="hello world";
b:=format('字符串拼接:%s', a);
end;
1.4、布尔类型
例:
var
a:boolean;
begin
a:=true;
end;
1.5、CONST常量
例:
const
pi=3.14159;
zero=0;
2、赋值语句
变量名:=表达式;
例:
a:="hello world";
3、if语句
例:
if x>y then
a:="big"
else
a:="small";
4、case语句
例:
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循环语句
例:
求N
的阶乘,N!=1*2*3*…*N
,这里 N
不大于 10
。
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循环语句
例:
var
a,:integer;
begin
a:=10;
while a>0 do
begin
a:=a-1;
end;
end;
7、引用其他脚本
#include "DllsImport.iss"
8、define常量与应用
#define MyAppName "我的应用名"
[Setup]
AppName={#MyAppName}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。