InnoSetup - GIF backgroung image? [duplicate] - inno-setup

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).

Related

Inno setup - adding an animated gif [duplicate]

I have prepared simple script that displays image under ProgressGauge bar on wpInstalling Page.
But... I need more complex functionality.
What I need is multiple images show, each after X (e.g. 7) seconds (with loop when installation longer then X secs * number of images) or each after X (e.g. 10) percent of installation. I have tried to embed images display in ProgressGauge.Position, but I failed.
Here is what I have:
procedure CurPageChanged(CurPageID: Integer);
var
BmpFile: TBitmapImage;
begin
ExtractTemporaryFile('01.bmp');
ExtractTemporaryFile('02.bmp');
ExtractTemporaryFile('03.bmp');
if CurPageID = wpInstalling then
begin
BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\01.bmp'));
BmpFile.Width:= ScaleX(420);
BmpFile.Height:= ScaleY(180);
BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
// BmpFile:= TBitmapImage.Create(WizardForm);
// BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\03.bmp'));
// BmpFile.Width:= ScaleX(420);
// BmpFile.Height:= ScaleY(400);
// BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
// BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
// BmpFile:= TBitmapImage.Create(WizardForm);
// BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\03.bmp'));
// BmpFile.Width:= ScaleX(420);
// BmpFile.Height:= ScaleY(400);
// BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
// BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
end;
end;
The goal is:
On the wpInstalling there should be X images displayed, every next per X seconds or after X percent of installation.
Since the ProgressGauge has no progress change events and there is no way to process setup application messages you will need to use the Windows API timer. This timer needs a callback function which you can't define in Inno Setup script unfortunately so you will need some external library to do this job for you. However there's the InnoCallback library which can do exactly this.
For the following code copy the InnoCallback.dll library into your setup directory, merge this code with your Inno Setup script and implement some kind of a slideshow page turning in the OnSlideTimer event which will be called periodically (with the current settings each second).
[Files]
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy
[code]
var
TimerID: Integer;
type
TTimerProc = procedure(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
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';
procedure OnSlideTimer(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
begin
{ here you can turn your slideshow pages; use some variable to store the }
{ current index of the slide you are on, note that this procedure is called }
{ periodically each 1000 ms (see below why), so here you can also check the }
{ progress value, if you want to }
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, 1000, TimerCallback);
end;
procedure KillSlideTimer;
begin
if TimerID <> 0 then
begin
if KillTimer(0, TimerID) then
TimerID := 0;
end;
end;
function InitializeSetup: Boolean;
begin
Result := True;
TimerID := 0;
end;
procedure DeinitializeSetup;
begin
KillSlideTimer;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpInstalling then
StartSlideTimer
else
KillSlideTimer;
end;

How to close finished Inno Setup installer after a certain time?

How to close the installer on the "Finished" page after a certain time?
It could also be interpreted as: how to close the installer after some time of non-activity? (close/cancel install). Is this possible?
Setup a timer once the "Finished" page displays to trigger the close.
[Code]
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord;
external 'SetTimer#User32.dll stdcall';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord;
external 'KillTimer#User32.dll stdcall';
var
PageTimeoutTimer: LongWord;
PageTimeout: Integer;
procedure UpdateFinishButton;
begin
WizardForm.NextButton.Caption :=
Format(SetupMessage(msgButtonFinish) + ' - %ds', [PageTimeout]);
end;
procedure PageTimeoutProc(
H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
if PageTimeout > 1 then
begin
Dec(PageTimeout);
UpdateFinishButton;
end
else
begin
WizardForm.NextButton.OnClick(WizardForm.NextButton);
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
PageTimeout := 10;
UpdateFinishButton;
PageTimeoutTimer := SetTimer(0, 0, 1000, CreateCallback(#PageTimeoutProc));
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID = wpFinished then
begin
KillTimer(0, PageTimeoutTimer);
PageTimeoutTimer := 0;
end;
Result := True;
end;
For CreateCallback function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback function from InnoTools InnoCallback library.
Related questions:
MsgBox - Make unclickable OK Button and change to countdown - Inno Setup;
Inno Setup - Automatically submitting uninstall prompts.

How to Delete / Hide / Disable [OK] button on message box

Here's the code...
ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
const
MB_TIMEDOUT = 32000;
MB_ICONERROR = $10;
MB_ICONQUESTION = $20;
MB_ICONWARNING = $30;
MB_ICONINFORMATION = $40;
function MessageBoxTimeout(hWnd: HWND; lpText: string; lpCaption: string;
uType: UINT; wLanguageId: Word; dwMilliseconds: DWORD): Integer;
external 'MessageBoxTimeout{#AW}#user32.dll stdcall';
procedure InitializeWizard;
begin
MessageBoxTimeout(WizardForm.Handle, 'Some ' +
'message', 'Setup', MB_OK or MB_ICONINFORMATION, 0, 5000);
end;
I just want the message box to appear without the button. What code to be added or removed? Where would I insert it? Thanks!
Does this a code from How to disable the “Next” button on the wizard form in Inno Setup? work with my script? I can't seem to to make it working.
You cannot.
But as you already know from MsgBox - Make unclickable OK Button and change to countdown - Inno Setup, you can implement the message box from a scratch yourself. This way, you can customize it any way you want.
Actually, all you need is to remove the button from my answer to the above question.
[Code]
function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord;
lpTimerFunc: LongWord): LongWord; external 'SetTimer#user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: LongWord): BOOL;
external 'KillTimer#user32.dll stdcall';
var
TimeoutForm: TSetupForm;
procedure TimeoutProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
TimeoutForm.Tag := TimeoutForm.Tag - 1;
if TimeoutForm.Tag = 0 then
begin
TimeoutForm.Close;
end;
end;
procedure TimeoutMessageBoxCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
{ Prevent the dialog from being closed by the X button and Alt-F4 }
CanClose := (TimeoutForm.Tag = 0);
end;
procedure TimeoutMessageBox(Message: string; Seconds: Integer);
var
MessageLabel: TLabel;
Timer: LongWord;
begin
TimeoutForm := CreateCustomForm;
try
TimeoutForm.ClientWidth := ScaleX(256);
TimeoutForm.ClientHeight := ScaleY(64);
TimeoutForm.Caption := 'Information';
TimeoutForm.Position := poMainFormCenter;
TimeoutForm.OnCloseQuery := #TimeoutMessageBoxCloseQuery;
TimeoutForm.Tag := Seconds;
MessageLabel := TLabel.Create(TimeoutForm);
MessageLabel.Top := ScaleY(16);
MessageLabel.Left := ScaleX(16);
MessageLabel.AutoSize := True;
MessageLabel.Caption := Message;
MessageLabel.Parent := TimeoutForm;
Timer := SetTimer(0, 0, 1000, CreateCallback(#TimeoutProc));
try
TimeoutForm.ShowModal();
finally
KillTimer(0, Timer);
end;
finally
TimeoutForm.Free();
TimeoutForm := nil;
end;
end;
For CreateCallback function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback function from InnoTools InnoCallback library.

How to have a custom click sound on button click in Inno Setup (Back + Next + Cancel)?

How to have button click sounds in Inno setup?
I mean a different for "Back", "Next" and "Cancel".
I know there might be some questions and also answers to them, but I'm new to this site and I need some help.
Thanks in advance...
You can use Inno Media Player to play sounds.
See question Playing sound during an Inno Setup install.
To trigger the sound on button clicks use a code like:
[Files]
Source: "next.mp3"; Flags: dontcopy
Source: "back.mp3"; Flags: dontcopy
Source: "cancel.mp3"; Flags: dontcopy
Source: "MediaPlayer.dll"; Flags: dontcopy
[Code]
type
TDirectShowEventProc = procedure(EventCode, Param1, Param2: Integer);
function DSInitializeAudioFile(
FileName: string; CallbackProc: TDirectShowEventProc): Boolean;
external 'DSInitializeAudioFile#files:mediaplayer.dll stdcall';
function DSPlayMediaFile: Boolean;
external 'DSPlayMediaFile#files:mediaplayer.dll stdcall';
function DSStopMediaPlay: Boolean;
external 'DSStopMediaPlay#files:mediaplayer.dll stdcall';
function GetTickCount: DWORD;
external 'GetTickCount#kernel32.dll stdcall';
procedure DeinitializeSetup;
begin
DSStopMediaPlay;
end;
var
PageChanged: DWORD;
procedure CurPageChanged(CurPageID: Integer);
begin
PageChanged := GetTickCount;
end;
procedure DirectShowEvent(EventCode, Param1, Param2: Integer);
begin
{ dummy }
end;
procedure PlaySound(FileName: string);
begin
DSStopMediaPlay;
ExtractTemporaryFile(FileName);
if DSInitializeAudioFile(ExpandConstant('{tmp}\') + FileName, #DirectShowEvent) then
begin
DSPlayMediaFile;
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
{ NextButtonClick is called even for skipped pages (like the Welcome page) and }
{ during silent installs. To detect that, we check if at least half }
{ second elapsed since the page was shown }
if GetTickCount - PageChanged > 500 then
begin
PlaySound('next.mp3');
end;
Result := True;
end;
function BackButtonClick(CurPageID: Integer): Boolean;
begin
PlaySound('back.mp3');
Result := True;
end;
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
PlaySound('cancel.mp3');
end;

Inno Setup add time release to button [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Friends
add time "Button Next or Install" to get released
on the page "Ready"
15 second
15,14,13,12,11,10,9,8,7,6,5,4 time after the button is released to click
example
Since there is no built-in timer in InnoSetup at this time, you'll need to use Windows API for this. Except that, function which will be used here needs a callback function which must be wrapped for instance by the InnoCallback used by the following script.
It shows how to disable the next button on the select directory page for 5 seconds, but you can simply change the parameter of the DisableNextButton function, which is the interval in seconds to value that you want as well as you can change for which page you will use it. There is also the remaining time value in the next button caption:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
[Files]
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy
[Code]
var
Counter: Integer;
TimerID: Integer;
type
TTimerProc = procedure(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
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';
procedure OnTimerTick(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
begin
Counter := Counter - 1;
if Counter <= 0 then
begin
WizardForm.NextButton.Enabled := True;
WizardForm.NextButton.Caption := SetupMessage(msgButtonNext);
if TimerID <> 0 then
KillTimer(0, TimerID);
end
else
WizardForm.NextButton.Caption := SetupMessage(msgButtonNext) +
IntToStr(Counter);
end;
procedure DisableNextButton(Timeout: Integer);
var
TimerCallback: LongWord;
begin
Counter := Timeout;
WizardForm.NextButton.Enabled := False;
WizardForm.NextButton.Caption := SetupMessage(msgButtonNext) +
IntToStr(Counter);
TimerCallback := WrapTimerProc(#OnTimerTick, 4);
TimerID := SetTimer(0, 0, 1000, TimerCallback);
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpSelectDir then
DisableNextButton(5);
end;
Here is the screenshot:

Resources