InnoSetup: возможно ли открыть мою пользовательскую форму Delphi (из DLL) вместо стандартного мастера установки - PullRequest
5 голосов
/ 21 декабря 2011

Мне нужно создать сложную форму с моими собственными компонентами (своего рода установщик OneClick) и использовать ее в качестве замены стандартного мастера InnoSetup. Возможно ли это?

Моя форма помещена в DLL, и эта DLL будет доступна для процесса InnoSetup.

Вот как я пытался это сделать:

Код DLL Delphi

library OneClickWizard;

uses
  SysUtils,
  Classes,
  Wizard in 'Wizard.pas' {FormWizard};

{$R *.res}

exports
  CreateWizardForm,
  DestroyWizardForm;

begin
end.

Форма Delphi

unit Wizard;

interface

type
  TFormWizard = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormWizard: TFormWizard;

procedure CreateWizardForm(AppHandle: THandle); stdcall;
procedure DestroyWizardForm; stdcall;

implementation

{$R *.dfm}

procedure CreateWizardForm(AppHandle: THandle);
begin
  Application.Handle := AppHandle;
  FormWizard := TFormWizard.Create(Application);
  FormWizard.Show;
  FormWizard.Refresh;
end;

procedure DestroyWizardForm;
begin
  FormWizard.Free;
end;

Сценарий InnoSetup (iss)

[Setup]
;Disable all of the default wizard pages
DisableDirPage=yes
DisableProgramGroupPage=yes
DisableReadyMemo=true
DisableReadyPage=true
DisableStartupPrompt=true
DisableWelcomePage=true
DisableFinishedPage=true

[Files]
Source:"OneClickWizard.dll"; Flags: dontcopy

[Code]
procedure CreateWizardForm(AppHandle: Cardinal); 
  external 'CreateWizardForm@files:OneClickWizard.dll stdcall';
procedure DestroyWizardForm;
  external 'DestroyWizardForm@files:OneClickWizard.dll stdcall';


procedure InitializeWizard();
begin
  CreateWizardForm(MainForm.Handle);
end;

Форма появляется на экране, но она не реагирует на мой ввод. Кажется, это вне основного цикла сообщений. Как это сделать правильно?

Ответы [ 3 ]

6 голосов
/ 21 декабря 2011

В моей настройке я делаю что-то подобное. Код InnoSetup Я передаю дескриптор как StrToInt(ExpandConstant('{wizardhwnd}')) (я предполагаю, что MainForm.Handle равен нулю)

в DLL:

OldAppHandle := Application.Handle;
try
  Application.Handle := hAppHandle; // hAppHandle the handle from InnoSetup
  F := TfmZForm.Create(Application);
  try
    F.Caption := lpTitle;
    F.ShowModal;
    Result := F.ErrorCode;
  finally
    F.Free;
  end;
finally
  Application.Handle := OldAppHandle;
end;
5 голосов
/ 21 декабря 2011

Я точно ничего не знаю о InnoSetup, но вам обязательно нужно использовать ShowModal, а не Show здесь.Пользовательский интерфейс установки всегда модален, и вам нужно подождать, пока пользователь закончит итерацию с формой, прежде чем вы вернетесь в Inno.Иначе как Инно узнает, когда действовать?ShowModal запускает цикл обработки сообщений для обслуживания формы, поэтому не будет проблем с получением ввода.

Вы также изменили бы свою DLL, чтобы удалить DestroyWizardForm, так как функция, вызывающая ShowModal, может как создавать, так и уничтожать форму.

1 голос
/ 21 декабря 2011

Если вы хотите полностью заменить пользовательский интерфейс, вероятно, будет проще создать приложение-заглушку, которое представляет форму, а затем запускает обычную настройку в режиме без вывода сообщений, передавая различные параметры командной строки.

Либо так, либо, по крайней мере, используя встроенную в Inno форму и функции / логику страницы мастера.

...