In Inno Setup: How do you use/know the values for CurPageIDs for custom pages? - inno-setup

Lets say we set up a page using the CreateInputQueryPage function and we use the NextButtonClick event to control actions taken on that page. How do we refer to the correct CurPageID within that code?

First initialize your page as a global:
...
[code]
var
UserPage: TInputQueryWizardPage;
...
Then refer to that page variable (for example within the NextButtonClick event handler) like so:
UserPage.ID
See the example file CodeDlg.iss for an a complete example with the variable use in evidence.

Related

Can I show the custom window before all the wizard pages in Inno Setup?

I export a function from dll like this:
function IsClientLaunched : Boolean;
external 'IsClientStarted#files:IsStart.dll stdcall setuponly';
I need this function to check if my application is already running or not. It returns True if it's running and false if it's not.
What I need to do is depending on the result of that function I have to show the custom window with the custom message and 2 buttons: Continue and Cancel. So if I close the app and press Continue then the installation process goes on. If I press Cancel then the installer finishes its work and closes. The problem is that I don't know how to show that custom window before all the wizard pages and if it's even possible to do that?
Also, I use ISSI to show the splash screen:
#define ISSI_Splash "C:\InnoSetupProject\Images\client.bmp"
#define ISSI_Splash_T 3
#define ISSI_Splash_X 500
#define ISSI_Splash_Y 220
There's also one problem with that. If I show the MsgBox dialog before the first wizard page and press Cancel on it I want my setup program to close, but instead it shows me the splash screen anyway and then closes. Can I somehow cancel it if I need it in InitializeSetup?
Use the code from:
Is it possible to check if program is already running before trying to install it? (Inno Setup)
(it's your question!)
And just replace IsAppRunning with your IsClientLaunched.
Though, now the question is, whether you need your custom IsClientLaunched at all. You can use the IsAppRunning instead.
According to the CreateCustomPage documentation the parameters for creating a custom page are as follows:
function CreateCustomPage(const AfterID: Integer;
const ACaption,
ADescription: String): TWizardPage;
As you can see, you are providing AfterID which implies you can tell it to show a custom page after a specific builtin page.
But, have you considered using PrepareToInstall? It says:
You can use this event function to detect and install missing
prerequisites and/or to shutdown any application which is about to be
updated.
So maybe you can do your tests there and show any needed pop-up message box. Then, based on the reply, you can return with the appropriate error message. The documentation explains.
There might be other ways to do what you want.

Inno Setup: How to display license page before custom page shows from procedure InitializeWizard();

I am using LicenseFile=D:\authorized\Builds\Integration\License.rtf to display license page and procedure InitializeWizard();.
The Problem is that the license page is displayed after the procedure InitializeWizard();. Is there any way we can display it before?
procedure InitializeWizard;
begin
{ Create the pages }
UsagePage := CreateInputOptionPage(wpWelcome,
'App setup information', 'How would you like to install App?',
'Would you like to install App as a service?.',
True, False);
UsagePage.Add('Yes');
UsagePage.Add('No');
UsagePage.Values[0] := true;
end;
It's a misunderstanding. The InitializeWizard function does not display anything. It just creates the custom page(s), it does not display them.
Try adding a MsgBox call at the end of the function. You will see that the message displays before the wizard form even pops up.
The order of the custom pages is determined by the AfterID parameter (the first one) of the Create*Page functions.
If you want the custom page to show after the license page, use wpLicense, instead of wpWelcome.
UsagePage := CreateInputOptionPage(wpLicense, ...);

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

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?

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.

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