Allow users choose hotkeys for icon/shortcut in Inno Setup

Viewed 74

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

1 Answers

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;

enter image description here


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.

Related