Inno setup 第一页上的消息框/wpWelcome

Inno setup 第一页上的消息框/wpWelcome,inno-setup,Inno Setup,我希望在我安装的第一页上有一条弹出消息,但是我不知道如何正确操作。我尝试将MsgBox链接到页面id更改,如下所示: procedure CurPageChanged(CurPageID: Integer); begin if CurPageID = wpWelcome then begin MsgBox('something something dark side', mbInformation, MB_OK); end; end; 不幸的是,在wpWelco

我希望在我安装的第一页上有一条弹出消息,但是我不知道如何正确操作。我尝试将MsgBox链接到页面id更改,如下所示:

procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpWelcome then
    begin
      MsgBox('something something dark side', mbInformation, MB_OK);
    end;
end;

不幸的是,在wpWelcome绘制之前,此消息框出现得太快,我如何才能延迟它?或者如何才能在第一页上获得弹出窗口?

显示向导表单后,不会立即触发脚本或表单事件。但是,可以为此任务制定变通方法。正确的方法是将自定义窗口消息从事件中发布到向导窗体本身,并在该消息的处理程序中完成任务。问题是Inno安装程序并没有内置的消息处理功能,所以这种方式需要一个外部库

1.使用OnActivate事件的解决方法 但让我们从另一个更脏但独立的解决方案开始。向导窗体有一个事件,该事件在窗体处于活动状态时触发,其中还包括窗体第一次显示的时间。在事件第一次触发后,您需要做的唯一一件事就是断开方法与事件的连接,然后完成自己的工作。在代码中,它可以是:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Code]
procedure WizardFormShow(Sender: TObject);
begin
  // disconnect binding of this method from the event
  WizardForm.OnActivate := nil;
  // and do your stuff
  MsgBox('Hello! I am your wizard form :)', mbInformation, MB_OK);
end;

procedure InitializeWizard;
begin
  // bind the event to the method
  WizardForm.OnActivate := @WizardFormShow;
end;
2.自定义邮件发布的解决方法 这是一个肮脏但可靠且独立的解决方案。现在去正确的方法,这需要图书馆,而且更复杂。这一个从事件向向导表单本身发布一条自定义消息,并等待该消息到达。这一额外的步骤已经完成,因为当窗体显示时,事件不会触发,但是当它即将显示时,我们需要一些方法来运行我们的东西,当窗体窗口处理它即将显示时排队的所有消息时:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Files]
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif
const
  GWL_WNDPROC = -4;
  WM_USER = $0400;
  CM_AFTERSHOW = WM_USER + 1;

type
  WPARAM = UINT_PTR;
  LPARAM = LongInt;
  LRESULT = LongInt;
  TWindowProc = function(hwnd: HWND; uMsg: UINT; wParam: WPARAM; 
    lParam: LPARAM): LRESULT;

function CallWindowProc(lpPrevWndFunc: LongInt; hWnd: HWND; Msg: UINT; 
  wParam: WPARAM; lParam: LPARAM): LRESULT;
  external 'CallWindowProc{#AW}@user32.dll stdcall';
function SetWindowLong(hWnd: HWND; nIndex: Integer; 
  dwNewLong: LongInt): LongInt;
  external 'SetWindowLong{#AW}@user32.dll stdcall';
function WrapWindowProc(Callback: TWindowProc; ParamCount: Integer): LongWord;
  external 'wrapcallback@files:InnoCallback.dll stdcall';

var
  OldWndProc: LongInt;

procedure WizardFormShow(Sender: TObject);
begin
  // enqueue our custom message when the wizard form is about to be shown
  PostMessage(WizardForm.Handle, CM_AFTERSHOW, 0, 0);
end;

function WizardFormWndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; 
  lParam: LPARAM): LRESULT;
begin
  // if we're processing our custom message, then...
  if uMsg = CM_AFTERSHOW then
    MsgBox('Hello! I am your wizard form :)', mbInformation, MB_OK);
  else
    // otherwise pass message to the original window procedure
    Result := CallWindowProc(OldWndProc, hwnd, uMsg, wParam, lParam);
end;

procedure InitializeWizard;
begin
  // intercept window proc of the wizard form and store the original one
  OldWndProc := SetWindowLong(WizardForm.Handle, GWL_WNDPROC,
    WrapWindowProc(@WizardFormWndProc, 4));
  // bind the OnShow event method, which is used for posting our message
  WizardForm.OnShow := @WizardFormShow;
end;

procedure DeinitializeSetup;
begin
  // restore the wizard form's window procedure
  SetWindowLong(WizardForm.Handle, GWL_WNDPROC, OldWndProc);
end;

谢谢,我回家后会试试的。从你的解决方案来看,我的问题异常复杂。不客气!好吧,由于Delphi中缺少类似于《AfterShow》的缺少事件,它更为复杂。TLama已经给了您一个合理的答案,但我想补充一点,您可能需要重新思考一下。欢迎页面已经是呈现给用户的信息了——在上面弹出额外的文本看起来很凌乱,用户体验也很糟糕。为什么不直接将文本添加到欢迎页面本身,或者添加到下一页?(这两项都非常容易引导。)