Windows 如何使用Delphi启动应用程序并获取其句柄?
我想从Delphi启动一个应用程序,并获得它的句柄,这样我就可以将所述应用程序的主窗口嵌入到类型为TFrame的框架上。到目前为止,我已经尝试:Windows 如何使用Delphi启动应用程序并获取其句柄?,windows,delphi,winapi,Windows,Delphi,Winapi,我想从Delphi启动一个应用程序,并获得它的句柄,这样我就可以将所述应用程序的主窗口嵌入到类型为TFrame的框架上。到目前为止,我已经尝试: Function TFrmEmbeddedExe.StartNewApplication : Boolean; var SEInfo: TShellExecuteInfo; ExitCode : DWORD; begin FillChar(SEInfo, SizeOf(SEInfo), 0) ; SEInfo.cbSize := Si
Function TFrmEmbeddedExe.StartNewApplication : Boolean;
var
SEInfo: TShellExecuteInfo;
ExitCode : DWORD;
begin
FillChar(SEInfo, SizeOf(SEInfo), 0) ;
SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
with SEInfo do
begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := self.Handle;
lpFile := PChar(self.fexecuteFileName) ;// Example could be 'C:\Windows\Notepad.exe'
nShow := SW_SHOWNORMAL;//SW_HIDE;
end;
if ShellExecuteEx(@SEInfo) then
begin
sleep(1500);
self.fAppWnd := FindWindow(nil, PChar(self.fWindowCaption)); //Example : 'Untitled - Notepad'
if self.fAppWnd <> 0 then
begin
Windows.SetParent(self.fAppWnd, SEInfo.Wnd);
ShowWindow(self.fAppWnd, SW_SHOWMAXIMIZED);
result := true;
end
else
result := false;
end
else
result := false;
end ;
Function TfrmEmbeddedExe.CreateProcessNewApplication : Boolean;
var
zAppName: array[0..512] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
Res : DWORD;
DoWait : Boolean;
begin
DoWait := False;
StrPCopy(zAppName, self.fexecuteFileName); //'C:\Windows\Notepad.exe'
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;
if CreateProcess (zAppName,
nil, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) then { pointer to PROCESS_INF }
begin
if DoWait then //just set it to false... so it will never enter here
begin
WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, Res);
end
else
begin
self.fAppWnd := ProcessInfo.hProcess;
Windows.SetParent(self.fAppWnd, self.Handle);
ShowWindow(self.fAppWnd, SW_SHOWMAXIMIZED);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
result := true;
end
else begin
Result := false;
end;
end;
请不要运行以上代码!它会产生奇怪的结果,包括在所有运行的应用程序中的任意位置拾取一个看似随机的窗口,并嵌入该窗口(甚至是Windows开始菜单中的菜单项…)
因此,基本上我需要的是如何启动应用程序,并获取应用程序主窗口的句柄
非常感谢您的帮助
问候
Jens Fudge以下是您需要做的粗略概述。我将把编码留给您:
ShellExecuteEx
或CreateProcess
启动流程。这将产生一个进程句柄WaitForInputIdle
。这使流程有机会加载并启动其消息循环GetProcessId
,以获取进程IDEnumWindows
枚举顶级窗口GetWindowThreadProcessId
,以检查是否已找到目标进程的顶级窗口处理完进程句柄后,不要忘记关闭它们。进程句柄不是窗口句柄。看标题,我正要进来坚持说这一定是一个副本,但在看到您将此应用程序嵌入到自己的应用程序中后,这确实使它与众不同。好问题。请不要在你的帖子中添加签名。大卫·赫弗南,这听起来确实是前进的方向,我会在有时间的时候这样做。谢谢你的解释。