unit WinSearch; interface uses Windows, Messages, SysUtils, Classes, ComCtrls, Forms; type PHWndArray = ^THWndArray; THWndArray = array[0..500] of HWND; procedure ListViewColumnAdd(LV: TListView; ACaption: string; AWidth: integer); procedure ListViewItemAdd(LV: TListView; ACaption,SubItem: string); function IsChildWindow(Handle:HWND):Boolean; function GetClassNameStr(hWindow:HWND):string; function GetWindowTextStr(hWindow:HWND):string; procedure ClassInfos(LV:TListView;hWindow:HWND); procedure WindowInfos(LV:TListView;hWindow:HWND); function IsOwnedWindow(hWindow:HWND):Boolean; // EnumWindows() のラッパー、すべてのトップレベルウィンドウの列挙 function AEnumWindows(var WA:THWndArray):integer; // 可視で所有されていないトップレベルウィンドウの列挙 function EnumVisbleNoOwnedWindows(var WA:THWndArray):integer; // 上の GetWindow() 版、Z-Order の高い方から列挙する function EnumVisibleNoOwnedWindowAsZOrder(var WA:THWndArray):integer; // ClassName のウィンドウを Z-Order の高い方から列挙する function EnumWindowsOfClassNameAsZOrder(var WA:THWndArray; ClassName:string):integer; // EnumThreadWindows() のラッパー、スレッド内のトップレベルウィンドウの列挙 function AEnumThreadWindows(var WA:THWndArray; OneOfHandles:HWND):integer; // EnumChildWindows() のラッパー、子、孫、ひ孫、.. 全部列挙 function AEnumChildWindows(var WA:THWndArray; hParent:HWND):integer; // 上で列挙したうち、特定のクラス名のもののハンドルを返す function FindChildOfClass(hParent:HWND; ClassName:string):HWND; // 直接の子ウィンドウのみ列挙する function EnumDirectChildren(var WA:THWndArray; hParent:HWND):integer; // 任意のウィンドウから最上位のトップレベルウィンドウを取得する function GetMostTopLevelWindow(hWindow:HWND):HWND; // 直接の Owned ウィンドウを列挙する function EnumDirectOwnedWindows(var WA:THWndArray; hOwner:HWND):integer; implementation procedure ListViewColumnAdd(LV: TListView; ACaption: string; AWidth: integer); begin with LV.Columns.Add do begin Caption := ACaption; Width := AWidth; end; end; procedure ListViewItemAdd(LV: TListView; ACaption,SubItem: string); begin with LV.Items.Add do begin Caption := ACaption; SubItems.Text := SubItem; end; end; function IsChildWindow(Handle:HWND):Boolean; begin result := (GetWindowLong(Handle,GWL_STYLE) and WS_CHILD) <> 0; end; function GetClassNameStr(hWindow:HWND):string; var p:PChar; ret:integer; begin GetMem(p,100); ret := GetClassName(hWindow,p,100); SetString(result,p,ret); FreeMem(p); end; function GetWindowTextStr(hWindow:HWND):string; var p:PChar; ret:integer; begin ret := GetWindowTextLength(hWindow); GetMem(p,ret+1); ret := GetWindowText(hWindow,p,ret+1); SetString(result,p,ret); FreeMem(p); end; procedure ClassInfos(LV:TListView;hWindow:HWND); var WC: TWndClass; s:string; begin s := GetClassNameStr(hWindow); ListViewItemAdd(LV,'ClassName',s); GetClassInfo(hInstance,PChar(s),WC); ListViewItemAdd(LV,'Style',Format('$%.8x',[GetClassLong(hWindow,GCL_STYLE),8])); ListViewItemAdd(LV,'WndProc',Format('$%.8x',[GetClassLong(hWindow,GCL_WNDPROC)])); ListViewItemAdd(LV,'hModule',Format('$%.8x',[GetClassLong(hWindow,GCL_HMODULE)])); ListViewItemAdd(LV,'ClsExtra',Format('$%.8x bytes',[GetClassLong(hWindow,GCL_CBCLSEXTRA)])); ListViewItemAdd(LV,'WndExtra',Format('$%.8x bytes',[GetClassLong(hWindow,GCL_CBWNDEXTRA)])); ListViewItemAdd(LV,'hIcon',Format('$%.8x',[GetClassLong(hWindow,GCL_HICON)])); ListViewItemAdd(LV,'hBrush',Format('$%.8x',[GetClassLong(hWindow,GCL_HBRBACKGROUND)])); ListViewItemAdd(LV,'hCursor',Format('$%.8x',[GetClassLong(hWindow,GCL_HCURSOR)])); end; procedure WindowInfos(LV:TListView;hWindow:HWND); begin ListViewItemAdd(LV,'TEXT',GetWindowTextStr(hWindow)); ListViewItemAdd(LV,'HANDLE',Format('$%.8x (%d)',[hWindow,hWindow])); ListViewItemAdd(LV,'EXSTYLE',Format('$%.8x',[GetWindowLong(hWindow,GWL_EXSTYLE)])); ListViewItemAdd(LV,'STYLE',Format('$%.8x',[GetWindowLong(hWindow,GWL_STYLE)])); ListViewItemAdd(LV,'WNDPROC',Format('$%.8x',[GetWindowLong(hWindow,GWL_WNDPROC)])); ListViewItemAdd(LV,'HINSTANCE',Format('$%.8x',[GetWindowLong(hWindow,GWL_HINSTANCE)])); ListViewItemAdd(LV,'HWNDPARENT',Format('$%.8x (%d)', [GetWindowLong(hWindow,GWL_HWNDPARENT),GetWindowLong(hWindow,GWL_HWNDPARENT)])); ListViewItemAdd(LV,'ID',Format('$%.8x (%d)', [GetWindowLong(hWindow,GWL_ID),GetWindowLong(hWindow,GWL_ID)])); end; function IsOwnedWindow(hWindow:HWND):Boolean; begin result := GetWindow(hWindow,GW_OWNER) <> 0; end; function EnumWndProc(hWindow:HWND;lData:LPARAM):BOOL;stdcall; var pWA:PHWndArray; begin pWA := PHWndArray(lData); pWA^[0] := pWA^[0]+1; pWA^[pWA^[0]] := hWindow; result := true; end; function AEnumWindows(var WA:THWndArray):integer; begin WA[0] := 0; EnumWindows(@EnumWndProc,LPARAM(@WA)); result := WA[0]; end; function EnumVisbleNoOwnedWndProc(hWindow:HWND;lData:LPARAM):BOOL;stdcall; var pWA:PHWndArray; begin result := true; if IsOwnedWindow(hWindow) then exit; if not IsWindowVisible(hWindow) then exit; pWA := PHWndArray(lData); pWA^[0] := pWA^[0]+1; pWA^[pWA^[0]] := hWindow; end; function EnumVisbleNoOwnedWindows(var WA:THWndArray):integer; begin WA[0] := 0; EnumWindows(@EnumVisbleNoOwnedWndProc,LPARAM(@WA)); result := WA[0]; end; function EnumVisibleNoOwnedWindowAsZOrder(var WA:THWndArray):integer; var hWindow:HWND; begin WA[0] := 0; hWindow := GetWindow(Application.Handle,GW_HWNDFIRST); while (hWindow <> 0) do begin if (not IsOwnedWindow(hWindow)) and IsWindowVisible(hWindow) then begin WA[0] := WA[0]+1; WA[WA[0]] := hWindow end; hWindow := GetWindow(hWindow,GW_HWNDNEXT); end; result := WA[0]; end; function EnumWindowsOfClassNameAsZOrder(var WA:THWndArray; ClassName:string):integer; var hWindow:HWND; begin WA[0] := 0; hWindow := GetWindow(Application.Handle,GW_HWNDFIRST); while (hWindow <> 0) do begin if (not IsOwnedWindow(hWindow)) and IsWindowVisible(hWindow) and (UpperCase(GetClassNameStr(hWindow)) = UpperCase(ClassName)) then begin WA[0] := WA[0]+1; WA[WA[0]] := hWindow end; hWindow := GetWindow(hWindow,GW_HWNDNEXT); end; result := WA[0]; end; function EnumThreadWndProc(hWindow:HWND;lData:LPARAM):BOOL;stdcall; var pWA:PHWndArray; begin pWA := PHWndArray(lData); pWA^[0] := pWA^[0]+1; pWA^[pWA^[0]] := hWindow; result := true; end; function AEnumThreadWindows(var WA:THWndArray; OneOfHandles:HWND):integer; begin WA[0] := 0; EnumThreadWindows(GetWindowThreadProcessId(OneOfHandles,nil), @EnumThreadWndProc,LPARAM(@WA)); result := WA[0]; end; function EnumChildWndProc(hWindow:HWND;lData:LPARAM):BOOL;stdcall; var pWA:PHWndArray; begin pWA := PHWndArray(lData); pWA^[0] := pWA^[0]+1; pWA^[pWA^[0]] := hWindow; result := true; end; function AEnumChildWindows(var WA:THWndArray; hParent:HWND):integer; begin WA[0] := 0; EnumChildWindows(hParent,@EnumChildWndProc,LPARAM(@WA)); result := WA[0]; end; function FindChildOfClass(hParent:HWND; ClassName:string):HWND; var WA:THWndArray; i,Num:integer; begin result := 0; Num := AEnumChildWindows(WA,hParent); if Num > 0 then for i := 1 to Num do if UpperCase(GetClassNameStr(WA[i])) = UpperCase(ClassName) then begin result := WA[i]; break; end; end; function EnumDirectChildren(var WA:THWndArray; hParent:HWND):integer; var hWindow:HWND; begin WA[0] := 0; hWindow := GetWindow(hParent,GW_CHILD); while (hWindow <> 0) do begin WA[0] := WA[0]+1; WA[WA[0]] := hWindow; hWindow := GetWindow(hWindow,GW_HWNDNEXT); end; result := WA[0]; end; function GetMostTopLevelWindow(hWindow:HWND):HWND; var hAncestor,hPrev:HWND; begin hPrev := hWindow; hAncestor := GetParent(hPrev); while hAncestor <> 0 do begin hPrev := hAncestor; hAncestor := GetParent(hPrev) end; hAncestor := hPrev; while hAncestor <> 0 do begin hPrev := hAncestor; hAncestor := GetWindow(hPrev,GW_OWNER) end; result := hPrev; end; function EnumDirectOwnedWindows(var WA:THWndArray; hOwner:HWND):integer; var WWA:THWndArray; i,Num:integer; begin result := 0; Num := AEnumThreadWindows(WWA,hOwner); if Num > 0 then for i := 1 to Num do if GetWindow(WWA[i],GW_OWNER) = hOwner then begin Inc(result); WA[result] := WWA[i] end; end; end.