2017-02-04 7 views
1

last questionに基づいて、私は外部プロセスを実行できる完全に機能するアプリケーションを持っています。アプリケーションを最大化モードで実行するには?

しかし、問題があります。たとえば、Internet Explorerが起動されると、ブラウザウィンドウは最大化されません。

ブラウザウィンドウ(または他のウィンドウ)を最大化モードにするにはどうすればよいですか?ここで

は私のコードです:

フォーム:

type 
     PEnumInfo = ^TEnumInfo; 
     TEnumInfo = record ProcessID: DWORD; HWND: THandle; end; 

    type 
     TForm1 = class(TForm) 
     btn1: TButton; 
     procedure btn1Click(Sender: TObject); 
     private 
     { Private declarations } 
     public 
     { Public declarations } 
     end; 

    var 
     Form1: TForm1; 
     myPID: DWORD = 0; 

    implementation 

    uses 
    UTaskBarList; 

    {$R *.dfm} 

    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall; 
     var 
      PID: DWORD; 
     begin 
      GetWindowThreadProcessID(Wnd, @PID); 
      Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or (not IsWindowEnabled(WND)); 
      if not Result then EI.HWND := WND; 
     end; 

     function FindMainWindow(PID: DWORD): DWORD; 
     var 
      EI: TEnumInfo; 
     begin 
      EI.ProcessID := PID; 
      EI.HWND := 0; 
      EnumWindows(@EnumWindowsProc, Integer(@EI)); 
      Result := EI.HWND; 
     end; 

    procedure dgCreateProcess(const FileName: string); 
    var ProcInfo: TProcessInformation; 
     StartInfo: TStartupInfo; 
    begin 
     FillMemory(@StartInfo, sizeof(StartInfo), 0); 
     StartInfo.cb := sizeof(StartInfo); 
     // StartInfo.dwX := Screen.DesktopRect.BottomRight.X; 
     // StartInfo.dwY := Screen.DesktopRect.BottomRight.Y; 
     CreateProcess(
         PChar(FileName), 
         nil, 
         nil, Nil, False, 
         NORMAL_PRIORITY_CLASS, 
         nil, nil, 
         StartInfo, 
         ProcInfo); 

         myPID := ProcInfo.dwProcessId; 

     CloseHandle(ProcInfo.hProcess); 
     CloseHandle(ProcInfo.hThread); 
    end; 

    procedure TForm1.btn1Click(Sender: TObject); 
    var 
     hWindow : DWORD; 
     szRect : TRect; 
     posX, posY, windW, windH: Integer; 
    begin 

     dgCreateProcess('C:\Program Files\Internet Explorer\iexplore.exe'); 

     repeat 

      hWindow := FindMainWindow(myPID);//FindWindow('IEFrame', nil); 

      if hWindow > 0 then 
      begin 

      GetWindowRect(hWindow,szRect); 

      windW := szRect.Width; 
      windH := szRect.Height; 

      posX := Screen.DesktopRect.BottomRight.X; 
      posY := Screen.DesktopRect.BottomRight.Y; 

      MoveWindow(hWindow, posX, posY, windW, windH,True); 

      TTaskbarList.Remove(hWindow); 

      end; 
     until (IsWindowVisible(hWindow)); 

    ShowMessage('outside of loop'); 
    end; 

    end. 

UTaskBarList:

unit UTaskBarList; 

interface 

uses ComObj, ShlObj; 

type 
    ITaskbarList = interface 
    [SID_ITaskbarList] 
    function HrInit: HResult; stdcall; 
    function AddTab(hwnd: Cardinal): HResult; stdcall; 
    function DeleteTab(hwnd: Cardinal): HResult; stdcall; 
    function ActivateTab(hwnd: Cardinal): HResult; stdcall; 
    function SetActiveAlt(hwnd: Cardinal): HResult; stdcall; 
    end; 

    TTaskbarList = class 
    private 
    xTaskbarList: ITaskbarList; 
    public 
    constructor Create; 
    procedure Activate(hwnd: THandle); 
    procedure Add(hwnd: THandle); 
    procedure Delete(hwnd: THandle); 
    class procedure Insert(hwnd: THandle); 
    class procedure Remove(hwnd: THandle); 
    end; 

implementation 

constructor TTaskbarList.Create; 
begin 
    inherited Create; 
    xTaskbarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList; 
    xTaskbarList.HrInit; 
end; 

procedure TTaskbarList.Activate(hwnd: THandle); 
begin 
    xTaskbarList.ActivateTab(hwnd); 
end; 

procedure TTaskbarList.Add(hwnd: THandle); 
begin 
    xTaskbarList.AddTab(hwnd); 
end; 

procedure TTaskbarList.Delete(hwnd: THandle); 
begin 
    xTaskbarList.DeleteTab(hwnd); 
end; 

class procedure TTaskbarList.Insert(hwnd: THandle); 
begin 
    with TTaskbarList.Create do 
    begin 
    Add(hwnd); 
    Free; 
    end; 
end; 

class procedure TTaskbarList.Remove(hwnd: THandle); 
begin 
    with TTaskbarList.Create do 
    begin 
    Delete(hwnd); 
    Free; 
    end; 
end; 

end. 
+2

'StartupInfo.dwFlags'を' STARTF_USESHOWWINDOW'に、 'StartupInfo.wShowWindow'を' SW_MAXIMIZE'に設定してみてください。 – quasoft

+0

@quasoft、ありがとう、これが動作します。 –

+0

しかし、以前の質問では、アプリをオフスクリーンで起動したり、隠したりしたいと思っていました。それで、その「最大化」の有無はどういうことになりますか? (これは、コンピュータ上の可能な複数の画面のうちの1つ全体の空間を埋めることを意味する。すなわち、***画面上***)、 –

答えて

1

でウィンドウを最大化する通常の方法Windowsは、プロセスが開始された後に、ウィンドウにハンドルを渡し、引数としてSW_MAXIMIZEを渡してWin32 APIからShowWindowを呼び出すことです。

しかし、新しいプロセスを開始するCreateProcessを使用しているとき、あなたはSW_MAXIMIZETStartupInfowShowWindowフィールドを設定することによって、あなたのためのShowWindowを呼び出すためにそれを指示することができます。

wShowWindowに設定した値は、dwFlagsフィールドにSTARTF_USESHOWWINDOWフラグも設定した場合にのみ考慮されます。 dwFlagsビットフィールドは、プロセスがウィンドウを作成するときにTStartupInfoレコードの特定のメンバーが使用されるかどうかを決定します。

実際には、ShowWindowがGUIプロセスの開始時に自動的に呼び出されます。 wShowWindowフィールドをTStartupInfoに設定すると、ShowWindowの最初の呼び出しで、nCmdShowパラメータの引数として使用する値を指定するだけです。

は、あなたのコード内でStartInfo.cb := sizeof(StartInfo);後に次の行を追加します。

StartInfo.dwFlags := STARTF_USESHOWWINDOW; 
StartInfo.wShowWindow := SW_MAXIMIZE; 

これはSTARTUPINFO構造のドキュメントで説明されているすべて:

wShowWindow

、このdwFlagsSTARTF_USESHOWWINDOWを指定している場合memberに指定できる値のいずれかを指定できますを除く ShowWindow関数のnCmdShowパラメータ。そうでない場合、このメンバー は無視されます。

GUIプロセスの場合、最初にShowWindowが呼び出され、そのnCmdShowパラメータは無視されます。wShowWindowはデフォルト値を指定します。 ShowWindowの呼び出しでは、 のnCmdShowパラメータがShowWindowに設定されている場合、wShowWindowメンバが使用され、SW_SHOWDEFAULTに設定されます。

残念ながら、これはすべてのアプリケーションで普遍的に機能しません。 CreateProcessで始まるすべてのプロセスで個別にテストする必要があります。一部のアプリケーションでは、ShowWindowへの最初の呼び出し時にSW_MAXIMIZEDを設定すると、十分でない場合があります。

関連する問題