微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用InnoSetup实现Setup安装程序界面美化

一、前言

之前我写过一篇《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.dllInnoCallback.dll。用其来控制贴图的位置和样式,和给按钮绑定相应的事件等等的。

点击下载InnoCallback.dll
点击下载botva2.dll

五、界面美化逻辑实现

美化界面用到了botva2.dll。需要引入DllsImport.iss

#include "DllsImport.iss"  

1、资源目录

界面资源放在res/tmp目录中,包括我们引用的两个dllbotva2.dllInnoCallback.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、监听安装进度

用到了WindowsAPI

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] 举报,一经查实,本站将立刻删除。

相关推荐