添加最小化和還原轉換(動畫),以創新安裝嚮導形式:
單位嚮導,
變化TWizardForm.CreateParams
這樣的:
procedure TWizardForm.CreateParams(var Params: TCreateParams);
begin
inherited;
{ Ensure the form is on top of MainForm by making MainForm
the "parent" of the form when *MainForm is set to Visible*. }
if shWindowVisible in SetupHeader.Options then
Params.WndParent := MainForm.Handle
else
Params.WndParent := GetDesktopWindow;
end;
更改TWizardForm.WMSysCommand
這樣的:
procedure TWizardForm.WMSysCommand(var Message: TWMSysCommand);
begin
if Message.CmdType and $FFF0 = SC_MINIMIZE then begin
{ A minimize button is shown on the wizard form when (shWindowVisible in
SetupHeader.Options). When it is clicked we want to minimize the whole
application. }
if shWindowVisible in SetupHeader.Options then
Application.Minimize
else
ShowWindow(WizardForm.Handle, SW_MINIMIZE);
end
else
if Message.CmdType and $FFF0 = SC_RESTORE then begin
if shWindowVisible in SetupHeader.Options then
Application.Restore
else
ShowWindow(WizardForm.Handle, SW_RESTORE);
end;
if Message.CmdType = 9999 then
MainForm.ShowAboutBox
else
inherited;
end;
聲明一個稱爲TWizardForm.FormShow
如下所示的新程序:
procedure FormShow(Sender: TObject);
聲明它像下面在Implementation
部單元嚮導。
procedure TWizardForm.FormShow(Sender: TObject);
begin
if not(shWindowVisible in SetupHeader.Options) then
ShowWindow(Application.Handle, SW_HIDE);
end;
最後,添加此TWizardForm.FormShow
爲WizardForm的OnShow中形成該事件。
你差不多完成了!現在,嚮導窗口應該會按照您的預期顯示「還原」和「最小化動畫」。
固定MessageBox的父窗口的問題將最小化轉換(動畫)的創新安裝嚮導後:
注:必須這樣做,以防止已記錄嚮導消息框(其可以用Inno Setup的編譯器登錄日誌)從有時顯示兩個任務欄按鈕甚至WizardForm是可見的。
單位主要的部分{ Variables for command line parameters }
,宣告一個新的布爾變量是這樣的:
IsApplicationRunning: Boolean;
單位主,
更改程序AbortInit
是這樣的:
procedure AbortInit(const Msg: TSetupMessageID);
begin
IsApplicationRunning := False;
LoggedMsgBox(SetupMessages[Msg], '', mbCriticalError, MB_OK, True, IDOK);
Abort;
end;
更改程序AbortInitFmt1
這樣的:
procedure AbortInitFmt1(const Msg: TSetupMessageID; const Arg1: String);
begin
IsApplicationRunning := False;
LoggedMsgBox(FmtSetupMessage(Msg, [Arg1]), '', mbCriticalError, MB_OK, True, IDOK);
Abort;
end;
更改程序AbortInitServicePackRequired
這樣的:
procedure AbortInitServicePackRequired(const ServicePack: Word);
begin
IsApplicationRunning := False;
LoggedMsgBox(FmtSetupMessage(msgWindowsServicePackRequired, ['Windows', IntToStr(Hi(ServicePack))]), '', mbCriticalError, MB_OK, True, IDOK);
Abort;
end;
在設備嚮導,
修改先前添加的程序TWizardForm.FormShow
這樣的:
procedure TWizardForm.FormShow(Sender: TObject);
begin
if not(shWindowVisible in SetupHeader.Options) then
ShowWindow(Application.Handle, SW_HIDE);
IsApplicationRunning := True;
end;
單位CmnFunc,
添加Wizard
和Main
的用途科單位CmnFunc的Implementation
。
更改程序AppMessageBox
這樣的:
function AppMessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
var
ActiveWindow: HWND;
MessageHandler: HWND;
WindowList: Pointer;
{$IFNDEF IS_D4}
DidMove: Boolean;
OldRect: TRect;
{$ENDIF}
begin
if MessageBoxRightToLeft then
Flags := Flags or (MB_RTLREADING or MB_RIGHT);
if IsApplicationRunning = False then
MessageHandler := Application.Handle
else
MessageHandler := WizardForm.Handle;
{ If the application window isn't currently visible, show the message box
with no owner window so it'll get a taskbar button }
if IsIconic(MessageHandler) or (GetWindowLong(MessageHandler, GWL_STYLE) and WS_VISIBLE = 0) or (GetWindowLong(MessageHandler, GWL_EXSTYLE) and WS_EX_TOOLWINDOW <> 0) then begin
ActiveWindow := GetActiveWindow;
WindowList := DisableTaskWindows(0);
try
{ Note: DisableTaskWindows doesn't disable invisible windows.
MB_TASKMODAL will ensure that Application.Handle gets disabled too. }
Result := MessageBox(0, Text, Caption, Flags or MB_TASKMODAL);
finally
EnableTaskWindows(WindowList);
SetActiveWindow(ActiveWindow);
end;
Exit;
end;
TriggerMessageBoxCallbackFunc(Flags, False);
try
{$IFDEF IS_D4}
{ On Delphi 4+, simply call Application.MessageBox }
Result := Application.MessageBox(Text, Caption, Flags);
{$ELSE}
{ Use custom implementation on Delphi 2 and 3. The Flags parameter is
incorrectly declared as a Word on Delphi 2's Application.MessageBox, and
there is no support for multiple monitors. }
DidMove := MoveAppWindowToActiveWindowMonitor(OldRect);
try
ActiveWindow := GetActiveWindow;
WindowList := DisableTaskWindows(0);
try
Result := MessageBox(Application.Handle, Text, Caption, Flags);
finally
EnableTaskWindows(WindowList);
SetActiveWindow(ActiveWindow);
end;
finally
if DidMove then
SetWindowPos(Application.Handle, 0,
OldRect.Left + ((OldRect.Right - OldRect.Left) div 2),
OldRect.Top + ((OldRect.Bottom - OldRect.Top) div 2),
0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or SWP_NOZORDER);
end;
{$ENDIF}
finally
TriggerMessageBoxCallbackFunc(Flags, True);
end;
end;
現在,所有的登錄和任何其他消息框將正常顯示!
現在,使用自述文件中的推薦編譯器編譯安裝程序(Setup.e32),並將其複製到安裝Inno Setup的目錄中。
注意:Inno Setup Unicode或Ansi的安裝版本必須與您修改爲重新編譯的Inno Setup源代碼的版本相匹配。或者您可以編譯整個Inno Setup項目並複製 - 將此修改後的和重新編譯的安裝程序(Setup.e32)替換爲編譯Inno Setup的目錄。
重新編譯安裝程序後,您需要將以下代碼添加到Pascal腳本中。立即現在
[Files]
Source: "InnoCallback.dll"; Flags: dontcopy
[Code]
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
const
GWL_WNDPROC = -4;
SC_ABOUTBOX = 9999;
SC_RESTORE = $F120;
SC_MINIMIZE = $F020;
WM_SYSCOMMAND = $0112;
Type
WPARAM = UINT_PTR;
LPARAM = LongInt;
LRESULT = LongInt;
TWindowProc = function(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
PrevWndProc: LongInt;
function CallWindowProc(lpPrevWndFunc: LongInt; hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
external 'CallWindowProc{#AW}@user32.dll stdcall';
function WrapWindowProc(Callback: TWindowProc; ParamCount: Integer): LongWord;
external '[email protected]:InnoCallback.dll stdcall';
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: LongInt): LongInt;
external 'SetWindowLong{#AW}@user32.dll stdcall';
function Wizard_WMSYSCOMMAND(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
if (uMsg = WM_SYSCOMMAND) and (wParam and $FFF0 = SC_MINIMIZE) then begin
//SOMETHING LIKE BASS_Pause();.
Log('Wizard Window has been Minimized.');
end;
if (uMsg = WM_SYSCOMMAND) and (wParam and $FFF0 = SC_RESTORE) then begin
//SOMETHING LIKE BASS_Start();.
Log('Wizard Window has been Restored.');
end;
if (uMsg = WM_SYSCOMMAND) and (wParam = SC_ABOUTBOX) then begin
Result := 0;
MainForm.ShowAboutBox;
end
else
Result := CallWindowProc(PrevWndProc, hwnd, uMsg, wParam, lParam);
end;
procedure InitializeWizard();
begin
PrevWndProc := SetWindowLong(WizardForm.Handle, GWL_WNDPROC, WrapWindowProc(@Wizard_WMSYSCOMMAND, 4));
end;
procedure DeinitializeSetup();
begin
SetWindowLong(WizardForm.Handle, GWL_WNDPROC, PrevWndProc);
end;
,你應當通知時,通過編譯器日誌消息WizardForm最大限度地減少或恢復。您可以通過在功能Wizard_WMSYSCOMMAND
中添加它們來根據您的代碼暫停或恢復音樂。
該死!我也檢查了你的答案。它也在工作。在我得到這個答案之前,我成功地使用了不使用Timer的代碼,而是使用'InnoCallBack.dll'。如果我發佈這個作爲我的問題的更新,你可以檢查它的任何錯誤的東西? – GTAVLover
如果它適合您,請將其作爲答案發布。我會看一看。 –
好吧,我會盡快。 – GTAVLover