2017-02-11 7 views
1

コード:Install DirectX & VCRedist in freearc default script when progress bar is full & paused after main file extraction Inno SetupでDirectXとVCRedistをインストールできます。しかし、これらのプログラムのインストールウィンドウを画面上の特定の場所に強制することは可能ですか?たとえば、次のようにInno Setup - Inno Setupから起動されたプログラムを強制的に画面の特定の場所で開く方法を教えてください。

enter image description here

enter image description here

答えて

2

それは、アプリケーションが明示的にサポートしていない限り、所望の位置に起動するアプリケーションを作ることはほとんど不可能です。

一般に、あなたができることは、特定のウィンドウが表示された後にそれを移動することを監視することです。キャプション(FindWindowByWindowName)またはクラス(FindWindowByClassName)でウィンドウを識別できます。欠点は、ウィンドウがデフォルトの位置に短時間表示されることです。

コードにはInnoTools InnoCallback libraryが使用されています。

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

[Run] 
Filename: "{tmp}\DXWebSetup.exe"; StatusMsg: "Installing DirectX..."; \ 
    BeforeInstall: StartWaitingForDirectXWindow; AfterInstall: StopWaitingForDirectXWindow 


[Code] 

type 
    TTimerProc = procedure(HandleW, msg, idEvent, TimeSys: LongWord); 

function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; 
    external '[email protected]:InnoCallback.dll stdcall delayload'; 
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; 
    external '[email protected] stdcall'; 
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; 
    external '[email protected] stdcall'; 
function GetTickCount: DWord; external '[email protected] stdcall'; 
function SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X: Integer; Y: Integer; 
    cx: Integer; cy: Integer; uFlags: UINT): BOOL; 
    external '[email protected] stdcall'; 

const 
    SWP_NOSIZE = $01; 
    SWP_NOZORDER = $04; 

var 
    WindowWaitTimer: LongWord; 
    WindowWaitStarted: DWord; 
    MoveWindowRunning: Boolean; 

procedure MoveDirectXWindowProc(
    H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord); 
var 
    Retry: Boolean; 
    Handle: HWND; 
begin 
    Handle := FindWindowByWindowName('Installing Microsoft(R) DirectX(R)'); 
    if Handle = 0 then 
    begin 
    if DWord(GetTickCount - WindowWaitStarted) < 5000 then 
    begin 
     Log('DirectX window not found, will try again shortly'); 
     Retry := True; 
    end 
    else 
    begin 
     Log('Giving up waiting for DirectX window'); 
     Retry := False; 
    end 
    end 
    else 
    begin 
    Log('DirectX window found'); 

    SetWindowPos(
     Handle, 0, WizardForm.Left + ScaleX(150), WizardForm.Top + ScaleX(30), 
     0, 0, SWP_NOSIZE or SWP_NOZORDER); 
    Retry := False; 
    end; 

    if not Retry then 
    begin 
    Log('Stopping timer'); 
    KillTimer(0, WindowWaitTimer); 
    WindowWaitTimer := 0; 
    end; 
end; 

procedure StartWaitingForDirectXWindow; 
begin 
    Log('Starting waiting for DirectX window'); 
    WindowWaitTimer := SetTimer(0, 0, 100, WrapTimerProc(@MoveDirectXWindowProc, 4)); 
    WindowWaitStarted := GetTickCount; 
end; 

procedure StopWaitingForDirectXWindow; 
begin 
    if WindowWaitTimer <> 0 then 
    begin 
    Log('DirectX installer finished, and we are still waiting for its window, stopping'); 
    KillTimer(0, WindowWaitTimer); 
    WindowWaitTimer := 0; 
    end 
    else 
    begin 
    Log('DirectX installer finished, and we are no longer waiting for its window'); 
    end; 
end; 

Windows positions

+0

ウィンドウのタイトルは、 ''マイクロソフト(R)DirectXの(R)のインストールされていないので、しかし、 'Instalando ...' - あなたは 'FindWindowByWindowName'内の文字列をローカライズする必要がありますコール。 –

+0

また、部分一致を使用する 'FindWindowByWindowName'の代わりに、より寛容な実装を使用してください(例えば' DirectX'のみ)。 –

+0

'SetTimer'コールの間隔を減らすことができます。しかし、それはすでに100ミリ秒しかありません。私は、より低い値が知覚されるとは思わない - 私はログにエラーを見ない。 –

関連する問題