Inno Setup-具有VCL样式的语言选择器 [英] Inno Setup - Language selector with VCL Styles

查看:92
本文介绍了Inno Setup-具有VCL样式的语言选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以将语言选择器(Inno Setup)与VCL样式一起使用?怎么样?

Is there any way to use language selector (Inno Setup) with VCL Styles? How?

推荐答案

选择设置语言"在 InitializeSetup事件函数被调用之前,将显示对话框.因此,您无法为对话框加载外观.

The "Select Setup Language" dialog displays before the InitializeSetup event function is called. So you cannot load the skin for the dialog.

作为一种解决方法,您可以实施自己的语言"对话框,然后从InitializeSetup中显示该对话框.这样,自定义对话框将被皮肤化.用户选择一种语言后,您可以使用 /LANG重新启动安装程序.切换以加载所选语言.

As a workaround, you can implement your own "language" dialog, and display that from the InitializeSetup. This way the custom dialog will be skinned. Once a user selects a language, you restart the installer with the /LANG switch to load the selected language.

通过设置 ShowLanguageDialogno.

[Setup]
ShowLanguageDialog=no

[Files]
Source: "skin.vsf"; Flags: dontcopy
Source: "VclStylesInno.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:VclStylesInno.dll stdcall setuponly';
procedure UnLoadVCLStyles;
  external 'UnLoadVCLStyles@files:VclStylesInno.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;

  { Restart the installer with the selected language }
  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;
      { /SL5 switch is an internal switch used to pass data }
      { from the master Inno Setup process to the child process. }
      { As we are starting a new master process, we have to remove it. }
      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
      S := 'Running installer with the selected language failed. Code: %d';
      MsgBox(Format(S, [Instance]), mbError, MB_OK);
    end;
  end;
end;

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

  Result := True;

  if WizardSilent then
  begin
    Log('Silent installation, keeping the default language');
  end
    else
  begin
    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;
end;

procedure DeinitializeSetup();
begin
  UnLoadVCLStyles;
end;

安装程序重新启动代码基于仅在需要时才使Inno Setup安装程序请求特权提升.

Installer re-launch code is based on Make Inno Setup installer request privileges elevation only when needed.

请注意,如果您想允许父进程等待安装完成,则可能需要对代码进行调整.尽管在这种情况下,您可能会使用静默安装,但代码可以正确处理.

Note that the code probably needs tweaking, if you want to allow parent process to wait for the installation to complete. Though in that case you are probably going to use the silent installation, what the code can handle correctly.

这篇关于Inno Setup-具有VCL样式的语言选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆