其中主要就是 [code]
块下面的 Pascal Script
,通过它来控制安装流程和界面的美化。
- 控制安装流程的原理是 Inno Setup 通过 Pascal Scripting: Event Functions 这种事件机制,把流程节点的控制交给
Pascal Script
,使其可以控制上一步
、下一步
等等的操作。 - 界面的美化,主要是调用两个美化插件动态库:
botva2.dll
和InnoCallback.dll
。用其来控制贴图的位置和样式,和给按钮绑定相应的事件等等的。
运行效果:
整体代码:
; 该执行目录为 setup.iss 所在的目录,请注意拼接相对目录
#define MyAppId "{{1AC4D338-0D28-47E4-9FC7-18929EDDF90D}"
#define MyAppName "xhschool_test"
#define MyAppNameZh "星火智慧课堂测试版"
#define MyAppVersion "3.4.5"
#define MyAppPublisher "码客说"
#define MyAppURL "www.psvmc.cn"
; 打包文件
#define MyAppExeName "xhschool.exe"
#define SourceMain "D:ProjectCSharpschoolclientbinx86Debugxhschool.exe"
#define SourceFolder "D:ProjectCSharpschoolclientbinx86Debug*"
#define SetupIconFilePath "D:ProjectCSharpschoolclientbinx86Debugfavicon256.ico"
; 打包生成位置
#define OutputPath "D:程序打包星火智慧课堂-测试版"
#define OutputFileName "星火智慧课堂测试版"
; license文件
#define LicenseFilePath "D:ToolsInnoSetupsetup_resourceslicense.txt"
; 美化资源文件
#define ResourcesPath "D:ToolsInnoSetupsetup_resources*"
[setup]
AppId={#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}{#MyAppName}
LicenseFile={#LicenseFilePath}
OutputDir={#OutputPath}
OutputBaseFilename={#OutputFileName}v{#MyAppVersion}
SetupIconFile={#SetupIconFilePath}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
Uninstallable=yes
UninstallDisplayName={#MyAppNameZh}
DefaultGroupName={#MyAppNameZh}
Versioninfodescription={#MyAppName} 安装程序
versioninfocopyright=Copyright(c) 2022
VersionInfoProductName={#MyAppName}
DisableReadyPage=yes
DisableProgramGroupPage=yes
DirExistsWarning=no
DisableDirPage=yes
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce
[Files]
Source: {#ResourcesPath}; DestDir: {tmp}; Flags: dontcopy solidbreak ; Attribs: hidden system
Source: {#SourceMain}; DestDir: "{app}"; Flags: ignoreversion
Source: {#SourceFolder}; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Messages]
SetupAppTitle={#MyAppName} 安装向导
SetupWindowTitle={#MyAppName} 安装向导
[Icons]
Name: "{commondesktop}{#MyAppNameZh}"; Filename: "{app}{#MyAppExeName}"; Tasks: desktopicon
Name: "{group}{#MyAppNameZh}"; Filename: "{app}{#MyAppExeName}"
Name: "{group}卸载{#MyAppNameZh}"; Filename: "{uninstallexe}"
[Code]
// for dll
type
TBtnEventProc = procedure (h:HWND);
TPBProc = function(h:hWnd;Msg,wParam,lParam:Longint):Longint; //百分比
TTimerProc = procedure(h:longword; msg:longword; idevent:longword; dwTime:longword);
const
Radius = 9;
GWL_EXSTYLE = (-20);
//窗口移动
WM_SYSCOMMAND = $0112;
WS_EX_LAYERED = $80000;
WS_EX_TRANSPARENT = $20;
LWA_COLORKEY = 1;
TransparentColor = clLime; //要去掉的图片底色
TransparentPercent = 80;
BTN_MAX_PATH = 1024;
BtnClickEventID = 1;
BtnMouseEnterEventID = 2;
BtnMouseLeaveEventID = 3;
BtnMouseMoveEventID = 4;
BtnMouseDownEventID = 5;
BtnMouseUpEventID = 6;
//function WrapBtnCallback(Callback: TBtnEventProc; ParamCount: Integer): Longword; external 'wrapcallback@files:innocallback.dll stdcall';
function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): Longword; external 'wrapcallback@files:innocallback.dll stdcall';
function DeleteObject(p1: Longword): BOOL; external 'DeleteObject@gdi32.dll stdcall';
function GetPM(nIndex:Integer):Integer; external 'GetSystemMetrics@user32.dll stdcall';
//botva2
function ImgLoad(Wnd :HWND; FileName :PAnsiChar; Left, Top, Width, Height :integer; Stretch, IsBkg :boolean) :Longint; external 'ImgLoad@{tmp}botva2.dll stdcall delayload';
procedure ImgSetVisibility(img :Longint; Visible :boolean); external 'ImgSetVisibility@{tmp}botva2.dll stdcall delayload';
procedure ImgApplyChanges(h:HWND); external 'ImgApplyChanges@{tmp}botva2.dll stdcall delayload';
procedure ImgSetPosition(img :Longint; NewLeft, NewTop, NewWidth, NewHeight :integer); external 'ImgSetPosition@files:botva2.dll stdcall';
procedure ImgRelease(img :Longint); external 'ImgRelease@{tmp}botva2.dll stdcall delayload';
procedure gdipShutdown; external 'gdipShutdown@{tmp}botva2.dll stdcall delayload';
function WrapBtnCallback(Callback: TBtnEventProc; ParamCount: Integer): Longword; external 'wrapcallback@{tmp}innocallback.dll stdcall delayload';
function BtnCreate(hParent:HWND; Left,Top,Width,Height:integer; FileName:PAnsiChar; ShadowWidth:integer; IsCheckBtn:boolean):HWND; external 'BtnCreate@{tmp}botva2.dll stdcall delayload';
procedure BtnSetText(h:HWND; Text:PAnsiChar); external 'BtnSetText@{tmp}botva2.dll stdcall delayload';
procedure BtnSetVisibility(h:HWND; Value:boolean); external 'BtnSetVisibility@{tmp}botva2.dll stdcall delayload';
procedure BtnSetFont(h:HWND; Font:Cardinal); external 'BtnSetFont@{tmp}botva2.dll stdcall delayload';
procedure BtnSetFontColor(h:HWND; NormalFontColor, FocusedFontColor, PressedFontColor, DisabledFontColor: Cardinal); external 'BtnSetFontColor@{tmp}botva2.dll stdcall delayload';
procedure BtnSetEvent(h:HWND; EventID:integer; Event:Longword); external 'BtnSetEvent@{tmp}botva2.dll stdcall delayload';
procedure BtnSetCursor(h:HWND; hCur:Cardinal); external 'BtnSetCursor@{tmp}botva2.dll stdcall delayload';
procedure BtnSetEnabled(h:HWND; Value:boolean); external 'BtnSetEnabled@{tmp}botva2.dll stdcall delayload';
function GetSysCursorHandle(id:integer):Cardinal; external 'GetSysCursorHandle@{tmp}botva2.dll stdcall delayload';
function BtnGetChecked(h:HWND):boolean; external 'BtnGetChecked@{tmp}botva2.dll stdcall delayload';
procedure BtnSetChecked(h:HWND; Value:boolean); external 'BtnSetChecked@{tmp}botva2.dll stdcall delayload';
procedure CreateFormFromImage(h:HWND; FileName:PAnsiChar); external 'CreateFormFromImage@{tmp}botva2.dll stdcall delayload';
procedure BtnSetPosition(h:HWND; NewLeft, NewTop, NewWidth, NewHeight: integer); external 'BtnSetPosition@{tmp}botva2.dll stdcall delayload';
function SetLayeredWindowAttributes(hwnd:HWND; crKey:Longint; bAlpha:byte; dwFlags:longint ):longint;
external 'SetLayeredWindowAttributes@user32 stdcall'; //函数声明
function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
function PBCallBack(P:TPBProc;ParamCount:integer):LongWord; external 'wrapcallback@files:innocallback.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
procedure ImgSetVisiblePart(img:Longint; NewLeft, NewTop, NewWidth, NewHeight : integer); external 'ImgSetVisiblePart@files:botva2.dll stdcall';
function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: LongWord; nIDEvent: LongWord): LongWord; external 'KillTimer@user32.dll stdcall';
function GetWindowLong(Wnd: HWnd; Index: Integer): Longint; external 'GetWindowLongA@user32.dll stdcall';
function ReleaseCapture(): Longint; external 'ReleaseCapture@user32.dll stdcall';
function CreateRoundRectRgn(p1, p2, p3, p4, p5, p6: Integer): THandle; external 'CreateRoundRectRgn@gdi32 stdcall';
function SetWindowRgn(hWnd: HWND; hRgn: THandle; bRedraw: Boolean): Integer; external 'SetWindowRgn@user32 stdcall';
procedure ShapeForm(aForm: TForm; edgeSize: integer); //圆角
var
FormRegion:LongWord;
begin
FormRegion:=CreateRoundRectRgn(0,0,aForm.Width,aForm.Height,edgeSize,edgeSize);
SetWindowRgn(aForm.Handle,FormRegion,True);
end;
// 安装前强制杀进
// 该函数在安装程序初始化时调用,返回False 将中断安装,True则继续安装.程
function InitializeSetup(): Boolean;
var ErrorCode: Integer;
begin
ShellExec('open','taskkill.exe','/f /im {#MyAppExeName}','',SW_HIDE,ewNoWait,ErrorCode);
ShellExec('open','tskill.exe',' {#MyAppName}','',SW_HIDE,ewNoWait,ErrorCode);
result := True;
end;
// 卸载前强制杀进程
function InitializeUninstall(): Boolean;
var ErrorCode: Integer;
begin
ShellExec('open','taskkill.exe','/f /im {#MyAppExeName}','',SW_HIDE,ewNoWait,ErrorCode);
ShellExec('open','tskill.exe',' {#MyAppName}','',SW_HIDE,ewNoWait,ErrorCode);
result := True;
end;
var
BGimg:longint;
btnShowLicense,MinBtn,CancelBtn,btnBrowser,btnSetup,btnBack:HWND;
isWelcomePage:boolean;
pathEdit:tedit;
labelReadImg,licenseImg,progressbgImg,PBOldProc,labelAutoRunImg:longint;
checkboxLicense,checkboxAutoRun:HWND;
licenseRich:TRichEditViewer;
// 向导调用这个事件函数确定是否在所有页或不在一个特殊页 (用PageID 指定) 显示。如果返回True,将跳过该页;如果你返回False,该页被显示。
// 注意: 这个事件函数不被wpWelcome、wpPreparing 和wpInstalling 页调用,还有安装程序已经确定要跳过的页也不会调用
// wpWelcome, wpLicense, wpPassword, wpInfoBefore, wpUserInfo, wpSelectDir, wpSelectComponents, wpSelectProgramGroup, wpSelectTasks, wpReady, wpPreparing, wpInstalling, wpInfoAfter, wpFinished
function ShouldSkipPage(PageID: Integer): Boolean;
begin
if PageID=wpLicense then
result:=true;
if PageID=wpInfoBefore then
result:=true;
if PageID=wpUserInfo then
result:=true;
if PageID=wpSelectDir then
result:=true;
if PageID=wpSelectComponents then
result:=true;
if PageID=wpSelectProgramGroup then
result:=true;
if PageID=wpSelectTasks then
result:=true;
end;
// 关闭按钮
procedure CancelBtnOnClick(hBtn:HWND);
begin
WizardForm.CancelButton.OnClick(WizardForm);
end;
// 最小化按钮
procedure MinBtnOnClick(hBtn:HWND);
begin
SendMessage(WizardForm.Handle,WM_SYSCOMMAND,61472,0);
end;
// 浏览文件夹按钮
procedure btnBrowserclick(hBtn:HWND);
begin
WizardForm.DirBrowseButton.OnClick(WizardForm);
pathEdit.text := WizardForm.DirEdit.text;
end;
// 路径选择器 change
procedure pathEditChange(Sender: TObject);
begin
WizardForm.DirEdit.text:=pathEdit.Text ;
end;
// 立即安装等按钮的操作就是不断地下一步
procedure nextSetpBtnClick(hBtn:HWND);
begin
WizardForm.NextButton.OnClick(WizardForm);
end;
// 安装的进度条
function PBProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
var
pr,i1,i2 : Extended;
w : integer;
begin
Result:=CallWindowProc(PBOldProc,h,Msg,wParam,lParam);
if (Msg=$402) and (WizardForm.ProgressGauge.Position>WizardForm.ProgressGauge.Min) then
begin
i1:=WizardForm.ProgressGauge.Position-WizardForm.ProgressGauge.Min;
i2:=WizardForm.ProgressGauge.Max-WizardForm.ProgressGauge.Min;
pr:=i1*100/i2;
w:=Round(650*pr/100);
ImgSetPosition(progressbgImg,0,320,w,15);
ImgSetVisiblePart(progressbgImg,0,0,w,15);
ImgApplyChanges(WizardForm.Handle);
end;
end;
// 鼠标拖动
procedure WizardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture
SendMessage(WizardForm.Handle, $0112, $F012, 0)
end;
// 查看 license
procedure btnShowLicenseClick(hBtn:HWND);
begin
if isWelcomePage=true then
begin
licenseImg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}bg_license.png'),0,0,650,450,false,false);
isWelcomePage:=false
licenseRich.Height:=295
BtnSetVisibility(checkboxLicense,false)
BtnSetVisibility(btnShowLicense,false)
BtnSetVisibility(btnSetup,false)
BtnSetVisibility(btnBrowser,false)
pathEdit.Hide
BtnSetVisibility(btnBack,true)
end else
begin
isWelcomePage:=true
BGimg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}bg_welcome.png'),0,0,650,450,false,true);
labelReadImg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}label_read.png'),243,398,72,20,false,true);
licenseRich.Height:=0
BtnSetVisibility(checkboxLicense,true)
BtnSetVisibility(btnShowLicense,true)
BtnSetVisibility(btnSetup,true)
ImgRelease(licenseImg)
BtnSetVisibility(btnBrowser,true)
pathEdit.show
BtnSetVisibility(btnBack,false)
end;
ImgApplyChanges(WizardForm.Handle)
end;
// 勾选查看 license
procedure checkboxLicenseClick(hBtn:HWND);
begin
if BtnGetChecked(checkboxLicense)=true then
begin
BtnSetEnabled(btnSetup,true)
end else
begin
BtnSetEnabled(btnSetup,false)
end
end;
// 该过程在开始的时候改变向导或者向导页,不要指望使用InitializeSetup函数实现改变向导页的功能,因为InitializeSetup函数触发时向导窗口并不存在。
procedure InitializeWizard();
var
MainLabel: TLabel;
begin
// 设置欢迎向导页的尺寸大小
WizardForm.OuterNotebook.hide;
WizardForm.Bevel.Hide;
WizardForm.BorderStyle:=bsnone;
WizardForm.Position:=poScreenCenter;
// WizardForm.Center;
WizardForm.Width:=650;
WizardForm.Height:=450;
// WizardForm.Color:=clWhite;
isWelcomePage:=true;
// WizardForm.InnerNotebook.Hide;
// wizardform.Color:=TransparentColor;
// 添加可以拖动窗口的Label
MainLabel := TLabel.Create(WizardForm);
MainLabel.Parent := WizardForm;
MainLabel.AutoSize := False;
MainLabel.Left := 0;
MainLabel.Top := 0;
MainLabel.Width := WizardForm.Width;
MainLabel.Height := WizardForm.Height;
MainLabel.Caption := '';
MainLabel.Transparent := True;
MainLabel.OnMouseDown := @WizardMouseDown;
// 加载资源到 tmp 临时目录
ExtractTemporaryFile('bg_welcome.png');
ExtractTemporaryFile('bg_installing.png');
ExtractTemporaryFile('bg_license.png');
ExtractTemporaryFile('label_read.png');
ExtractTemporaryFile('label_license.png');
ExtractTemporaryFile('license.txt');
ExtractTemporaryFile('btn_close.png');
ExtractTemporaryFile('btn_min.png');
ExtractTemporaryFile('btn_back.png');
ExtractTemporaryFile('btn_setup.png');
ExtractTemporaryFile('btn_browser.png');
ExtractTemporaryFile('checkbox.png');
ExtractTemporaryFile('bg_finished.png');
ExtractTemporaryFile('btn_complete.png');
ExtractTemporaryFile('loading.png');
ExtractTemporaryFile('label_autorun.png');
// 关闭按钮样式
CancelBtn:=BtnCreate(WizardForm.Handle,627,8,12,12,ExpandConstant('{tmp}btn_close.png'),1,False)
BtnSetEvent(CancelBtn,BtnClickEventID,WrapBtnCallback(@CancelBtnOnClick,1));
// 最小化按钮样式
MinBtn:=BtnCreate(WizardForm.Handle,607,8,12,12,ExpandConstant('{tmp}btn_min.png'),1,False)
BtnSetEvent(MinBtn,BtnClickEventID,WrapBtnCallback(@MinBtnOnClick,1));
// 立即安装按钮样式
btnSetup:=BtnCreate(WizardForm.Handle,195,340,260,44,ExpandConstant('{tmp}btn_setup.png'),1,False)
BtnSetEvent(btnSetup,BtnClickEventID,WrapBtnCallback(@nextSetpBtnClick,1));
// 返回按钮样式
btnBack:=BtnCreate(WizardForm.Handle,285,390,80,32,ExpandConstant('{tmp}btn_back.png'),1,False)
BtnSetEvent(btnBack,BtnClickEventID,WrapBtnCallback(@btnShowLicenseClick,1));
BtnSetVisibility(btnBack,false)
pathEdit:= TEdit.Create(WizardForm);
with pathEdit do
begin
Parent:=WizardForm;
text:=WizardForm.DirEdit.text;
Font.Name:='宋体'
BorderStyle:=bsNone;
SetBounds(110,272,340,15)
OnChange:=@pathEditChange;
TabStop:=false;
end;
// 浏览按钮样式
btnBrowser:=BtnCreate(WizardForm.Handle,470,263,80,32,ExpandConstant('{tmp}btn_browser.png'),1,False)
BtnSetEvent(btnBrowser,BtnClickEventID,WrapBtnCallback(@btnBrowserclick,1));
PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4,PBCallBack(@PBProc,4));
// 查看 license 的文本区域
licenseRich:= TRichEditViewer.Create(WizardForm);
with licenseRich do
begin
Parent:=WizardForm;
ReadOnly:=true;
SCROLLBARS:=ssVertical;
font.Name:='宋体'
Color:=clWhite;
BorderStyle:=bsNone;
SetBounds(40,65,570,0)
Lines.LoadFromFile(ExpandConstant('{tmp}license.txt'));
TabStop:=false;
end;
ImgApplyChanges(WizardForm.Handle)
end;
// 该过程在安装终止时被调用,注意及时在用户没有安装任何文件之前退出也会被调用。
procedure DeinitializeSetup();
var RCode: Integer;
begin
// 检查是否需要自动运行
if BtngetChecked(checkboxAutoRun)=true then
begin
Exec(ExpandConstant('{app}{#MyAppExeName}'),'','',SW_SHOW, ewNoWait,RCode);
end;
gdipShutdown;
end;
// 在新向导页 (由CurPageID 指定) 显示后调用。
procedure CurPageChanged(CurPageID: Integer);
begin
// 默认的流程按钮隐藏掉
WizardForm.NextButton.Visible:=false;
WizardForm.CancelButton.Height:=0;
WizardForm.BackButton.Height:=0;
if CurPageID=wpWelcome then
begin
BGimg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}bg_welcome.png'),0,0,650,450,true,true);
// license 提示
checkboxLicense:=BtnCreate(WizardForm.Handle,220,400,16,16,ExpandConstant('{tmp}checkbox.png'),1,true)
BtnSetEvent(checkboxLicense,BtnClickEventID,WrapBtnCallback(@checkboxLicenseClick,1))
// 默认勾选 阅读并同意
BtnSetChecked(checkboxLicense,true)
labelReadImg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}label_read.png'),243,398,39,20,false,true);
btnShowLicense:=BtnCreate(WizardForm.Handle,282,398,65,20,ExpandConstant('{tmp}label_license.png'),4,false)
BtnSetEvent(btnShowLicense,BtnClickEventID,WrapBtnCallback(@btnShowLicenseClick,1))
WizardForm.Width:=650;
WizardForm.Height:=450;
WizardForm.Show;
end;
if CurPageID = wpInstalling then
begin
BtnSetPosition(checkboxLicense,560,421,75,15);
pathEdit.Hide;
BtnSetVisibility(btnBrowser,false)
WizardForm.Height:=450
BtnSetVisibility(btnShowLicense,false);
BtnSetVisibility(checkboxLicense,false);
BGimg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}bg_installing.png'),0,0,650,450,false,true);
progressbgImg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}loading.png'),0,320,0,0,True,True);
BtnSetVisibility(btnSetup,false);
end;
if CurPageID = wpFinished then
begin
ImgSetVisibility(progressbgImg,false)
btnSetup:=BtnCreate(WizardForm.Handle,195,340,260,44,ExpandConstant('{tmp}btn_complete.png'),1,False)
BtnSetEvent(btnSetup,BtnClickEventID,WrapBtnCallback(@nextSetpBtnClick,1));
BGimg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}bg_finished.png'),0,0,650,450,false,true);
// 是否自动运行
checkboxAutoRun:=BtnCreate(WizardForm.Handle,275,400,16,16,ExpandConstant('{tmp}checkbox.png'),1,true)
labelAutoRunImg:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}label_autorun.png'),295,398,84,20,false,true);
// 默认勾选
BtnSetChecked(checkboxAutoRun,true);
// 完成页面隐藏关闭和最小化
BtnSetVisibility(CancelBtn,false);
BtnSetVisibility(MinBtn,false);
end;
ImgApplyChanges(WizardForm.Handle)
end;
兼容问题
窗口拖动
因为Inno5.5之后,WizardForm不再支持OnMouseDown, 所以首先我们要先创建一个Label覆盖窗口,再将label设置为透明,由Label来重载OnMouseDown。
var
MainLabel: TLabel;
MainLabel := TLabel.Create(WizardForm);
MainLabel.Parent := WizardForm;
MainLabel.AutoSize := False;
MainLabel.Left := 0;
MainLabel.Top := 0;
MainLabel.Width := WizardForm.Width;
MainLabel.Height := 50;
MainLabel.Caption := '';
MainLabel.Transparent := True;
MainLabel.OnMouseDown := @WizardFormMouseDown;
//窗口移动
procedure WizardFormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
SendMessage(WizardForm.Handle, WM_SYSCOMMAND, $F012, 0);
end;
高分屏缩放
[Code]
var
DpiScalePctg:integer;
CurrentDPI:integer;
procedure InitializeWizard();
begin
CurrentDPI := WizardForm.Font.PixelsPerInch;
DpiScalePctg := 1000* CurrentDPI / 96;
end;
function DpiScale(v:integer):integer;
begin
Result:=v*DpiScalePctg/1000;
end;
自定义语法
创建文本
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;
创建按钮
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;
创建图片
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
启动定时器
SetTimer(0, 0, 50, WrapTimerProc(@PageInstall_TimerProc, 4));
procedure PageInstall_TimerProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
//轮播背景图逻辑
end
创建输入编辑框
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
设置UI对象显示与隐藏
//隐藏按钮
BtnSetVisibility(btn, false);
//隐藏图片
ImgSetVisibility(imgBig, false);
//隐藏文本TLabel、隐藏输入框TEdit
TconSetVisible(lbl, false);
TconSetVisible(edt, false);
监听安装进度
//设置监听
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;
解压图片
要先把图片包含在安装包中
[Files]
Source: {#ResourcesPath}; DestDir: {tmp}; Flags: dontcopy solidbreak ; Attribs: hidden system
将tmp的资源, 解压到安装运行时搞出来的临时目录
ExtractTemporaryFile('bg_welcome.png');
ExtractTemporaryFile('bg_installing.png');
ExtractTemporaryFile('bg_license.png');
ExtractTemporaryFile('label_read.png');
ExtractTemporaryFile('label_license.png');
ExtractTemporaryFile('license.txt');
ExtractTemporaryFile('btn_close.png');
ExtractTemporaryFile('btn_min.png');
ExtractTemporaryFile('btn_back.png');
ExtractTemporaryFile('btn_setup.png');
ExtractTemporaryFile('btn_browser.png');
ExtractTemporaryFile('checkbox.png');
ExtractTemporaryFile('bg_finished.png');
ExtractTemporaryFile('btn_complete.png');
ExtractTemporaryFile('loading.png');
ExtractTemporaryFile('label_autorun.png');
使用
btnSetup:=BtnCreate(WizardForm.Handle,195,340,260,44,ExpandConstant('{tmp}btn_setup.png'),1,False)
目录常量
{app}
应用程序目录,这是用户在安装向导的选择安装目录页里面所选择的。这是Inno Setup中最常用的一个变量。
{userappdata}
类似于这样的目录C:UsersAdministratorAppDataRoaming
{autopf}
类似于C:Program Files (x86)
或者C:Program Files
{pf}
也是Inno Setup中比较常用的一个常量,这个路径是系统的Program Files目录,典型的是C:Program Files
。
{tmp}
临时目录,这个目录并不是用户的 TEMP 环境变量指向的目录,而是安装程序在启动时在用户的临时目录下建立的一个子目录(它有一个类似于C:WINDOWSTEMPIS-xxxxx.tmp
这样的名字),在安装程序退出时所有的文件和子目录将会被删除。对于在 [Run] 段里面要被执行且在安装以后又不需要的程序文件来说这个功能是非常有用的。
{win}
系统的Windows目录,一般为C:WINDOWS
。例如:如果你使用了 {win}”MYPROG.INI ,而你的 Windows 目录是C:WINDOWS
,那么安装程序就会将它转换成C:WINDOWSMYPROG.INI
。
{sys}
系统的 Windows 系统(System)目录(在 Windows NT/2000 下是 System32)。 例如:如果你使用了 {sys}CTL3D32.DLL
,并且系统的 Windows 系统目录是C:WINDOWSSYSTEM
,那么安装程序就会将它转换成C:WINDOWSSYSTEMCTL3D32.DLL
。
{src}
指向安装程序所在的位置。
{sd}
系统驱动器,它是指 Windows 被安装到的那个驱动器,典型的是C:
,对于 Windows NT/2000,这个常量同系统的环境变量“SystemDrive”是等效的。
{cf}
公共文件夹(Common Files),这个路径是系统的 Common Files 文件夹,典型的是C:Program FilesCommon Files
。
{fonts}
字体目录。
{dao}
DAO 目录,当安装程序运行在 Windows 95/NT 4+ 上时,它被等效为 {cf}Microsoft SharedDAO
,
当运行于 Windows NT 3.51 时,它被等效为 { win}MSAPPSDAO
。

暂无评论内容