如何以最大化模式执行应用程序?
How to execute an application in maximized mode?
基于我的 last question,我有一个功能齐全的应用程序,可以执行外部进程。
但是有个问题。例如,当 Internet Explorer
启动时,浏览器 window 不会最大化打开。
如何使浏览器 window(或任何其他 window)以最大化模式启动?
这是我的代码:
形式:
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.
在 Windows
中最大化 window 的常用方法是从 Win32 API 调用 ShowWindow
,将句柄传递给 window 和 SW_MAXIMIZE
作为参数,在进程启动后。
但是当使用CreateProcess
启动一个新进程时,你可以通过设置[=16=来指示它为你调用ShowWindow
] TStartupInfo
到 SW_MAXIMIZE
的字段。
仅当您还在 dwFlags
字段中设置了 STARTF_USESHOWWINDOW
标志时,才会考虑您在 wShowWindow
中设置的值。 dwFlags
位域确定在进程创建 window.
时是否使用 TStartupInfo
记录的某些成员
实际上,ShowWindow
是在 GUI 进程启动时自动调用的。通过设置 TStartupInfo
的 wShowWindow
字段,您只是告诉它在第一次调用 ShowWindow
.
时将哪个值用作 nCmdShow
参数的参数
在您的代码中 StartInfo.cb := sizeof(StartInfo);
后添加以下行:
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_MAXIMIZE;
所有这些都在 STARTUPINFO 结构的文档中进行了解释:
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
.
不幸的是,这并不适用于所有应用程序。您必须针对您打算从 CreateProcess
开始的每个进程单独测试它。对于某些应用程序,在第一次调用 ShowWindow
时设置 SW_MAXIMIZED
可能还不够。
基于我的 last question,我有一个功能齐全的应用程序,可以执行外部进程。
但是有个问题。例如,当 Internet Explorer
启动时,浏览器 window 不会最大化打开。
如何使浏览器 window(或任何其他 window)以最大化模式启动?
这是我的代码:
形式:
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.
在 Windows
中最大化 window 的常用方法是从 Win32 API 调用 ShowWindow
,将句柄传递给 window 和 SW_MAXIMIZE
作为参数,在进程启动后。
但是当使用CreateProcess
启动一个新进程时,你可以通过设置[=16=来指示它为你调用ShowWindow
] TStartupInfo
到 SW_MAXIMIZE
的字段。
仅当您还在 dwFlags
字段中设置了 STARTF_USESHOWWINDOW
标志时,才会考虑您在 wShowWindow
中设置的值。 dwFlags
位域确定在进程创建 window.
TStartupInfo
记录的某些成员
实际上,ShowWindow
是在 GUI 进程启动时自动调用的。通过设置 TStartupInfo
的 wShowWindow
字段,您只是告诉它在第一次调用 ShowWindow
.
nCmdShow
参数的参数
在您的代码中 StartInfo.cb := sizeof(StartInfo);
后添加以下行:
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_MAXIMIZE;
所有这些都在 STARTUPINFO 结构的文档中进行了解释:
wShowWindow
If
dwFlags
specifiesSTARTF_USESHOWWINDOW
, this member can be any of the values that can be specified in thenCmdShow
parameter for the ShowWindow function, except forSW_SHOWDEFAULT
. Otherwise, this member is ignored.For GUI processes, the first time
ShowWindow
is called, itsnCmdShow
parameter is ignoredwShowWindow
specifies the default value. In subsequent calls toShowWindow
, thewShowWindow
member is used if thenCmdShow
parameter ofShowWindow
is set toSW_SHOWDEFAULT
.
不幸的是,这并不适用于所有应用程序。您必须针对您打算从 CreateProcess
开始的每个进程单独测试它。对于某些应用程序,在第一次调用 ShowWindow
时设置 SW_MAXIMIZED
可能还不够。