Inno Setup-具有VCL样式的语言选择器 [英] Inno Setup - Language selector with VCL Styles
问题描述
有什么方法可以将语言选择器(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.
通过设置 ShowLanguageDialog
到no
.
[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屋!