ISDone (error) finish page - inno-setup

I am having a problem with ISdone library error finish page.
according to the library error page should be in red colour like this:
But i am not getting the red colour:
I know why this is happening,This is because of the code of stratching the image.
Now how can i get the red colour for FinishedLabel and FinishedHeadingLabel if ISDone error occures.
Thank You .
Script :
; --- Generated by InnoSetup Script Joiner version 3.0, Jul 22 2009, (c) Bulat Ziganshin <Bulat.Ziganshin#gmail.com>. More info at http://issjoiner.codeplex.com/
; --- Source: 2.iss ------------------------------------------------------------
// Setup.ini internal
#define MyAppName "Game"
#define MyAppVersion "2.0.0.0"
#define MyAppPublisher "Dante1995"
#define MyAppExeName "MyProg.exe"
#define NeedSize "5000000"
// only Arc, Disable PrecompInside
;#Define PrecompInside
[Setup]
WizardSmallImageFile=Include\WizModernSmallImage.bmp
WizardImageFile=Include\WizModernImage-IS.bmp
AppName={#MyAppName}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppVersion={#MyAppVersion}
DefaultDirName={pf}\{#MyAppPublisher}\{#MyAppName}
OutputBaseFilename=Setup
OutputDir=Output
Compression=zip
InternalCompressLevel=Ultra64
SetupIconFile=include\icon.ico
UninstallDisplayIcon={uninstallexe}
VersionInfoCopyright={#MyAppPublisher}
#ifdef NeedSize
ExtraDiskSpaceRequired={#NeedSize}
#endif
DisableWelcomePage=False
DisableProgramGroupPage=yes
[Languages]
Name: "default"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked;
Name: DX; Description: Install Microsoft DirectX
Name: VC; Description: Install Microsoft Visual C++ Redist
[Icons]
Name: "{group}\Play {#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Check: CheckError
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; Check: CheckError
Name: "{commondesktop}\Play {#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Check: CheckError; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Check: CheckError; Tasks: quicklaunchicon
[Files]
#ifdef PrecompInside
Source: include\facompress.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\CLS-precomp.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\packjpg_dll.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\packjpg_dll1.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\precomp.exe; DestDir: {tmp}; Flags: dontcopy
Source: include\zlib1.dll; DestDir: {tmp}; Flags: dontcopy
#endif
#ifdef SrepInside
Source: include\CLS-srep.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\cls.ini; DestDir: {tmp}; Flags: dontcopy
#endif
#ifdef MSC
Source: include\CLS-MSC.dll; DestDir: {tmp}; Flags: dontcopy
#endif
Source: include\English.ini; DestDir: {tmp}; Flags: dontcopy
Source: include\unarc.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\ISDone.dll; DestDir: {tmp}; Flags: dontcopy
Source: include\CallbackCtrl.dll; Flags: dontcopy noencryption noencryption
Source: include\arc.ini; DestDir: {tmp}; Flags: dontcopy
Source: "Setup.ini"; Flags: dontcopy solidbreak;
[CustomMessages]
default.ORE=h
default.MINUTI=min
default.SECONDI=sec
default.RIMANENTE=Remaining Time:
default.ESTRAZIONE=Extracted Files:
default.TTime=Total Extraction Time :
default.Elapsed=Elapsed Time:
[UninstallDelete]
Type: filesandordirs; Name: "{app}"
Type: dirifempty; Name: "{pf}\{#MyAppPublisher}"
[Messages]
default.SetupWindowTitle=%1
[Code]
var
ElapsedTimeLbl,TotalTimeLbl,Percentuale,//RollingBack,
RemainingTimeLbl,LabelCurrFileName: TLabel;
ISDoneCancel:integer;
ISDoneError:boolean;
CancelBtn: TButton;
PBOldProc : Longint;
WFCaption : string;
eTime, sTime : DWORD;
type
#ifdef UNICODE
PChar = PAnsiChar;
#endif
TCallback = function (OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
TPBProc = function (h:hWnd;Msg,wParam,lParam:Longint):Longint;
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLongA#user32.dll stdcall';
function CallBackProc(P:TPBProc;ParamCount:integer):LongWord; external 'wrapcallbackaddr#files:CallbackCtrl.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA#user32.dll stdcall';
function GetTickCount: DWORD; external 'GetTickCount#kernel32.dll stdcall';
function WrapCallback(callback:TCallback; paramcount:integer):longword;external 'wrapcallback#files:ISDone.dll stdcall delayload';
function ISDoneInit(RecordFileName:AnsiString; TimeType,Comp1,Comp2,Comp3:Cardinal; WinHandle, NeededMem:longint; callback:TCallback):boolean; external 'ISDoneInit#files:ISDone.dll stdcall';
function ISArcExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath, ExtractedPath: AnsiString; DeleteInFile:boolean; Password, CfgFile, WorkPath: AnsiString; ExtractPCF: boolean ):boolean; external 'ISArcExtract#files:ISDone.dll stdcall delayload';
function IS7ZipExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath: AnsiString; DeleteInFile:boolean; Password: AnsiString):boolean; external 'IS7zipExtract#files:ISDone.dll stdcall delayload';
function ISRarExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath: AnsiString; DeleteInFile:boolean; Password: AnsiString):boolean; external 'ISRarExtract#files:ISDone.dll stdcall delayload';
function ISPrecompExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString; DeleteInFile:boolean):boolean; external 'ISPrecompExtract#files:ISDone.dll stdcall delayload';
function ISSRepExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString; DeleteInFile:boolean):boolean; external 'ISSrepExtract#files:ISDone.dll stdcall delayload';
function ISxDeltaExtract(CurComponent:Cardinal; PctOfTotal:double; minRAM,maxRAM:integer; InName, DiffFile, OutFile: AnsiString; DeleteInFile, DeleteDiffFile:boolean):boolean; external 'ISxDeltaExtract#files:ISDone.dll stdcall delayload';
function ISPackZIP(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString;ComprLvl:integer; DeleteInFile:boolean):boolean; external 'ISPackZIP#files:ISDone.dll stdcall delayload';
function ShowChangeDiskWindow(Text, DefaultPath, SearchFile:AnsiString):boolean; external 'ShowChangeDiskWindow#files:ISDone.dll stdcall delayload';
function Exec2 (FileName, Param: PAnsiChar;Show:boolean):boolean; external 'Exec2#files:ISDone.dll stdcall delayload';
function ISFindFiles(CurComponent:Cardinal; FileMask:AnsiString; var ColFiles:integer):integer; external 'ISFindFiles#files:ISDone.dll stdcall delayload';
function ISPickFilename(FindHandle:integer; OutPath:AnsiString; var CurIndex:integer; DeleteInFile:boolean):boolean; external 'ISPickFilename#files:ISDone.dll stdcall delayload';
function ISGetName(TypeStr:integer):PAnsichar; external 'ISGetName#files:ISDone.dll stdcall delayload';
function ISFindFree(FindHandle:integer):boolean; external 'ISFindFree#files:ISDone.dll stdcall delayload';
function ISExec(CurComponent:Cardinal; PctOfTotal,SpecifiedProcessTime:double; ExeName,Parameters,TargetDir,OutputStr:AnsiString;Show:boolean):boolean; external 'ISExec#files:ISDone.dll stdcall delayload';
function SrepInit(TmpPath:PAnsiChar;VirtMem,MaxSave:Cardinal):boolean; external 'SrepInit#files:ISDone.dll stdcall delayload';
function PrecompInit(TmpPath:PAnsiChar;VirtMem:cardinal;PrecompVers:single):boolean; external 'PrecompInit#files:ISDone.dll stdcall delayload';
function FileSearchInit(RecursiveSubDir:boolean):boolean; external 'FileSearchInit#files:ISDone.dll stdcall delayload';
function ISDoneStop:boolean; external 'ISDoneStop#files:ISDone.dll stdcall';
function ChangeLanguage(Language:AnsiString):boolean; external 'ChangeLanguage#files:ISDone.dll stdcall delayload';
function SuspendProc:boolean; external 'SuspendProc#files:ISDone.dll stdcall';
function ResumeProc:boolean; external 'ResumeProc#files:ISDone.dll stdcall';
function ProgressCallback(OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
begin
if OveralPct<=Wizardform.ProgressGauge.Max then
Wizardform.Progressgauge.Position := OveralPct;
Result := ISDoneCancel;
TotalTimeLbl.Caption:=ExpandConstant('{cm:TTime}')+TimeStr2;
with WizardForm.ProgressGauge do begin
LabelCurrFileName.Caption:=SetupMessage(msgStatusExtractFiles)+': '+MinimizePathName(CurrentFile, LabelCurrFileName.Font, LabelCurrFileName.Width-ScaleX(100));
end;
end;
function LongintToStringTime(t:Longint):string;
var
h,m,s:integer;
begin
h:=t div 3600;
t:=t-h*3600;
m:=t div 60;
s:=t-m*60;
Result:='';
if h>0 then Result:=Result+IntToStr(h)+ ExpandConstant(' {cm:ORE} ');
if (m>0) or (h>0) then Result:=Result+IntToStr(m)+ExpandConstant(' {cm:MINUTI} ');
if (m>0) or (h>0) or (s>0) then Result:=Result+IntToStr(s)+ExpandConstant(' {cm:SECONDI} ');
end;
function PBProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
var
R,A:Longint;
dt,at,pr,i1,i2:Extended;
p:string;
tc:DWORD;
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;
tc:=GetTickCount;
if (tc-eTime)>=1000 then begin
dt:=(tc-sTime)/1000;
at:=i2*dt/i1;
R:=Round(at-dt)
A:=Round(dt)
RemainingTimeLbl.Caption:=ExpandConstant('{cm:RIMANENTE} ')+LongintToStringTime(R);
ElapsedTimeLbl.Caption:=ExpandConstant('{cm:Elapsed} ')+LongintToStringTime(A);
eTime:=tc;
end;
pr:=i1*100/i2;
p:=''+Format('%f',[pr])+'%';
StringChange(p,',','.');
Percentuale.Caption:=WFCaption+p;
end;
end;
procedure AllCancel;
begin
SetWindowLong(WizardForm.ProgressGauge.Handle,-4,PBOldProc);
Percentuale.Caption:=WFCaption;
end;
procedure CancelButtonOnClick(Sender: TObject);
begin
SuspendProc;
//RollingBack.Show;
if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then ISDoneCancel:=1;
ResumeProc;
//RollingBack.Hide;
end;
procedure HideControls;
begin
CancelBtn.Hide;
LabelCurrFileName.Hide;
RemainingTimeLbl.Hide;
ElapsedTimeLbl.Hide;
end;
procedure InitializeWizard1();
begin
WizardForm.ProgressGauge.Top := ScaleY(46);
ElapsedTimeLbl := TLabel.Create(WizardForm);
with ElapsedTimeLbl do begin
Parent := WizardForm.InstallingPage;
Font.Size:=10;
Font.Color:=clYellow;
Font.Style := [fsBold];
Font.Name:='calibri';
SetBounds(0,90,WizardForm.ClientWidth-40,14);
end;
RemainingTimeLbl:=TLabel.Create(WizardForm);
with RemainingTimeLbl do begin
Parent:=WizardForm.InstallingPage;
SetBounds(216,90,WizardForm.ClientWidth-40,14);
Font.Size:=10;
Font.Color:=clYellow;
Font.Style := [fsBold];
Font.Name:='calibri';
end;
Percentuale := TLabel.Create(WizardForm);
with Percentuale do begin
Parent:= WizardForm.InstallingPage;
SetBounds(150,130,WizardForm.ClientWidth-40,14);
Font.Size:=20;
Font.Color:=clYellow;
Font.Style := [fsBold];
Font.Name:='calibri';
end;
CancelBtn := TButton.Create(WizardForm);
with CancelBtn do begin
Name := 'Cancel';
Parent := WizardForm;
Left := WizardForm.CancelButton.Left;
Top := WizardForm.CancelButton.Top;
Width := WizardForm.CancelButton.Width;
Height := WizardForm.CancelButton.Height;
OnClick:=#CancelButtonOnClick;
Font.Size:=8;
Font.Name:='calibri';
end;
LabelCurrFileName := TLabel.Create(WizardForm);
with LabelCurrFileName do begin
Parent := WizardForm.InstallingPage;
AutoSize := False;
Width := WizardForm.ProgressGauge.Width+ScaleX(30);
Left := ScaleX(0);
Top := ScaleY(30);
Font.Size:=8;
Font.Color:=clYellow;
Font.Name:='calibri';
end;
TotalTimeLbl := TLabel.Create(WizardForm);
with TotalTimeLbl do begin
Parent := WizardForm.FinishedPage;
AutoSize := False;
Width := 300;
Left := 180;
Top := 200;
Font.Size:=14;
Font.Color:=clYellow;
Font.Style := [fsBold];
Font.Name:='calibri';
Height := 35;
end;
end;
procedure CurPageChanged1(CurPageID: integer);
begin
HideControls;
if CurPageID=wpWelcome then
begin
end;
if CurPageID=wpSelectDir then
begin
end;
if CurPageID=wpInstalling then
begin
CancelBtn.Show;
LabelCurrFileName.Show;
RemainingTimeLbl.Show;
ElapsedTimeLbl.Show;
end;
if CurPageID=wpFinished then
begin
RemainingTimeLbl.Hide;
AllCancel;
HideControls;
end;
if (CurPageID = wpFinished) and ISDoneError then
begin
WizardForm.Caption:= SetupMessage(msgErrorTitle);
WizardForm.FinishedLabel.Font.Color:= clRed;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted);
end;
end;
function CheckError:boolean;
begin
result:= not ISDoneError;
end;
procedure CurStepChanged1(CurStep: TSetupStep);
var
res, i, ResultCode: integer;
Arc1, Arc2: Array of String;
begin
If CurStep = ssInstall then begin
WizardForm.StatusLabel.Caption:='Installing The Game...';
sTime:=GetTickCount;
eTime:=sTime;
PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4,CallBackProc(#PBProc,4));
#ifdef PrecompInside
ExtractTemporaryFile('CLS-precomp.dll');
ExtractTemporaryFile('packjpg_dll.dll');
ExtractTemporaryFile('packjpg_dll1.dll');
ExtractTemporaryFile('precomp.exe');
ExtractTemporaryFile('zlib1.dll');
ExtractTemporaryFile('facompress.dll');
#endif
#ifdef SrepInside
ExtractTemporaryFile('CLS-srep.dll');
#endif
#ifdef MSC
ExtractTemporaryFile('CLS-MSC.dll');
#endif
ExtractTemporaryFile('arc.ini');
ExtractTemporaryFile('unarc.dll');
ExtractTemporaryFile('English.ini');
ISDoneError:=false;
i:=1;
if (GetIniString('FreearcFile' + IntToStr(i),'Archive','',ExpandConstant('{tmp}\Setup.ini')) <> '') then
begin
WizardForm.ProgressGauge.Max:=0;
repeat
WizardForm.ProgressGauge.Max:= WizardForm.ProgressGauge.Max + 1000;
i:= i + 1;
until (GetIniString('FreearcFile' + IntToStr(i),'Archive','',ExpandConstant('{tmp}\Setup.ini')) = '');
end;
if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0,0,0, MainForm.Handle, 512, #ProgressCallback) then begin
repeat
ChangeLanguage('English');
if not SrepInit('',512,0) then ISDoneError := True;
if not PrecompInit('',128,0) then ISDoneError := True;
if not FileSearchInit(true) then ISDoneError := True;
i:=1;
if (GetIniString('FreearcFile' + IntToStr(i),'Archive','',ExpandConstant('{tmp}\Setup.ini')) <> '') then
begin
SetArrayLength(Arc1,4);
SetArrayLength(Arc2,4);
repeat
Arc1[0]:=ExpandConstant(GetIniString('FreearcFile' + IntToStr(i),'Archive','',ExpandConstant('{tmp}\Setup.ini')));
Arc1[1]:=ExpandConstant(GetIniString('FreearcFile' + IntToStr(i),'Output','',ExpandConstant('{tmp}\Setup.ini')));
Arc1[2]:=ExpandConstant(GetIniString('FreearcFile' + IntToStr(i),'Disk','1',ExpandConstant('{tmp}\Setup.ini')));
if Arc1[0] <> '' then
begin
if not FileExists(Arc1[0]) then
begin
if MsgBox(SetupMessage(msgChangeDiskTitle) +' '+'( '+ Arc1[2]+' )', mbError, MB_OKCANCEL) = IDCANCEL then ISDoneError := True;
end else begin
if not ISArcExtract( 0, 0, Arc1[0], Arc1[1], '', false, Arc1[3], ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), False) then ISDoneError := True;
i:= i + 1;
end;
end;
until ((GetIniString('FreearcFile' + IntToStr(i),'Archive','',ExpandConstant('{tmp}\Setup.ini')) = '') or (ISDoneError = True));
end;
until true;
ISDoneStop;
end;
AllCancel;
HideControls;
WizardForm.ProgressGauge.Hide;
end;
if (CurStep=ssPostInstall) and ISDoneError then begin
WizardForm.StatusLabel.Caption:=SetupMessage(msgStatusRollback);
TotalTimeLbl.Caption:='';
Exec(ExpandConstant('{uninstallexe}'), '/VERYSILENT','', sw_Hide, ewWaitUntilTerminated, ResultCode);
end;
end;
function InitializeSetup1: Boolean;
var
Uninstall,Location: string;
ResultCode: Integer;
begin
if not FileExists(ExpandConstant('{tmp}\CallbackCtrl.dll')) then ExtractTemporaryFile('CallbackCtrl.dll');
ExtractTemporaryFile('Setup.ini');
if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppName}_is1','UninstallString', Uninstall) then
Uninstall:=RemoveQuotes(Uninstall);
begin
if not Exec(Uninstall, ' /SILENT', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppName}_is1','InstallLocation', Location);
end;
Result:=True;
end;
[Setup]
; --- Source: 3.iss ------------------------------------------------------------
[code]
var
WelcomeLabel1, WelcomeLabel2, FinishedLabel, FinishedHeadingLabel: TLabel;
PageNameLabel, PageDescriptionLabel: TLabel;
procedure InitializeWizard2();
begin
WizardForm.WizardBitmapImage.Width := ScaleX(497);
WizardForm.WizardBitmapImage2.Width := ScaleX(497);
{ WelcomeLabel1 }
WizardForm.WelcomeLabel1.Hide;
WelcomeLabel1 := TLabel.Create(WizardForm);
with WizardForm.WelcomeLabel1 do
begin
WelcomeLabel1.Parent := Parent;
WelcomeLabel1.SetBounds(Left, Top, Width, Height);
WelcomeLabel1.AutoSize := AutoSize;
WelcomeLabel1.Font := Font;
WelcomeLabel1.Font.Color := clWhite;
WelcomeLabel1.Transparent := True;
WelcomeLabel1.WordWrap := WordWrap;
WelcomeLabel1.Caption := Caption;
end;
{ WelcomeLabel2 }
WizardForm.WelcomeLabel2.Hide;
WelcomeLabel2 := TLabel.Create(WizardForm);
with WizardForm.WelcomeLabel2 do
begin
WelcomeLabel2.Parent := Parent;
WelcomeLabel2.SetBounds(Left, Top, Width, Height);
WelcomeLabel2.AutoSize := AutoSize;
WelcomeLabel2.Font := Font;
WelcomeLabel2.Font.Color := clWhite;
WelcomeLabel2.Transparent := True;
WelcomeLabel2.WordWrap := WordWrap;
WelcomeLabel2.Caption := Caption;
end;
WizardForm.WizardSmallBitmapImage.SetBounds(ScaleX(0), ScaleY(0), WizardForm.MainPanel.Width, WizardForm.MainPanel.Height);
{ PageNameLabel }
WizardForm.PageNameLabel.Hide;
PageNameLabel := TLabel.Create(WizardForm);
with WizardForm.PageNameLabel do
begin
PageNameLabel.Parent := Parent;
PageNameLabel.SetBounds(Left, Top, Width, Height);
PageNameLabel.AutoSize := AutoSize;
PageNameLabel.Font := Font;
PageNameLabel.Font.Color := clYellow;
PageNameLabel.Transparent := True;
PageNameLabel.WordWrap := WordWrap;
end;
{ PageDescriptionLabel }
WizardForm.PageDescriptionLabel.Hide;
PageDescriptionLabel:= TLabel.Create(WizardForm);
with WizardForm.PageDescriptionLabel do
begin
PageDescriptionLabel.Parent := Parent;
PageDescriptionLabel.SetBounds(Left, Top, Width, Height);
PageDescriptionLabel.AutoSize := AutoSize;
PageDescriptionLabel.Font := Font;
PageDescriptionLabel.Font.Color := clYellow;
PageDescriptionLabel.Transparent := True;
PageDescriptionLabel.WordWrap := WordWrap;
end;
{ FinishedHeadingLabel }
WizardForm.FinishedHeadingLabel.Hide;
FinishedHeadingLabel := TLabel.Create(WizardForm);
with WizardForm.FinishedHeadingLabel do
begin
FinishedHeadingLabel.Parent := Parent;
FinishedHeadingLabel.SetBounds(Left, Top, Width, Height);
FinishedHeadingLabel.AutoSize := AutoSize;
FinishedHeadingLabel.Font := Font;
FinishedHeadingLabel.Font.Color := clWhite;
FinishedHeadingLabel.Transparent := True;
FinishedHeadingLabel.WordWrap := WordWrap;
FinishedHeadingLabel.Caption := Caption;
end;
{ FinishedLabel }
WizardForm.FinishedLabel.Hide;
FinishedLabel := TLabel.Create(WizardForm);
with WizardForm.FinishedLabel do
begin
FinishedLabel.Parent := Parent;
FinishedLabel.SetBounds(Left, Top, Width, Height);
FinishedLabel.AutoSize := AutoSize;
FinishedLabel.Font := Font;
FinishedLabel.Font.Color := clWhite;
FinishedLabel.Transparent := True;
FinishedLabel.WordWrap := WordWrap;
end;
end;
procedure CurPageChanged2(CurPageID: Integer);
begin
begin
PageNameLabel.Caption := WizardForm.PageNameLabel.Caption;
PageDescriptionLabel.Caption := WizardForm.PageDescriptionLabel.Caption;
FinishedLabel.Caption := WizardForm.FinishedLabel.Caption;
end;
if (CurPageID = wpFinished) and ISDoneError then
begin
WizardForm.Caption:= SetupMessage(msgErrorTitle);
WizardForm.FinishedLabel.Font.Color:= clRed;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted);
end;
end;
[Setup]
; --- Dispatching code ------------------------------------------------------------
[Code]
procedure InitializeWizard();
begin
InitializeWizard1();
InitializeWizard2();
end;
procedure CurPageChanged(CurPageID: Integer);
begin
CurPageChanged1(CurPageID);
CurPageChanged2(CurPageID);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
CurStepChanged1(CurStep);
end;
function InitializeSetup(): Boolean;
begin
Result := InitializeSetup1(); if not Result then exit;
end;

You'r Label's are messed up. If you are creating a new label in the place of an existing one make sure you use it everywhere. Dont mix it up!
Though i would not proceed with a code such as that in its current state...here's a fix.
Set the parent of FinishedLabel to WizardForm.FinishedPage
with WizardForm.FinishedLabel do begin
FinishedLabel.Parent:=WizardForm.FinishedPage;
....
end;
and use that FinishedLabel to display the error message.
if (CurPageID = wpFinished) and ISDoneError then
begin
WizardForm.Caption:= SetupMessage(msgErrorTitle);
FinishedLabel.Font.Color:= clRed;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted);
end;
in procedure CurPageChanged2.
Btw the code is very clumsy. Please take some time to go through your code and organise it before you go any further.
Edit: The updated code. I have tested this code in my PC and its working fine. Replace the CurPageChanged2 with this.
procedure CurPageChanged2(CurPageID: Integer);
begin
begin
PageNameLabel.Caption := WizardForm.PageNameLabel.Caption;
PageDescriptionLabel.Caption := WizardForm.PageDescriptionLabel.Caption;
FinishedLabel.Caption := WizardForm.FinishedLabel.Caption;
end;
if (CurPageID = wpFinished) and ISDoneError then
begin
WizardForm.Caption:= SetupMessage(msgErrorTitle);
FinishedLabel.Font.Color:= clRed; // changed
FinishedHeadingLabel.Font.Color:= clRed; // changed
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted);
end;
end;

Related

InnoSetup - GIF backgroung image? [duplicate]

I would like to have in my installer:
an infinite music loop playback during installation
a window on the background (like the old installations that used to fill the screen with an image and only show the installation window), with a slideshow on that background window
How to do this in InnoSetup ?
If you want to have an installer with a background image slideshow with an infinite music track playback, you can do e.g. the following:
get the recent version of the InnoCallback library for slideshow timer implementation
for music playback get e.g. most recent copy of the Inno Media Player for Unicode Inno Setup
Write a script similar to following, or download the complete project, which includes all necessary files used in the next script code. So the only thing you'd need to do, is to build it in the recent version of Unicode Inno Setup.
Please note, that Inno Media Player is a Unicode library, and so you can use it only with Unicode versions of Inno Setup, not with ANSI ones! There is no support for ANSI versions of Inno Setup...!
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output
BackColor=clLime
BackColor2=clYellow
WindowVisible=yes
[Files]
Source: "Image1.bmp"; Flags: dontcopy
Source: "Image2.bmp"; Flags: dontcopy
Source: "AudioFile.mp3"; Flags: dontcopy
Source: "MediaPlayer.dll"; Flags: dontcopy
Source: "InnoCallback.dll"; Flags: dontcopy
[Code]
var
TimerID: Integer;
SlideID: Integer;
BackImage: TBitmapImage;
const
EC_COMPLETE = $01;
type
TTimerProc = procedure(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
TDirectShowEventProc = procedure(EventCode, Param1, Param2: Integer);
function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord;
external 'wrapcallback#files:InnoCallback.dll stdcall';
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT;
lpTimerFunc: UINT): UINT; external 'SetTimer#user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL;
external 'KillTimer#user32.dll stdcall';
function DSGetLastError(var ErrorText: WideString): HRESULT;
external 'DSGetLastError#files:mediaplayer.dll stdcall';
function DSPlayMediaFile: Boolean;
external 'DSPlayMediaFile#files:mediaplayer.dll stdcall';
function DSStopMediaPlay: Boolean;
external 'DSStopMediaPlay#files:mediaplayer.dll stdcall';
function DSSetVolume(Value: LongInt): Boolean;
external 'DSSetVolume#files:mediaplayer.dll stdcall';
function DSInitializeAudioFile(FileName: WideString;
CallbackProc: TDirectShowEventProc): Boolean;
external 'DSInitializeAudioFile#files:mediaplayer.dll stdcall';
procedure OnMediaPlayerEvent(EventCode, Param1, Param2: Integer);
begin
if EventCode = EC_COMPLETE then
begin
if DSInitializeAudioFile(ExpandConstant('{tmp}\AudioFile.mp3'),
#OnMediaPlayerEvent) then
begin
DSSetVolume(-2500);
DSPlayMediaFile;
end;
end;
end;
procedure OnSlideTimer(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
begin
case SlideID of
0: SlideID := 1;
1: SlideID := 0;
end;
BackImage.Bitmap.LoadFromFile(
ExpandConstant('{tmp}\Image' + IntToStr(SlideID + 1) + '.bmp'));
end;
procedure StartSlideTimer;
var
TimerCallback: LongWord;
begin
TimerCallback := WrapTimerProc(#OnSlideTimer, 4);
{ third parameter here is the timer's timeout value in milliseconds }
TimerID := SetTimer(0, 0, 5000, TimerCallback);
end;
procedure KillSlideTimer;
begin
if TimerID <> 0 then
begin
if KillTimer(0, TimerID) then
TimerID := 0;
end;
end;
procedure InitializeWizard;
var
ErrorCode: HRESULT;
ErrorText: WideString;
begin
TimerID := 0;
SlideID := 0;
ExtractTemporaryFile('Image1.bmp');
ExtractTemporaryFile('Image2.bmp');
BackImage := TBitmapImage.Create(MainForm);
BackImage.Parent := MainForm;
BackImage.Top := 70;
BackImage.Left := 10;
BackImage.AutoSize := True;
BackImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\Image1.bmp'));
StartSlideTimer;
ExtractTemporaryFile('AudioFile.mp3');
if DSInitializeAudioFile(ExpandConstant('{tmp}\AudioFile.mp3'),
#OnMediaPlayerEvent) then
begin
DSSetVolume(-2500);
DSPlayMediaFile;
end
else
begin
ErrorCode := DSGetLastError(ErrorText);
MsgBox('TDirectShowPlayer error: ' + IntToStr(ErrorCode) + '; ' +
ErrorText, mbError, MB_OK);
end;
end;
procedure DeinitializeSetup;
begin
KillSlideTimer;
DSStopMediaPlay;
end;
Further resources:
How to make a slideshow in InnoSetup ?
How to play a sound during InnoSetup installation process ?
Creating backgrounds feature:
Did you try Graphical Installer (http://www.graphical-installer.com) ?
It is a professional Inno Setup extension specially for this (creating cool looking installers with background) so creating such installer is matter of few minutes (no coding is required).

Inno Setup: Enlarge component page only with preview and description

I need help from you to merge two scripts found here to have preview image on a maximized components windows:
Add image into the components list - component description
Long descriptions on Inno Setup components
Edit: Thanks to Martin Prikryl. With his patience and his help, I successfully merge these two scripts.
Your preview image should have a resolution of 208x165 in .bmp
[Files]
...
Source: "1.bmp"; Flags: dontcopy
Source: "2.bmp"; Flags: dontcopy
Source: "3.bmp"; Flags: dontcopy
Source: "InnoCallback.dll"; Flags: dontcopy
[Code]
var
LastMouse: TPoint;
type
TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos#user32.dll stdcall';
function SetTimer(hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; external 'SetTimer#user32.dll stdcall';
function ScreenToClient(hWnd: HWND; var lpPoint: TPoint): BOOL; external 'ScreenToClient#user32.dll stdcall';
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL; external 'ClientToScreen#user32.dll stdcall';
function ListBox_GetItemRect(const hWnd: HWND; const Msg: Integer; Index: LongInt; var Rect: TRect): LongInt; external 'SendMessageW#user32.dll stdcall';
const
LB_GETITEMRECT = $0198;
LB_GETTOPINDEX = $018E;
function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; external 'wrapcallback#files:InnoCallback.dll stdcall';
function FindControl(Parent: TWinControl; P: TPoint): TControl;
var
Control: TControl;
WinControl: TWinControl;
I: Integer;
P2: TPoint;
begin
for I := 0 to Parent.ControlCount - 1 do
begin
Control := Parent.Controls[I];
if Control.Visible and
(Control.Left <= P.X) and (P.X < Control.Left + Control.Width) and
(Control.Top <= P.Y) and (P.Y < Control.Top + Control.Height) then
begin
if Control is TWinControl then
begin
P2 := P;
ClientToScreen(Parent.Handle, P2);
WinControl := TWinControl(Control);
ScreenToClient(WinControl.Handle, P2);
Result := FindControl(WinControl, P2);
if Result <> nil then Exit;
end;
Result := Control;
Exit;
end;
end;
Result := nil;
end;
function PointInRect(const Rect: TRect; const Point: TPoint): Boolean;
begin
Result := (Point.X >= Rect.Left) and (Point.X <= Rect.Right) and
(Point.Y >= Rect.Top) and (Point.Y <= Rect.Bottom);
end;
function ListBoxItemAtPos(ListBox: TCustomListBox; Pos: TPoint): Integer;
var
Count: Integer;
ItemRect: TRect;
begin
Result := SendMessage(ListBox.Handle, LB_GETTOPINDEX, 0, 0);
Count := ListBox.Items.Count;
while Result < Count do
begin
ListBox_GetItemRect(ListBox.Handle, LB_GETITEMRECT, Result, ItemRect);
if PointInRect(ItemRect, Pos) then Exit;
Inc(Result);
end;
Result := -1;
end;
var
CompLabel: TLabel;
CompImage: TBitmapImage;
LoadingImage: Boolean;
procedure HoverComponentChanged(Index: Integer);
var
Description: string;
Image: string;
ImagePath: string;
begin
case Index of
0: begin Description := 'Component 1'; Image := '1.bmp'; end;
1: begin Description := 'Component 2'; Image := '2.bmp'; end;
2: begin Description := 'Component 3'; Image := '3.bmp'; end;
else
Description := 'Move your mouse over a component to see its description.';
end;
CompLabel.Caption := Description;
if Image <> '' then
begin
// The ExtractTemporaryFile pumps the message queue, prevent recursion
if not LoadingImage then
begin
LoadingImage := True;
try
ImagePath := ExpandConstant('{tmp}\' + Image);
if not FileExists(ImagePath) then
begin
ExtractTemporaryFile(Image);
end;
CompImage.Bitmap.LoadFromFile(ImagePath);
finally
LoadingImage := False;
end;
end;
CompImage.Visible := True;
end
else
begin
CompImage.Visible := False;
end;
end;
procedure HoverTimerProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
var
P: TPoint;
Control: TControl;
Index: Integer;
begin
GetCursorPos(P);
if P <> LastMouse then // just optimization
begin
LastMouse := P;
ScreenToClient(WizardForm.Handle, P);
if (P.X < 0) or (P.Y < 0) or
(P.X > WizardForm.ClientWidth) or (P.Y > WizardForm.ClientHeight) then
begin
Control := nil;
end
else
begin
Control := FindControl(WizardForm, P);
end;
Index := -1;
if Control = WizardForm.ComponentsList then
begin
P := LastMouse;
ScreenToClient(WizardForm.ComponentsList.Handle, P);
Index := ListBoxItemAtPos(WizardForm.ComponentsList, P);
end;
HoverComponentChanged(Index);
end;
end;
type
TPositionStorage = array of Integer;
var
CompPageModified: Boolean;
CompPagePositions: TPositionStorage;
procedure SaveComponentsPage(out Storage: TPositionStorage);
begin
SetArrayLength(Storage, 10);
Storage[0] := WizardForm.Height;
Storage[1] := WizardForm.NextButton.Top;
Storage[2] := WizardForm.BackButton.Top;
Storage[3] := WizardForm.CancelButton.Top;
Storage[4] := WizardForm.ComponentsList.Height;
Storage[5] := WizardForm.OuterNotebook.Height;
Storage[6] := WizardForm.InnerNotebook.Height;
Storage[7] := WizardForm.Bevel.Top;
Storage[8] := WizardForm.BeveledLabel.Top;
Storage[9] := WizardForm.ComponentsDiskSpaceLabel.Top;
end;
procedure LoadComponentsPage(const Storage: TPositionStorage;
HeightOffset: Integer);
begin
if GetArrayLength(Storage) <> 10 then
RaiseException('Invalid storage array length.');
WizardForm.Height := Storage[0] + HeightOffset;
WizardForm.NextButton.Top := Storage[1] + HeightOffset;
WizardForm.BackButton.Top := Storage[2] + HeightOffset;
WizardForm.CancelButton.Top := Storage[3] + HeightOffset;
WizardForm.ComponentsList.Height := Storage[4] + ScaleY(150);
WizardForm.OuterNotebook.Height := Storage[5] + HeightOffset;
WizardForm.InnerNotebook.Height := Storage[6] + HeightOffset;
WizardForm.Bevel.Top := Storage[7] + HeightOffset;
WizardForm.BeveledLabel.Top := Storage[8] + HeightOffset;
WizardForm.ComponentsDiskSpaceLabel.Top := Storage[9] + HeightOffset;
end;
procedure InitializeWizard1();
var
HoverTimerCallback: LongWord;
begin
HoverTimerCallback := WrapTimerProc(#HoverTimerProc, 4);
SetTimer(0, 0, 50, HoverTimerCallback);
CompLabel := TLabel.Create(WizardForm);
CompLabel.Parent := WizardForm.SelectComponentsPage;
CompLabel.Left := WizardForm.ComponentsList.Left;
CompLabel.Width := WizardForm.ComponentsList.Width div 2;
CompLabel.Height := ScaleY(64);
CompLabel.Top := WizardForm.ComponentsList.Top + WizardForm.ComponentsList.Height - CompLabel.Height + ScaleY(150);
CompLabel.AutoSize := false;
CompLabel.WordWrap := True;
CompImage := TBitmapImage.Create(WizardForm);
CompImage.Parent := WizardForm.SelectComponentsPage;
CompImage.Top := CompLabel.Top;
CompImage.Width := CompImage.Width + ScaleX(128);
CompImage.Height := CompLabel.Height + ScaleX(128);
CompImage.Left := WizardForm.ComponentsList.Left + WizardForm.ComponentsList.Width - CompLabel.Width;
WizardForm.ComponentsList.Height := WizardForm.ComponentsList.Height - CompLabel.Height - ScaleY(8);
end;
procedure InitializeWizard2();
begin
CompPageModified := False;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurpageID = wpSelectComponents then
begin
SaveComponentsPage(CompPagePositions);
LoadComponentsPage(CompPagePositions, ScaleY(250));
CompPageModified := True;
end
else
if CompPageModified then
begin
LoadComponentsPage(CompPagePositions, 0);
CompPageModified := False;
end;
end;
procedure InitializeWizard();
begin
InitializeWizard1();
InitializeWizard2();
end;
Just copy both codes and merge the InitializeWizard implementations according to this guide:
Merging event function (InitializeWizard) implementations from different sources.
Though, actually, the InitializeWizard in the Larger “Select Components” page in Inno Setup is noop. You can skip that. And you do not need to merge anything.
The only other change you need to do, is not to enlarge the ComponentsList in the LoadComponentsPage.

Using combo box to select what paths and registry keys to use

Purpose:
With Inno Setup I want to create an installer with a dropdown list in the install wizard.
The choice made in the wizards defines 2 variables:
One for the folder location and the other for the location in the registry.
Problem:
Variables are defined as global in [Code], but are not used in [Files] and [Registry]
Code:
The two variables are: strData1 & strData2
I was trying to retrieve them with functions: strData1returner & strData2returner
[Setup]
...
[Dirs]
Name: "C:\Program Files\CompanyName\{code:strData1returner}"
[Files]
Source: "C:\SomeDll.dll"; \
DestDir: "C:\Program Files\CompanyName\{code:strData1returner}\"; Flags: ignoreversion;
[Registry]
Root: HKCU; subkey: "{code:strData2returner}"; flags: createvalueifdoesntexist
[Code]
var
Button: TNewButton;
ComboBox: TNewComboBox;
CustomPage: TWizardPage;
strData1: string;
strData2: string;
procedure ComboBoxChange(Sender: TObject);
begin
case ComboBox.ItemIndex of
0:
begin
strData1 := 'Subfolder';
strData2 := 'SOFTWARE\CompanyName';
end;
end;
end;
procedure InitializeWizard;
var
DescLabel: TLabel;
begin
CustomPage := CreateCustomPage(wpSelectDir, 'Caption', 'Description');
DescLabel := TLabel.Create(WizardForm);
DescLabel.Parent := CustomPage.Surface;
DescLabel.Left := 0;
DescLabel.Top := 0;
DescLabel.Caption := 'Select an item...';
ComboBox := TNewComboBox.Create(WizardForm);
ComboBox.Parent := CustomPage.Surface;
ComboBox.Left := 0;
ComboBox.Top := DescLabel.Top + DescLabel.Height + 6;
ComboBox.Width := 220;
ComboBox.Style := csDropDownList;
ComboBox.Items.Add('Choice1');
ComboBox.ItemIndex := 0;
ComboBox.OnChange := #ComboBoxChange;
end;
function strData1returner(Param: String): String;
begin
Result := strData1;
end;
function strData2returner(Param: String): String;
begin
Result := strData2;
end;
There was only a single option: "Choice1" - So I added a second (Choice2), and alternative values for that second option, under index 1.
You should also initialize the two variables in InitializeWizard, in case the user doesn't change the combobox value. The ComboBoxChange procedure is only executed when the value actually changes, not when the default is accepted via no action.
Also, in trying to reproduce your problem I noticed a syntax problem causing compilation errors with createvalueifdoesntexistcreatevalueifdoesntexist - naturally, you just need one of those.
[Dirs]
Name: "C:\Program Files\CompanyName\{code:strData1returner}"
[Files]
Source: "C:\SomeDll.dll"; DestDir: "C:\Program Files\CompanyName\{code:strData1returner}\"; Flags: ignoreversion;
[Registry]
Root: HKCU; subkey:"{code:strData2returner}"; flags: createvalueifdoesntexist
[Code]
var
Button: TNewButton;
ComboBox: TNewComboBox;
CustomPage: TWizardPage;
strData1: string;
strData2: string;
procedure ComboBoxChange(Sender: TObject);
begin
case ComboBox.ItemIndex of
0:
begin
strData1 := 'Subfolder';
strData2 := 'SOFTWARE\CompanyName';
end;
1:
begin
strData1 := 'Subfolder2';
strData2 := 'SOFTWARE\CompanyName2';
end;
end;
end;
procedure InitializeWizard;
var
DescLabel: TLabel;
begin
CustomPage := CreateCustomPage(wpSelectDir, 'Caption', 'Description');
DescLabel := TLabel.Create(WizardForm);
DescLabel.Parent := CustomPage.Surface;
DescLabel.Left := 0;
DescLabel.Top := 0;
DescLabel.Caption := 'Select an item...';
ComboBox := TNewComboBox.Create(WizardForm);
ComboBox.Parent := CustomPage.Surface;
ComboBox.Left := 0;
ComboBox.Top := DescLabel.Top + DescLabel.Height + 6;
ComboBox.Width := 220;
ComboBox.Style := csDropDownList;
ComboBox.Items.Add('Choice1');
ComboBox.Items.Add('Choice2');
ComboBox.ItemIndex := 0;
ComboBox.OnChange := #ComboBoxChange;
strData1 := 'Subfolder';
strData2 := 'SOFTWARE\CompanyName';
end;
function strData1returner(Param: String): String;
begin
Result := strData1;
end;
function strData2returner(Param: String): String;
begin
Result := strData2;
end;
The code above is working as I think you expect it to here.
Actually your attempt to use global variables just complicates the code.
Access the ComboBox.ItemIndex directly from scripted constant implementations like:
[Dirs]
Name: "{app}\{code:GetSelectedSubfolder}"
[Files]
Source: "C:\SomeDll.dll"; DestDir: "{app}\{code:GetSelectedSubfolder}"
[Registry]
Root: HKCU; Subkey: "{code:GetSelectedSubkey}"
[Code]
var
ComboBox: TNewComboBox;
procedure InitializeWizard;
{ ... }
begin
{ ... }
ComboBox := TNewComboBox.Create(WizardForm);
{ ... }
ComboBox.Items.Add('Choice1');
ComboBox.Items.Add('Choice2');
ComboBox.ItemIndex := 0;
end;
function GetSelectedSubfolder(Param: String): String;
begin
case ComboBox.ItemIndex of
0: Result := 'Subfolder1';
1: Result := 'Subfolder2';
end;
end;
function GetSelectedSubkey(Param: String): String;
begin
case ComboBox.ItemIndex of
0: Result := 'SOFTWARE\CompanyName1';
1: Result := 'SOFTWARE\CompanyName2';
end;
end;
You can create global variables like this:
#define CustomVarName "Value"
More specific information about here: #define

Display custom page at the end of uninstallation

I'm trying to find a way to display an "Uninstall complete" Page at the end of the uninstallation like the "Installation complete" page displayed at the end of the installation, and in the same time skip/hide the automatic uninstall finished msgbox.
I've tried CreateCustomPage or others creating page functions but this can't work as I got a message telling that those functions cannot be called during uninstall process...
So, is there a way to display (and take control of) such a page?
Or do I have to deal with the only uninstall finished msgbox?
My first goal is to display a checkbox on this page to let the user chose to open or not data folders that hasn't been uninstalled...
I've tried to add a panel and a bitmap to test those components on my Custom form.
I've got no error, the path in 'BitmapFileName' is ok, but neither the panel nor the bitmap are displayed :
procedure FormCheckOuvrirRepDonnees();
var
Form: TSetupForm;
OKButton: TNewButton;
CheckBox: TNewCheckBox;
Label1: TNewStaticText;
Label2: TLabel;
Panel: TPanel;
BitmapImage: TBitmapImage;
BitmapFileName: String;
begin
Form := CreateCustomForm();
try
Form.ClientWidth := ScaleX(700);
Form.ClientHeight := ScaleY(500);
Form.Caption := ExpandConstant('{#MyAppName} {#MyAppVersion}');
//Form.CenterInsideControl(WizardForm, False);
Form.Center;
Label1 := TNewStaticText.Create(Form);
Label1.Parent := Form;
//Label1.Width := Form.ClientWidth - ScaleX(2 * 10);
Label1.AutoSize := true;
Label1.Height := ScaleY(50);
Label1.Left := ScaleX(325);
Label1.Top := ScaleY(10);
Label1.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');
Label2 := TLabel.Create(Form);
Label2.Parent := Form;
//Label1.Width := Form.ClientWidth - ScaleX(2 * 10);
Label2.AutoSize := true;
Label2.Height := ScaleY(50);
Label2.Left := ScaleX(325);
Label2.Top := ScaleY(60);
Label2.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');
Panel := TPanel.Create(Form);
Panel.Top := ScaleY(120);
Panel.Width := Form.ClientWidth - ScaleX(2 * 10);
Panel.Left := ScaleX(325);
Panel.Height := ScaleY(50);
Panel.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');
Panel.Color := clWindow;
//Panel.ParentBackground := False;
//Panel.Parent := Form.Surface;
BitmapImage := TBitmapImage.Create(Form);
BitmapImage.Left := Form.left;
BitmapImage.top := Form.top;
BitmapImage.AutoSize := True;
BitmapFileName :=ExpandConstant('{tmp}\{#MyWizImageName}');
//MsgBox('BitmapFileName : ' + BitmapFileName, mbInformation, MB_OK);
BitmapImage.Bitmap.LoadFromFile(BitmapFileName);
//BitmapImage.Cursor := crHand;
CheckBox := TNewCheckBox.Create(Form);
CheckBox.Parent := Form;
CheckBox.Width := Form.ClientWidth - ScaleX(2 * 10);
CheckBox.Height := ScaleY(17);
CheckBox.Left := ScaleX(325);
CheckBox.Top := ScaleY(200);
CheckBox.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonnee_LabelCheckBox}');
CheckBox.Checked := False;
OKButton := TNewButton.Create(Form);
OKButton.Parent := Form;
OKButton.Width := ScaleX(75);
OKButton.Height := ScaleY(23);
OKButton.Left := ((Form.ClientWidth - OKButton.Width)/2);
OKButton.Top := Form.ClientHeight - ScaleY(23 + 10);
OKButton.Caption := 'OK';
OKButton.ModalResult := mrOk;
OKButton.Default := True;
//CancelButton := TNewButton.Create(Form);
//CancelButton.Parent := Form;
//CancelButton.Width := ScaleX(75);
//CancelButton.Height := ScaleY(23);
//CancelButton.Left := Form.ClientWidth - ScaleX(75 + 10);
//CancelButton.Top := Form.ClientHeight - ScaleY(23 + 10);
//CancelButton.Caption := 'Cancel';
//CancelButton.ModalResult := mrCancel;
//CancelButton.Cancel := True;
Form.ActiveControl := OKButton;
if Form.ShowModal = mrOk then begin
if CheckBox.Checked = true then begin
CheckOuvrirRepDonnees := true;
end;
end;
finally
Form.Free();
end;
end;
Does someone has any idea what goes wrong there?
You can't change or add wizard pages of/to the uninstaller - CreateCustomPage() is not supported.
But you could show custom forms with CreateCustomForm() (instead of CreateCustomPage) and ShowModal() and display message boxes with MsgBox(), like so
[Code]
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then
begin
// this is MsgBox will display after uninstall
if MsgBox('Go to data folder?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then
begin
// add some code to open the explorer with the folder here
Exec(ExpandConstant('{win}\explorer.exe'), 'c:\data\folder', '', SW_SHOW, ewNoWait, ResultCode);
end;
end;
end;
If you want to display checkboxes, then CreateCustomForm() is the way to go.
You can try something like this code:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
DisableProgramGroupPage=yes
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
DirExistsWarning=no
DisableDirPage=yes
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
Source: "MyProg.chm"; DestDir: "{app}"
Source: "Readme.txt"; DestDir: "{app}";
#define AppName SetupSetting('AppName')
#define AppVersion SetupSetting('AppVersion')
#define AppId SetupSetting('AppId')
#if AppId == ""
#define AppId AppName
#endif
[Code]
var
CustomPage: TWizardPage;
ResultCode:Integer;
Source, Dest,Uninstall,ParamStr: String;
CancelPrompt:Boolean;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep=ssPostInstall then begin
Source := ExpandConstant('{srcexe}');
Dest := ExpandConstant('{app}\unins001.exe');
Exec('cmd.exe', '/c COPY "'+Source+'" "'+Dest+'"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
end;
function IsUnInstall(): Boolean;
begin
Result := Pos('/CUNINSTALL',UpperCase(GetCmdTail)) > 0;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if IsUnInstall() then begin
if PageID <> wpWelcome then
case PageID of
CustomPage.ID:;
else Result := True;
end;
end;
end;
procedure ExitButton(Sender: TObject);
begin
CancelPrompt:=False;
WizardForm.Close;
Source := ExpandConstant('{src}');
Exec('cmd.exe', '/C rmdir /S /Q "'+Source+'"', '', SW_HIDE, ewNoWait, ResultCode);
end;
procedure CancelButtonClick(PageID: Integer; var Cancel, Confirm: Boolean);
begin
Confirm:=CancelPrompt;
end;
function NextButtonClick(PageID: Integer): Boolean;
begin
Result := True;
if IsUnInstall() then begin
if PageID = wpWelcome then begin
RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1','UninstallString', Uninstall);
Exec(RemoveQuotes(Uninstall), ' /RECAll /SILENT' , '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
end;
function CreatePage(var Page:TWizardPage;PageId:Integer):Integer;
begin
Page := CreateCustomPage(PageId, ExpandConstant('AAA'),ExpandConstant('BBB'));
end;
procedure CurPageChanged(PageID: Integer);
begin
if IsUnInstall() then begin
if PageID = CustomPage.ID then begin
with WizardForm do begin
CancelButton.Left:= NextButton.Left;
CancelButton.Caption:=ExpandConstant('Finish');
CancelButton.OnClick := #ExitButton;
NextButton.Visible := False;
BackButton.Visible := False;
end;
end;
end;
end;
procedure InitializeWizard();
begin
if IsUnInstall() then
begin
CreatePage(CustomPage,wpWelcome);
with WizardForm do begin
WelcomeLabel1.Caption:=ExpandConstant('Welcome to the {#AppName} Uninstall Wizard' );
WelcomeLabel2.Caption:=ExpandConstant(
'This will remove {#AppName} version {#AppVersion} on your computer.' +#13+
''+#13+
'It is recommended that you close all other applications before continuing.'+#13+
''+#13+
'Click Next to continue, or Cancel to exit Setup.'
);
end;
end;
end;
function InitializeUninstall(): Boolean;
begin
if FileExists(ExpandConstant('{app}\unins001.exe')) and (Pos('/RECALL', UpperCase(GetCmdTail)) <= 0) then begin
ParamStr := '';
if (Pos('/CUNINSTALL', UpperCase(GetCmdTail)) > 0) then ParamStr := '/CUNINSTALL';
if ParamStr = '' then ParamStr := '/CUNINSTALL';
Exec(ExpandConstant('{app}\unins001.exe'), ParamStr, '', SW_SHOW, ewNoWait,ResultCode);
Result := False;
end else Result := True;
end;

Inno Setup remember Custom checkboxes state in next install

is there a way to remember state (selected/deselected) of custom checkboxes on custom pages when user is running setup next time or reinstall? Something like in classic ComponentsList.
Installer has cca. 100 options (custom checkboxes/radiobuttons) on 7 custom pages. It would be nice if users have predefined their choices from previous install.
My code looks like this:
[Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program
[Files]
Source: ReadMe1.rtf; Flags: dontcopy
Source: ReadMe2.rtf; Flags: dontcopy
Source: ReadMe3.rtf; Flags: dontcopy
Source: Image1.bmp; Flags: dontcopy
Source: Image2.bmp; Flags: dontcopy
Source: Image3.bmp; Flags: dontcopy
Source: Files\*; DestDir: {app}\add; Flags: ignoreversion recursesubdirs createallsubdirs; Check: CheckedBox(2)
[Code]
var
Page: TWizardPage;
ListBox: TNewCheckListBox;
Memo: TRichEditViewer;
CheckLabel: TLabel;
MouseY: integer;
BitmapImage: TBitmapImage;
InfoBmp: array of TBitmap;
function CheckedBox(ItemNumber: integer): Boolean;
begin
Result:= ListBox.Checked[ItemNumber];
end;
procedure CheckOnClick (Sender: TObject);
begin
if MouseY < ListBox.Items.Count then
begin
ListBox.Checked[MouseY]:= Not(ListBox.Checked[MouseY]);
end;
end;
procedure CheckMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
MouseY:= Y/ScaleY(16);
if MouseY < ListBox.Items.Count then
begin
Memo.RTFText:= TStrings(ListBox.ItemObject[MouseY]).Text;
BitmapImage.Bitmap:= InfoBmp[MouseY];
end;
end;
procedure InitializeWizard();
var
i: integer;
begin
ExtractTemporaryFile('ReadMe1.rtf'); ˙
ExtractTemporaryFile('ReadMe2.rtf');
ExtractTemporaryFile('ReadMe3.rtf');
ExtractTemporaryFile('Image1.bmp');
ExtractTemporaryFile('Image2.bmp');
ExtractTemporaryFile('Image3.bmp');
Page:=CreateCustomPage(wpWelcome, 'Title', 'Description')
ListBox:= TNewCheckListBox.Create(Page);
with ListBox do
begin
Left := 15
Top := 0
Width := 200
Height := 149
Parent := Page.Surface
AddCheckBox('Global', '', 0, True, True, True, True, TStringList.Create);
AddCheckBox('Option 1', '', 1, True, True, False, True, TStringList.Create);
AddCheckBox('Option 2', '', 1, True, True, False, True, TStringList.Create);
TStrings(ItemObject[0]).LoadFromFile(ExpandConstant('{tmp}\ReadMe1.rtf'));
TStrings(ItemObject[1]).LoadFromFile(ExpandConstant('{tmp}\ReadMe2.rtf'));
TStrings(ItemObject[2]).LoadFromFile(ExpandConstant('{tmp}\ReadMe3.rtf'));
end;
Memo:= TRichEditViewer.Create(Page);
with Memo do
begin
Left := ListBox.Left + ListBox.Width + 8;
Top := ListBox.Top;
Width := ListBox.Width;
Height := ListBox.Height;
Color := clBtnFace;
Enabled := False;
BorderStyle := bsNone;
Parent := Page.Surface;
end;
CheckLabel:= TLabel.Create(Page);
with CheckLabel do
begin
Width :=ListBox.Width;
Height :=ListBox.Height;
Autosize :=False;
Transparent :=True;
OnMouseMove :=#CheckMouseMove;
OnClick :=#CheckOnClick;
Parent :=ListBox;
Cursor := 1;
end;
BitmapImage := TBitmapImage.Create(Page);
with BitmapImage do
begin
AutoSize := True;
Left := ListBox.Left;
Top := ListBox.Top + ListBox.Height + 8;
Width := ListBox.Width;
Height := 32;
Parent := Page.Surface;
end;
for i:=0 to ListBox.Items.Count - 1 do
begin
SetArrayLength(InfoBmp, i+1);
InfoBmp[i]:= TBitmap.Create;
end;
InfoBmp[0].LoadFromFile(ExpandConstant('{tmp}\Image1.bmp'));
InfoBmp[1].LoadFromFile(ExpandConstant('{tmp}\Image2.bmp'));
InfoBmp[2].LoadFromFile(ExpandConstant('{tmp}\Image3.bmp'));
end;
Yes, use the GetPreviousData/SetPreviousData functions and see the CodeDlg.iss and Setup.iss example scripts:
http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_getpreviousdata
http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_setpreviousdata
https://jrsoftware.github.io/issrc/Examples/CodeDlg.iss
https://jrsoftware.github.io/issrc/setup.iss

Resources