I'm searching for quite a while now for an extension for Inno Setup to use a video file, for example an AVI or maybe a .png sequence as a splash-screen for my installation (the usage of an alpha channel would be a HUGE plus but is not a must have).
There are several .dll's to use static pictures with a fade-in and fade-out but I couldn't find anything to use as video file for that purpose.
As far as I know, I can use any kind of .dll with Inno Setup. For example I can use the popular bass.dll for audio playback even though it has no "real" Inno support but Inno can call the functions of that .dll.
So is there any program out there that would allow me to do this?
Any tip in that direction would be very helpful.
Edit: This may be possible with Qt, I know you can make exactly those frame based splash-screens for your applications but I'm not sure if it's possible to use Qt with Inno Setup?
I have founded the Inno Media Player project which is able to embed the video and audio playback into the InnoSetup wizard. It is based on DirectShow technology and requires at least DirectX 9 to use.
Except built-in formats it supports all DirectShow codecs, but you should consider that your target users doesn't need to have codecs for some exotic media formats and install them codec just because of the show at the installation startup would be an overkill and unfair to user.
About the transparency you wanted to have, if you find the codec that supports that, we can try to make the popup window transparent and let the DirectShow renderer draw on a layered window, but without the codec and a sample video I can't do nothing.
the libraries with a sample script you may find in the source trunk or download it from here
I wrote a simple function reference where you can find the function parameter descriptions
So to show a popup window with the video playback before the wizard form is displayed you can use the following:
Please note, that Inno Media Player is a Unicode library, and so you can use it only with Unicode versions of InnoSetup, not with ANSI ones! There is no support for ANSI versions of InnoSetup...!
[Setup]
AppName=Media Player Project
AppVersion=1.0
DefaultDirName={pf}\Media Player Project
[Files]
Source: "MediaPlayer.dll"; Flags: dontcopy
[Code]
const
EC_COMPLETE = $01;
type
TDirectShowEventProc = procedure(EventCode, Param1, Param2: Integer);
function DSPlayMediaFile: Boolean;
external 'DSPlayMediaFile#files:mediaplayer.dll stdcall';
function DSStopMediaPlay: Boolean;
external 'DSStopMediaPlay#files:mediaplayer.dll stdcall';
function DSInitializeVideoFile(FileName: WideString; WindowHandle: HWND;
var Width, Height: Integer; CallbackProc: TDirectShowEventProc): Boolean;
external 'DSInitializeVideoFile#files:mediaplayer.dll stdcall';
var
VideoForm: TSetupForm;
procedure OnMediaPlayerEvent(EventCode, Param1, Param2: Integer);
begin
if EventCode = EC_COMPLETE then
VideoForm.Close;
end;
procedure OnVideoFormShow(Sender: TObject);
begin
DSPlayMediaFile;
end;
procedure OnVideoFormClose(Sender: TObject; var Action: TCloseAction);
begin
DSStopMediaPlay;
end;
procedure InitializeWizard;
var
Width: Integer;
Height: Integer;
begin
VideoForm := CreateCustomForm;
VideoForm.Caption := 'Popup Video Window';
VideoForm.BorderStyle := bsNone;
VideoForm.FormStyle := fsStayOnTop;
VideoForm.Position := poScreenCenter;
VideoForm.OnShow := #OnVideoFormShow;
VideoForm.OnClose := #OnVideoFormClose;
if DSInitializeVideoFile('d:\Video.avi', VideoForm.Handle, Width,
Height, #OnMediaPlayerEvent)
then
begin
VideoForm.ClientWidth := Width;
VideoForm.ClientHeight := Height;
VideoForm.ShowModal;
end;
end;
procedure DeinitializeSetup;
begin
DSStopMediaPlay;
end;
Hope that it helps!
Related
This question already has answers here:
Image covering whole page in Inno Setup
(1 answer)
Inno Setup - Image as installer background
(2 answers)
Closed 9 months ago.
I am using the following code to add a background image,
function Page1_Create: TWizardPage;
var
Page1: TWizardPage;
// Fonts
// Pictures
PictureBox2_PictureName: String;
// Controls
PictureBox2: TBitmapImage;
begin
// This is a page creator Function. You can use the Result of it to access the controls on this Page.
Page1 := CreateCustomPage(wpWelcome, 'Title', 'Subtitle');
{ PictureBox2 (TBitmapImage) }
PictureBox2 := TBitmapImage.Create(Page1);
PictureBox2.Parent := Page1.Surface;
PictureBox2.Enabled := True;
PictureBox2.Visible := True;
PictureBox2.Left := ScaleX(0);
PictureBox2.Top := ScaleY(0);
PictureBox2.Width := ScaleX(513);
PictureBox2.Height := ScaleY(302);
PictureBox2.Anchors := [akLeft, akTop, akRight, akBottom];
PictureBox2.Stretch := True;
PictureBox2_PictureName := ExpandConstant('{tmp}\purple-skin.bmp');
ExtractTemporaryFile(ExtractFileName(PictureBox2_PictureName));
PictureBox2.Bitmap.LoadFromFile(PictureBox2_PictureName);
// Result is the newly created Page (TWizardPage).
Result := Page1;
end;
procedure InitializeWizard;
begin
PageWelcome_Create()
end;
But this does not fill the entire background. It fills like as shown by the image below,
How to fill the entire background?
Also, how to add images to the Title section (fill the entire title bar) at top and command button section (fill the entire bottom bar) at bottom?
TLDR: Your code is correct, simply repeat it for each page and the title and bottom part of the form + adjust the controls positions and dimensions (posting whole code is beyond the SO, it would be hundreds of lines of code).
Detailed answer:
Filling the entire background is quite tricky. The setup form consists of several "layers" of components placed on it.
There is no such thing as "background", there is a WizardForm: TWizardForm containing OuterNotebook: TNewNotebook which contains InnerNotebook: TNewNotebook which represents the individual pages of the installer, see https://github.com/jrsoftware/issrc/blob/main/Projects/Wizard.dfm for details.
So you need to create several images: first for title section, second for all setup pages (I assume all pages have the same dimensions) and third for bottom section.
Each control has its own handle and custom position (relative to its parent so you need to play with updating control's Left and Top position) and also there is some "space" around the controls which can be minimized by adjusting the WIdth and Height of the control.
Then load these images and show them in some control e.g. TBitmapImage as you did.
Also do not forget to handle the page refreshing.
This require a lot of work in vanilla Inno Setup. As this question is quite often I have developed a 3rd party extension specially designed for this purpose.
It is called Graphical Installer: http://www.graphical-installer.com
Please try it (it is commercial but costs only few bucks and save you hundreds of hours of work) and let me know whether it suits your needs.
For a Firemokey project i'm working on a Bitmap, which should make a Bitmap on a TImage Component to get more transparent with the time. In order to do so, i want to use a procedure like the following, but it seems as if there is no way to create a change of the transparency as the following:
procedure changeBitmapTransperency(TransparencyInPercent : Integer);
begin
{Set transparency of the bitmap to (TransparencyInPercent) percent}
end;
So, my question is, if there is a way to do so. Thanks for your time and effort,
Max
I am trying to create a Manga viewer which needs to load JPG images with large sizes like 1000*16000, my application is in delphi FMX and i have already tried using TImage, TImageViewer, TImageControl but all of them use TBitmap which trims the size to 8192 after loading the image
I tried searching for image libraries but i was unable to find anything for FMX (firemonkey)
I was thinking maybe i could load the image in a Memory stream and then copy and draw it in smaller sizes to several bitmaps ? but i don't how can i read and parse the memory stream and only pick to a certain clean height !
In the end i'm looking for a way to load and show these large (1000*16000) images in Delphi FMX
I am using delphi 10.2.3
Thanks.
Edit 01 :
I think i have found a way that might make things easy, i added the Vcl.Imaging.jpeg to uses clause in the FMX (FireMonkey) and then i used TJPEGImage and loaded the image, and i printed the width and height and they are correct and not trimmed ! so i was thinking, maybe i can read each pixel from TJPEGImage.canvas and then print it into FMX TBitmap ?, what do you think about this approach ?, do you know a good way to copy the data inside TJPEGImage to FMX TBitmap ?
Edit 02 :
I have found a new solution, the TBitmapSurface, it seems this class doesn't have the TBitmap limitations and i was able to load the image inside of it without getting trimmed ! but there is a problem! how can i give this to TImage ? if i simply say Image.bitmap.assign(TBitmapsurface), then the image gets trimmed again ! so it seems the only possible way is rewriting the TImage so it uses TBitmapSurface instead of TBitmap, any help regarding this issue is appreciated, thanks.
Here is the code for the TBitmapSurface :
bitmapSurf := TBitmapSurface.Create;
TBitmapCodecManager.LoadFromFile(path, bitmapSurf);
Unlike FMX.Graphics.TBitmap which has a size limitations of 8192 * 8192, FMX.Surface.TBitmapSurface seems to support up to 16k * 16k and possibly even more (i haven't tested), so using FMX.Surface.TBitmapSurface you can load the image without getting trimmed, and then you can easily split it into two FMX.Graphics.TBitmap (or possible more parts using the same approach)
Below you can see the code which first loads the JPG into TBitmapSurface, and then the code which splits that into two TBitmap :
var
srce, dest: TBitmapSurface;
path: string;
scan: integer;
w, h1, h2: integer;
begin
path := 'C:\tmp\Imgs\res.bmp';
srce := TBitmapSurface.Create;
TBitmapCodecManager.LoadFromFile(path, srce);
dest := TBitmapSurface.Create;
// first half
w := srce.Width;
h1 := srce.Height div 2;
dest.SetSize(w, h1, TPixelFormat.RGBA);
for scan := 0 to h1-1 do
Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan]^, srce.Width * 4);
Image1.Bitmap.Assign(dest);
// second half
h2 := srce.Height - h1;
dest.SetSize(w, h2, TPixelFormat.RGBA);
for scan := h1 to srce.Height-1 do
Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan-h1]^, srce.Width * 4);
Image2.Bitmap.Assign(dest);
end;
This answer was provided using the comments on the first post and the answer to my other question:
How to draw FMX.Surface.TBitmapSurface on FMX.Graphics.TBitmap
I am wondering why TFontDialog gives less fonts than Screen.Fonts? (For example, the Arial* font, the Comic font, etc, does not show in TFontDialog)
It also seems that the font list given by TFontDialog is the same as WordPad, whereas the font list given by Screen.Fonts is basically the same as Word.
Thank you very much for your insights!
PS:
Delphi XE,
Windows 7
PS: related SO topics:
Too many fonts when enumerating with EnumFontFamiliesEx function
Finding System Fonts with Delphi
How to use external fonts?
PS: related web pages:
TFontDialog to show all Fonts # borland.newsgroups.archived
TFontDialog to show all Fonts # delphigroups
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
lst1: TListBox;
dlgFont1: TFontDialog;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
begin
lst1.Items.AddStrings(Screen.Fonts);
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
dlgFont1.Device := fdBoth;
if dlgFont1.Execute then
begin
end;
end;
end.
Screen.Fonts returns all installed fonts, including hidden fonts as administrated in Registry\HKCU\Software\Microsoft\Windows NT\CurrentVersion\Font Management\Inactive Fonts. (Source) Apparently, TFontDialog does not display these hidden fonts.
Furthermore, some fonts listed in Screen.Fonts are not mentioned in the Font combo box of TFontDialog, but are added to the Font style combo box. Take Arial for example: the Font style lists 10 items, which seems to be the combination of the fonts Arial, Arial Black and Arial Narrow.
Different APIs, different results. Screen.Fonts uses EnumFontFamiliesEx(), which returns all installed fonts. TFontDialog uses ChooseFont() instead, which only displays the fonts that are compatible with the TFontDialog.Font and TFontDialog.Options properties.
In installer, you can easily change the small bitmap in wizard's top right corner using this code:
[Setup]
WizardSmallImageFile=gfx\bitmap.bmp
Hovewer, how to change that same bitmap in uninstaller's wizard's top right corner?
There doesn't seem to be any parameter for this.
I think one of the solution is to let the installer extract the required bitmap into the {app} and then use this code:
procedure InitializeUninstallProgressForm;
var bitmap : string;
begin
bitmap := ExpandConstant('{app}\uninst.bmp');
uninstallProgressForm.WizardSmallBitmapImage.Bitmap.LoadFromFile(bitmap);
end;
However, I don't want to have that satelite bitmap hanging in my {app}, I want it to be compiled into the uninstaller. Is it possible to somehow compile that bitmap into the uninstaller? Or is there some other way how to change that bitmap in the uninstaller's wizard?
No, there is no way to compile additional files into the uninstaller.