user6365505
user6365505

Reputation:

How to execute an application in maximized mode?

Based on my last question, I have a fully functional application that can execute an external process.

But there is a problem. When, for example, Internet Explorer is started, the browser window is not opened maximized.

How to make the browser window (or any other window) start in maximized mode?

Here is my code:

Form:

 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.

Upvotes: 1

Views: 1056

Answers (1)

quasoft
quasoft

Reputation: 5438

The usual way to maximize a window in Windows is to call ShowWindow from Win32 API, passing the handle to the window and SW_MAXIMIZE as arguments, after the process has been started.

But when using CreateProcess to start a new process, you can instruct it to call ShowWindow for you, by setting the wShowWindow field of TStartupInfo to SW_MAXIMIZE.

The value you set in wShowWindow is only taken in account if you also set the STARTF_USESHOWWINDOW flag in the dwFlags field. The dwFlags bitfield determines whether certain members of the TStartupInfo record are used when the process creates a window.

Actually, ShowWindow is called automatically when a GUI process is started. By setting the wShowWindow field of TStartupInfo you are just telling it which value to use as argument for nCmdShow parameter on the first call to ShowWindow.

Add the following lines after StartInfo.cb := sizeof(StartInfo); in your code:

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

All this is explained in documentation of STARTUPINFO structure:

wShowWindow

If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.

For GUI processes, the first time ShowWindow is called, its nCmdShow parameter is ignored wShowWindow specifies the default value. In subsequent calls to ShowWindow, the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.

Unfortunately this does not work universally for all applications. You have to test it individually with every process that you intend to start with CreateProcess. For some applications setting SW_MAXIMIZED on the first call to ShowWindow might not be enough.

Upvotes: 1

Related Questions