Inno Setup - 带VCL样式的语言选择器

时间:2016-12-07 15:26:40

标签: inno-setup pascalscript

有没有办法在VCL样式中使用语言选择器(Inno Setup)?怎么样?

2 个答案:

答案 0 :(得分:3)

"选择设置语言"在调用InitializeSetup event function之前显示对话框。因此,您无法为对话框加载外观。

作为一种解决方法,您可以实施自己的语言"对话框,并显示InitializeSetup中的内容。这样,自定义对话框将被蒙皮。用户选择语言后,使用/LANG switch重新启动安装程序以加载所选语言。

确保通过将ShowLanguageDialog设置为no来停用标准语言对话框。

[Setup]
ShowLanguageDialog=no

[Files]
Source: "skin.vsf"; Flags: dontcopy
Source: "VclStyles.dll"; Flags: dontcopy

[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "cs"; MessagesFile: "compiler:Languages\Czech.isl"

[Code]

procedure LoadVCLStyle(VClStyleFile: String);
  external 'LoadVCLStyleW@files:VclStyles.dll stdcall setuponly';
procedure UnLoadVCLStyles;
  external 'UnLoadVCLStyles@files:VclStyles.dll stdcall setuponly';

function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
  lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
  external 'ShellExecuteW@shell32.dll stdcall';

procedure SelectLanguage();
var
  LanguageForm: TSetupForm;
  CancelButton: TNewButton;
  OKButton: TNewButton;
  LangCombo: TNewComboBox;
  SelectLabel: TNewStaticText;
  Languages: TStrings;
  Params: string;
  Instance: THandle;
  P, I: Integer;
  S, L: string;
begin
  Languages := TStringList.Create();

  Languages.Add('en=English');
  Languages.Add('cs='+#$010C+'e'+#$0161+'tina');

  LanguageForm := CreateCustomForm;

  LanguageForm.Caption := SetupMessage(msgSelectLanguageTitle);
  LanguageForm.ClientWidth := ScaleX(297);
  LanguageForm.ClientHeight := ScaleY(125);
  LanguageForm.BorderStyle := bsDialog;
#if Ver < 0x06000000
  LanguageForm.Center;
#endif

  CancelButton := TNewButton.Create(LanguageForm);
  CancelButton.Parent := LanguageForm;
  CancelButton.Top := ScaleY(93);
  CancelButton.Width := ScaleY(75);
  CancelButton.Left := LanguageForm.ClientWidth - CancelButton.Width - ScaleX(16);
  CancelButton.Height := ScaleY(23);
  CancelButton.TabOrder := 3;
  CancelButton.ModalResult := mrCancel;
  CancelButton.Caption := SetupMessage(msgButtonCancel);

  OKButton := TNewButton.Create(LanguageForm);
  OKButton.Parent := LanguageForm;
  OKButton.Top := CancelButton.Top;
  OKButton.Width := CancelButton.Width;
  OKButton.Left := CancelButton.Left - OKButton.Width - ScaleX(8);
  OKButton.Height := CancelButton.Height;
  OKButton.Caption := SetupMessage(msgButtonOK);
  OKButton.Default := True
  OKButton.ModalResult := mrOK;
  OKButton.TabOrder := 2;

  LangCombo := TNewComboBox.Create(LanguageForm);
  LangCombo.Parent := LanguageForm;
  LangCombo.Left := ScaleX(16);
  LangCombo.Top := ScaleY(56);
  LangCombo.Width := LanguageForm.ClientWidth - ScaleX(16) * 2;
  LangCombo.Height := ScaleY(21);
  LangCombo.Style := csDropDownList;
  LangCombo.DropDownCount := 16;
  LangCombo.TabOrder := 1;

  SelectLabel := TNewStaticText.Create(LanguageForm);
  SelectLabel.Parent := LanguageForm;
  SelectLabel.Left := LangCombo.Left;
  SelectLabel.Top := ScaleY(8);
  SelectLabel.Width := LangCombo.Width;
  SelectLabel.Height := ScaleY(39);
  SelectLabel.AutoSize := False
  SelectLabel.Caption := SetupMessage(msgSelectLanguageLabel);
  SelectLabel.TabOrder := 0;
  SelectLabel.WordWrap := True;

  for I := 0 to Languages.Count - 1 do
  begin
    P := Pos('=', Languages.Strings[I]);
    L := Copy(Languages.Strings[I], 0, P - 1);
    S := Copy(Languages.Strings[I], P + 1, Length(Languages.Strings[I]) - P);
    LangCombo.Items.Add(S);
    if L = ActiveLanguage then
      LangCombo.ItemIndex := I;
  end;

  if LanguageForm.ShowModal = mrOK then
  begin
    { Collect current instance parameters }
    for I := 1 to ParamCount do
    begin
      S := ParamStr(I);
      { Unique log file name for the elevated instance }
      if CompareText(Copy(S, 1, 5), '/LOG=') = 0 then
      begin
        S := S + '-localized';
      end;
      { Do not pass our /SL5 switch }
      if CompareText(Copy(S, 1, 5), '/SL5=') <> 0 then
      begin
        Params := Params + AddQuotes(S) + ' ';
      end;
    end;

    L := Languages.Strings[LangCombo.ItemIndex];
    P := Pos('=', L);
    L := Copy(L, 0, P-1);

    { ... and add selected language }
    Params := Params + '/LANG=' + L;

    Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
    if Instance <= 32 then
    begin
      MsgBox(
        Format('Running installer with selected language failed. Code: %d', [Instance]),
        mbError, MB_OK);
    end;
  end;
end;

function InitializeSetup(): Boolean;
var
  Language: string;
begin
  ExtractTemporaryFile('skin.vsf');
  LoadVCLStyle(ExpandConstant('{tmp}\skin.vsf'));

  Result := True;

  Language := ExpandConstant('{param:LANG}');
  if Language = '' then
  begin
    Log('No language specified, showing language dialog');
    SelectLanguage();
    Result := False;
    Exit;
  end
    else
  begin
    Log('Language specified, proceeding with installation');
  end;
end;

procedure DeinitializeSetup();
begin
  UnLoadVCLStyles;
end;

Select Setup Language dialog

安装程序重新启动代码基于Make Inno Setup installer request privileges elevation only when needed

答案 1 :(得分:0)

您需要从source重新编译Inno设置。

Main.pas文件中找到此代码,并在CodeRunnerInitializeSetup之后移动此部分。

{ Show "Select Language" dialog if necessary }
  if ShowLanguageDialog and (Entries[seLanguage].Count > 1) and
     not InitSilent and not InitVerySilent then begin
    if not AskForLanguage then
      Abort;
  end;

enter image description here