Inno Setup - How to increase the separation between all the components of the component list? - inno-setup

I am using this code: Long descriptions on Inno Setup components. How to increase the separation between all the components of the component list?
Example:
And i want to see this:

There's TNewCheckListBox.MinItemHeight property that you can use to make a line in the checklist box higher, effectively increasing the spacing.
But problem is that setting the property does not affect existing items. And at the time the InitializeWizard is called, the WizardForm.ComponentsList is populated already.
What you can do is to programmatically change each item caption to trigger re-measuring of the item. Simple appending of a space will do (you can even strip it after the fact, if you wish).
procedure InitializeWizard();
var
I: Integer;
begin
{ Change line height }
WizardForm.ComponentsList.MinItemHeight := ScaleY(26);
{ Trigger re-measuring of component items }
for I := 0 to WizardForm.ComponentsList.Items.Count - 1 do
begin
WizardForm.ComponentsList.ItemCaption[I] :=
WizardForm.ComponentsList.ItemCaption[I] + ' ';
end;
end;
Or you can completely give up on the built-in components mechanism and build your own components-like page using plain checkboxes. You can layout those any way you like.
For an example of implementing a custom components page, see
Inno Setup - Create a dynamic list of components/types from external source (file or folder contents)
Or similar questions for creating custom task pages:
How to split tasklist at tasks page of Inno Setup into multiple columns?
How to build a Treeview design (a task group with tasks nesting hierarchy) using Inno Setup?

Related

Can not create label on Inno Setup Welcome page

I'm trying to create a label (or a bitmap) on the welcome page using this code:
LabelTarget := TLabel.Create(WizardForm);
with LabelTarget do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(198);
Top := ScaleY(105);
Caption := 'Target';
end;
It won't work, but if I change the parent for example to WizardForm.InstallingPage it will create that label on Installing page. Where is the problem?
It's because almost whole area of the WelcomePage is covered by an opaque WelcomeLabel2.
The TLabel is not a real Windows control. It is a virtual one, drawn by the form itself. So it gets hidden by any other real Windows control, even if the TLabel is technically on top of it (what it is, as your LabelTarget is created later than the WelcomeLabel2). The WelcomeLabel2 is TStaticText, what is a real control. So it hides your LabelTarget.
To solve this either:
Shrink the WelcomeLabel2 height, or
Change your LabelTarget to TStaticText.

Inno Setup Change Caption of an existing radio button on custom options page

I'm new to Inno Setup. I'm using the Wizard pages to create an installer.
I've created an option page an some input pages.
On these input pages I get some values. Depending on such values I want to change the caption of an radio button already created in the initialize procedure of the wizard.
So, if a user entered 100-701 on an input page, I want to change the radio buttons caption on a later page to something like this:
(*) 100-701
( ) Standard
Can someone hint me, if there is a way to modify the caption or do i have to create a custom page from scratch?
Thanks,
Klaus
The CreateInputOptionPage function returns an instance of TInputOptionWizardPage class.
The class has CheckListBox property of type TNewCheckListBox, which it turn has ItemCaption property.
var
Page: TInputOptionWizardPage;
{ ... }
Page := CreateInputOptionPage(...);
Page.Add('Option 1');
Page.Add('Option 2');
{ ... }
Page.CheckListBox.ItemCaption[0] := 'Alternative caption for Option 1';
Page.CheckListBox.ItemCaption[1] := 'Alternative caption for Option 2';

Reading values from custom Inno Setup wizard pages without using global variables

On this support page for creating a custom CreateInputOptionPage, they suggest storing the values of the page by just assigning them to a variable. It's not clear however WHEN this assignment should happen.'
From what I can tell, if you assign this right when you create the page, you will get the default value. This makes sense as when the page is created, user hasn't input any "Input Query"'s yet.
Therefore, I reasoned to assign the values from the page to a variable when the 'Next' button is clicked, using function NextButtonClick(CurPageID: Integer): Boolean;
In order to do that, I needed to access the page's variable (Page.Values[0]) in the NextButtonClick function. Since Page was defined in a different function, is the only way to access those values to have Page be a global variable? That's what I've resolved to do but I was wondering if anyone out there had an alternative to global variables.
Stub of my code so far.
[Code]
var
Page: TInputOptionWizardPage;
InstallationTypeIsClient: boolean;
procedure InitializeWizard();
begin
Page := CreateInputOptionPage(wpWelcome,'Installation Type', 'Select Installation Type', 'No really, do some selecting', True, False)
Page.Add('Server Install');
Page.Add('Client Install');
Page.Values[1] := True;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID=100 then
begin
InstallationTypeIsClient := Page.Values[1];
MsgBox('InstallationTypeIsClient value is ' + Format('%d', [InstallationTypeIsClient]), mbInformation, MB_OK);
end;
Result := True;
end;
Using a global variable to store the reference to the custom page is the correct and the easiest way.
Related question: Inno Setup: Access to custom control from OnClick event of another control.
Though it's questionable whether you really need to store the user value to another variable. Just read the value from the custom page at the moment you need it.
Using global variables in indeed frowned upon, in general. But that's, when you are developing a standalone code. In this case, you are just implementing event hooks for an existing application, so you have no other choice.
The only other way is to recursively lookup the custom page in child controls of the WizardForm. It's lot of code and quite inefficient.
See my answer to Inno Setup: OnHover event for an example of recursive component iteration.

Inno Setup: WizardForm from an external form

I was trying to create an installer for my new project and used an external DLL to call a function to create a custom form. Instead of using the WizardForm, can I create the WizardForm from that custom form?
Here's the code I use to create that form:
procedure NewFormCreate;
var
rt: TTimer;
begin
NewForm:= TForm.Create(nil);
NewForm.BorderStyle := bsNone;
CreateFormFromImage(NewForm.Handle, 'form.png');
rt:= TTimer.create(nil);
rt.OnTimer:= #WFProc;
rt.Interval:= 1;
rt.Enabled:= true;
NewForm.Show;
NewForm.Enabled:= False;
end;
If I understand your question correctly, you want to use your own implementation of the WizardForm.
You cannot. You can only modify the existing WizardForm. Maybe like this:
CreateFormFromImage(WizardForm.Handle, 'form.png');
You can of course create and display your own form, and prevent the WizardForm from even displaying.
But it does not make sense. The Inno Setup is all about the WizardForm. If you do not want to use it, you do not need the Inno Setup at all. Build your custom installer in Delphi (if that's your preferred IDE).
Maybe you should explain us what do you really want to achieve. It's quite probable that you have an XY problem.
Is your X problem creating an installer with irregular shape?
Instead of scripting everything manually you can use Graphical Installer for Inno Setup (http://graphical-installer.com/) and achieve something like this in few minutes:
If you use Delphi you can use RAD & Installer (http://rad-installer.com/) to create the Inno Setup installers directly from RAD Studio IDE.
Sorry for little self promo :)

Show the download progress by default and no hide button

When starting to download files from my setup, it only appears total progress and the button details to show what appears in the next image:
What I want to do is to have that step by default without hitting details button and not showing the hide button.
I assume, that we are talking about this Inno Download Plugin. On its source code page I found the idp.iss script file which seems to be an interface to the library. It contains the idpShowDetails function which if you call with the show parameter set to True will show the detail components, that you can see by clicking the details button. What remains then is hiding that details button, which in the script is accessible through the IDPForm record variable's DetailsButton member. Through this member you can set the Visible property to False to hide that button.
To realize this without modifying the original scripts you can include the following piece of code into your existing script:
procedure CurPageChanged(CurPageID: Integer);
begin
// if the downloader page was just shown, then...
if CurPageID = IDPForm.Page.ID then
begin
// show the detail components
idpShowDetails(True);
// and hide the details button
IDPForm.DetailsButton.Visible := False;
end;
end;
And a screenshot:

Resources