基于我的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.
答案 0 :(得分:1)
在Windows
中最大化窗口的常用方法是从Win32 API调用ShowWindow
,将句柄传递给窗口并在进程启动后将SW_MAXIMIZE
作为参数传递。
但是当使用CreateProcess
开始新流程时,您可以通过将wShowWindow
的{{1}}字段设置为{{1}来指示它为您调用ShowWindow
}}
如果您还在TStartupInfo
字段中设置SW_MAXIMIZE
标记,则只会考虑您在wShowWindow
中设置的值。 STARTF_USESHOWWINDOW
位域确定在进程创建窗口时是否使用dwFlags
记录的某些成员。
实际上,GUI进程启动时会自动调用ShowWindow
。通过设置dwFlags
TStartupInfo
字段,您只需告诉它在第一次调用ShowWindow
时使用哪个值作为wShowWindow
参数的参数。
在代码中TStartupInfo
之后添加以下行:
nCmdShow
所有这些都在STARTUPINFO结构的文档中解释:
<强> wShowWindow 强>
如果
StartInfo.cb := sizeof(StartInfo);
指定StartInfo.dwFlags := STARTF_USESHOWWINDOW; StartInfo.wShowWindow := SW_MAXIMIZE;
,则此成员可以是dwFlags
参数中可以指定的任何值。 ShowWindow函数,STARTF_USESHOWWINDOW
除外。否则,这个成员 被忽略了。对于GUI进程,第一次调用
nCmdShow
时,忽略其SW_SHOWDEFAULT
参数ShowWindow
指定默认值。 在后续调用nCmdShow
时,如果使用wShowWindow
成员ShowWindow
的{{1}}参数设置为wShowWindow
。
不幸的是,这并不适用于所有应用程序。您必须对要以nCmdShow
开头的每个进程单独测试它。对于某些应用程序,在第一次调用ShowWindow
时设置SW_SHOWDEFAULT
可能还不够。