我希望在我的安装的第一页上有一条弹出消息,但我不知道如何正确地做到这一点。我尝试将MsgBox链接到页面ID更改,如下所示:
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpWelcome then
begin
MsgBox('something something dark side', mbInformation, MB_OK);
end;
end;
不幸的是,这个消息框显示得太早,在绘制wpWelcome之前,我该如何延迟它?或者我怎么能在第一页上弹出一个弹出窗口?
答案 0 :(得分:0)
在显示向导表单后,没有立即触发脚本或表单事件。但是,可以为此任务制定解决方法。 正确的方式是将自定义窗口消息从OnShow
事件发送到向导表单本身,并在该消息的处理程序中执行您的操作。问题是Inno Setup没有内置的消息处理功能,因此需要一个外部库。
但是,让我们从另一个更脏,但独立的解决方法开始。向导表单具有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;
这是一个肮脏但可靠且独立的解决方法。现在转到需要InnoCallback
库的正确的方式,并且更复杂。这个从OnShow
事件向向导表单发布自定义消息,并等待此消息到达。这个额外的步骤已经完成,因为OnShow
事件在显示表单时不会触发,但是当它即将显示时,我们需要某种方式来运行我们的东西,当表单窗口处理它的所有消息时当它即将被展示时排队:
[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;