如何以最大化模式执行应用程序?
Posted
技术标签:
【中文标题】如何以最大化模式执行应用程序?【英文标题】:How to execute an application in maximized mode? 【发布时间】:2017-02-04 20:21:33 【问题描述】:根据我的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.
【问题讨论】:
尝试将StartupInfo.dwFlags
设置为STARTF_USESHOWWINDOW
和StartupInfo.wShowWindow
设置为SW_MAXIMIZE
@quasoft,谢谢,这行得通。
但在您之前的问题中,您希望应用程序在屏幕外启动和/或隐藏。那么它是否“最大化”又有什么关系呢? (这意味着填充计算机上可能多个屏幕之一的整个空间。即 on-screen),
【参考方案1】:
在 Windows
中最大化窗口的常用方法是在进程启动后从 Win32 API 调用 ShowWindow
,将句柄传递给窗口,并将 SW_MAXIMIZE
作为参数传递。
但是当使用CreateProcess
启动一个新进程时,你可以通过将TStartupInfo
的wShowWindow
字段设置为SW_MAXIMIZE
来指示它为你调用ShowWindow
。
只有在dwFlags
字段中设置了STARTF_USESHOWWINDOW
标志时,才会考虑您在wShowWindow
中设置的值。 dwFlags
位域决定进程创建窗口时是否使用TStartupInfo
记录的某些成员。
实际上,ShowWindow
在 GUI 进程启动时会自动调用。通过设置TStartupInfo
的wShowWindow
字段,您只是告诉它在第一次调用ShowWindow
时将哪个值用作nCmdShow
参数的参数。
在代码中StartInfo.cb := sizeof(StartInfo);
之后添加以下行:
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_MAXIMIZE;
所有这些都在STARTUPINFO结构的文档中进行了解释:
wShowWindow
如果
dwFlags
指定STARTF_USESHOWWINDOW
,则此成员可以是可以在nCmdShow
参数中指定的任何值 ShowWindow 函数,SW_SHOWDEFAULT
除外。否则,该成员 被忽略。对于 GUI 进程,第一次调用
ShowWindow
时,忽略其nCmdShow
参数wShowWindow
指定默认值。 在随后对ShowWindow
的调用中,将使用wShowWindow
成员,如果ShowWindow
的nCmdShow
参数设置为SW_SHOWDEFAULT
。
不幸的是,这并不适用于所有应用程序。您必须使用您打算以CreateProcess
开始的每个进程单独测试它。对于某些应用程序,在第一次调用 ShowWindow
时设置 SW_MAXIMIZED
可能还不够。
【讨论】:
以上是关于如何以最大化模式执行应用程序?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Symfony 2 中进入维护模式以安全地更新生产应用程序?