XBa*_*000 0 delphi shell hwnd shellexecute handle
我用来创建一个自定义函数,如winexec(...):Hwnd将重新执行已执行应用程序的句柄.
我确实使用了findwindow()但是如果它改变了窗口标题就有问题.
没有通用的方法来获取应用程序的"窗口"句柄,因为不能保证任何程序都有一个窗口句柄.程序可能有许多顶级句柄(即Microsoft Word,每个文档一个),或者根本没有窗口.您可能会质疑您真正需要窗口句柄的内容; 可以有更好的方法做任何你想做的事情,不需要任何特定的窗口句柄.
WinExec(已被弃用近15年,因此你应该认真考虑不再使用它)并且ShellExecute绝对不会返回有关他们开始的程序的信息,如果它们确实启动任何程序的话.(ShellExecute可能使用DDE将命令发送到已经运行的应用程序实例.)如果他们启动了一个应用程序,它可能会在程序运行之前完成运行.
你可以使用CreateProcess或ShellExecuteEx代替.如果他们启动一个程序,他们会给你一个代表他们开始的程序的进程句柄.您可以使用它来帮助您获取有关该程序的其他信息,例如其窗口列表.不要打扰FindWindow; 标题和窗口类不保证是唯一的; 程序可能对许多不同的窗口使用相同的类名,并且程序的多个实例将使用相同的类名,而没有太多方法来选择您真正想要的那个.
EnumWindows是一个可用于获取候选窗口句柄列表的函数.你给它一个函数指针,它将为桌面上的每个顶级窗口调用该函数一次.您需要一种方法来告诉它您感兴趣的过程,以及返回结果列表的方法.该函数只接受一个参数,因此该参数必须是指向包含更多信息的结构的指针:
type
PWindowSearch = ^TWindowSearch;
TWindowSearch = record
TargetProcessID: DWord;
ResultList: TWndList;
end;
Run Code Online (Sandbox Code Playgroud)
TWndList是我用来保存HWnd值列表的类型.如果你有Delphi 2009或更高版本,你可以使用TList<HWnd>; 对于早期版本,您可以使用TList后代或您选择的任何其他内容.
CreateProcess会告诉你它填写dwProcessID的TProcessInformation记录成员中的新进程ID ; ShellExecuteEx只返回一个进程句柄,所以使用GetProcessID它.window-enumerating函数需要一个与此签名匹配的回调函数:
function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;
Run Code Online (Sandbox Code Playgroud)
您可以使用EnumWindows获取这样的句柄列表:
function GetWindowListByProcessID(pid: DWord): TWndList;
var
SearchRec: TWindowSearch;
begin
Result := TWndList.Create;
try
SearchRec.TargetProcessID := pid;
SearchRec.ResultList := Result;
Win32Check(EnumWindows(SelectWindowByProcessID, LParam(@SearchRec)));
except
Result.Free;
raise;
end;
end;
Run Code Online (Sandbox Code Playgroud)
你将实现这样的回调函数:
function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;
var
SearchRec: PWindowSearch;
WindowPid: DWord;
begin
SearchRec := PWindowSearch(Param);
Assert(Assigned(SearchRec));
GetWindowThreadProcessID(Wnd, WindowPid);
if WindowPid = SearchRec.TargetProcessID then
SearchRec.ResultList.Add(Wnd);
Result := True;
end;
Run Code Online (Sandbox Code Playgroud)
获得列表后,您可以检查窗口的其他属性,以确定哪些属于您想要的属性.您可以通过窗口标题或类名来确定它,也可以通过窗口中的其他控件来确定它.
当您完成使用过程句柄时,请确保调用CloseHandle它,以便操作系统可以清理过程的簿记信息.