I'm looking to allow users, who run an installer made trough Inno Setup, to choose whether to use hot keys or not, and if yes, allow them to choose which hot keys use.
[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; \
HotKey: "ctrl+alt+b"
Name: "{autoprograms}\{#MyAppName2}"; Filename: "{app}\{#MyAppExeName2}"; \
HotKey: "ctrl+alt+x"
This is my [Icons]
section
The Icons
section HotKey
parameter cannot be modified at run time. So you will have to create the whole shortcut programmatically. An easy API that allows creating a shortcut with a hot key is WScript.Shell.CreateShortcut
.
[Code]
var
App1HotKeyCombo: TNewComboBox;
App2HotKeyCombo: TNewComboBox;
const
NoneHotKey = 'None';
procedure InitializeWizard();
var
HotKeysPage: TWizardPage;
ALabel: TNewStaticText;
begin
Log('InitializeWizard');
HotKeysPage := CreateCustomPage(wpSelectTasks, 'Select your hot keys', '');
App1HotKeyCombo := TNewComboBox.Create(HotKeysPage);
App1HotKeyCombo.Parent := HotKeysPage.Surface;
App1HotKeyCombo.Left := ScaleX(200);
App1HotKeyCombo.Top := 0;
App1HotKeyCombo.Width := ScaleX(100);
App1HotKeyCombo.Style := csDropDownList;
App1HotKeyCombo.Items.Add(NoneHotKey);
App1HotKeyCombo.Items.Add('Ctrl+Alt+A');
App1HotKeyCombo.Items.Add('Ctrl+Alt+B');
App1HotKeyCombo.Items.Add('Ctrl+Alt+C');
App1HotKeyCombo.ItemIndex := 1;
ALabel := TNewStaticText.Create(HotKeysPage);
ALabel.Parent := HotKeysPage.Surface;
ALabel.Top := App1HotKeyCombo.Top + ScaleY(4);
ALabel.Left := 0;
ALabel.Caption := 'Hot key for application 1:';
ALabel.FocusControl := App1HotKeyCombo;
App2HotKeyCombo := TNewComboBox.Create(HotKeysPage);
App2HotKeyCombo.Parent := HotKeysPage.Surface;
App2HotKeyCombo.Left := App1HotKeyCombo.Left;
App2HotKeyCombo.Top := App1HotKeyCombo.Top + App1HotKeyCombo.Height + ScaleY(8);
App2HotKeyCombo.Width := App1HotKeyCombo.Width;
App2HotKeyCombo.Style := csDropDownList;
App2HotKeyCombo.Items.Assign(App1HotKeyCombo.Items);
App2HotKeyCombo.ItemIndex := 2;
ALabel := TNewStaticText.Create(HotKeysPage);
ALabel.Parent := HotKeysPage.Surface;
ALabel.Top := App2HotKeyCombo.Top + ScaleY(4);
ALabel.Left := 0;
ALabel.Caption := 'Hot key for application 2:';
ALabel.FocusControl := App2HotKeyCombo;
end;
procedure CreateShortCut(IconName, Path: string; AppHotKeyCombo: TNewComboBox);
var
WshShell: Variant;
ShellLink: Variant;
Msg: string;
begin
WshShell := CreateOleObject('WScript.Shell');
IconName := ExpandConstant(IconName) + '.lnk';
ShellLink := WshShell.CreateShortcut(IconName)
ShellLink.TargetPath := ExpandConstant(Path);
ShellLink.WindowStyle := SW_SHOWNORMAL;
if AppHotKeyCombo.Text <> NoneHotKey then
ShellLink.Hotkey := AppHotKeyCombo.Text;
ShellLink.Save;
Msg := 'Created "%s" icon pointing to "%s" with "%s" hotkey';
Log(Format(Msg, [IconName, ShellLink.TargetPath, ShellLink.Hotkey]));
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
CreateShortCut('{autoprograms}\MyProg1', '{app}\MyProg.exe', App1HotKeyCombo);
CreateShortCut('{autoprograms}\MyProg2', '{app}\MyProg.exe', App2HotKeyCombo);
end;
end;
A more robust API, is IShellLink
. That's what Inno Setup uses internally. Though it requires considerably alot more code. For some examples, see Check for existence of a shortcut pointing to a specific target in Inno Setup.
You will also have to ensure that the shortcuts get deleted on uninstall. You can use UninstallDelete
section for that.
If you do not want to code the shortcut creation, an alternative approach would be to use preprocessor to generate separate [Icons]
entry for each shortcut you want to offer and use Check
parameters to activate only the entry corresponding to the shortcut the user selects.