Here is a way to get all the windows associated with the Process:
First, you need a enumThreadWindow procedure(same as other enumwindow
procedure). After you get the ProcessInformation, you can call
enumThreadWindows function to enumerate all the window's handles of this thread:
var
WndCount: integer;
WndArray: array [0..255] of HWnd;
lpProcessInformation: TProcessInformation;
//the enumerate Thread Window procedure
function EnumThreadWndProc(AHWnd: HWnd; ALPARAM: lParam): boolean; stdcall;
var
WndCaption: array[0..254] of char;
WndClassName: array[0..254] of char;
begin
Form1.WndArray[Form1.WndCount] := AHWnd;
Inc(Form1.WndCount);
GetWindowText(AHWnd, @WndCaption, 254);
GetClassName(AHWnd, @WndClassName, 254);
with Form1.Memo1.Lines do
begin
Add(format('hWnd: %x, Caption: %s, Class: %s',[AHWnd, StrPas(WndCaption), StrPas(WndClassName)]));
end;
Result := true;
end;
//create process and find its windows
procedure TForm1.Button1Click(Sender: TObject);
var
sCommandLine: string;
bCreateProcess: boolean;
lpStartupInfo: TStartupInfo;
begin
sCommandLine := 'C:/Windows/Notepad.exe';
Button1.Enabled := false;
//填入 StartupInfo
FillChar(lpStartupInfo, Sizeof(TStartupInfo), #0);
lpStartupInfo.cb := Sizeof(TStartupInfo);
lpStartupInfo.dwFlags := STARTF_USESHOWWINDOW;
lpStartupInfo.wShowWindow := SW_NORMAL;
bCreateProcess := CreateProcessA(pchar(sCommandLine),nil,// PChar(sCommandLine),
nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil,
lpStartupInfo, lpProcessInformation);
if bCreateProcess then
begin
WaitForInputIdle(lpProcessInformation.hProcess,// handle to process
60000);// time-out interval in milliseconds
memo1.clear;
memo1.Lines.Add(format(' hProcess: %d',[lpProcessInformation.hProcess]));
memo1.lines.add(format(' hThread: %d',[lpProcessInformation.hThread]));
memo1.lines.add(format('dwProcessID: %u', [lpProcessInformation.dwProcessID]));
memo1.lines.add(format(' dwThreadID: %u', [lpProcessInformation.dwThreadId]));
WndCount:=0;
enumThreadWindows(lpProcessInformation.dwThreadID, @enumThreadWndProc, 0);
end;
end;
You should know the features of the main window so you can pick out
the main window. Once you got the main window, you can use the api
function enumChildWindows to find out all child windows. Surely you
need to write a enumChildWndProc.
enumChildWindows(MainWnd, @enumChildWndProc, 0);
In this example("notepad.exe"), WndArray[0] is the main window.