mirror of
https://github.com/ngeor/Chameleon.git
synced 2025-12-19 09:53:43 +01:00
refactor: Extracted logic of enumerating child windows in WindowEnumerator
This commit is contained in:
parent
6ba70319e0
commit
1866eb19b5
@ -45,7 +45,7 @@
|
||||
<PackageName Value="LCL"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="7">
|
||||
<Units Count="8">
|
||||
<Unit0>
|
||||
<Filename Value="Chameleon.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
@ -83,6 +83,11 @@
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="windowenumerator.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="WindowEnumerator"/>
|
||||
</Unit7>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
||||
@ -8,13 +8,6 @@ uses Windows, Messages, SysUtils, Classes, Forms, Graphics,
|
||||
Writers;
|
||||
|
||||
type
|
||||
PEnumParams = ^TEnumParams;
|
||||
|
||||
TEnumParams = record
|
||||
List: TList;
|
||||
ParentWnd: HWND;
|
||||
end;
|
||||
|
||||
TKnownControl = (
|
||||
kcUnknown, kcButton, kcCheckBox, kcComboBox, kcEdit,
|
||||
kcGroupBox, kcImage, kcLabel, kcListBox, kcListView,
|
||||
@ -66,7 +59,6 @@ const
|
||||
|
||||
function BitTest(Value, Mask: integer): boolean;
|
||||
function GetWndText(wnd: HWND): string;
|
||||
function EnumChildrenProc(wnd: HWND; lp: LPARAM): BOOL; stdcall;
|
||||
procedure WriteBitmapData(dfm1: TDfmWriter; bmp: HBITMAP;
|
||||
BelongsToPicture: boolean; const Name: string);
|
||||
procedure WriteIconData(dfm1: TDfmWriter; icon: HICON; BelongsToPicture: boolean;
|
||||
@ -74,6 +66,8 @@ procedure WriteIconData(dfm1: TDfmWriter; icon: HICON; BelongsToPicture: boolean
|
||||
|
||||
implementation
|
||||
|
||||
uses WindowEnumerator;
|
||||
|
||||
function BitTest(Value, Mask: integer): boolean;
|
||||
begin
|
||||
Result := (Value and Mask) = Mask;
|
||||
@ -88,16 +82,6 @@ begin
|
||||
GetWindowText(wnd, PChar(Result), len + 1);
|
||||
end;
|
||||
|
||||
function EnumChildrenProc(wnd: HWND; lp: LPARAM): BOOL; stdcall;
|
||||
var
|
||||
p: PEnumParams;
|
||||
begin
|
||||
p := PEnumParams(lp);
|
||||
if GetParent(wnd) = p^.ParentWnd then
|
||||
p^.List.Add(Pointer(wnd));
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function GetBorderIconsStr(ABorderIcons: TBorderIcons): string;
|
||||
const
|
||||
biStr: array [TBorderIcon] of string = (
|
||||
@ -127,11 +111,9 @@ end;
|
||||
procedure TDfmBuilder.Build(OutStream: TStream; const frmName: string; wnd: HWND);
|
||||
var
|
||||
InStream: TMemoryStream;
|
||||
childlist: TList;
|
||||
i: integer;
|
||||
style, exstyle: longint;
|
||||
wndX: HWND;
|
||||
EnumParams: TEnumParams;
|
||||
|
||||
procedure WriteBorderIcons;
|
||||
var
|
||||
@ -156,7 +138,6 @@ begin
|
||||
FillChar(Counts, sizeof(Counts), #0);
|
||||
InStream := TMemoryStream.Create;
|
||||
Dfm1 := TDfmWriter.Create(InStream);
|
||||
childlist := TList.Create;
|
||||
|
||||
dfm1.WriteLn('object ' + frmName + ': T' + frmName);
|
||||
style := GetWindowLong(wnd, GWL_EXSTYLE);
|
||||
@ -175,14 +156,7 @@ begin
|
||||
dfm1.WriteIntProp('TextHeight', 13);
|
||||
|
||||
// write the children
|
||||
EnumParams.List := childlist;
|
||||
EnumParams.ParentWnd := wnd;
|
||||
EnumChildWindows(wnd, @EnumChildrenProc, integer(@EnumParams));
|
||||
for i := 0 to childlist.Count - 1 do
|
||||
begin
|
||||
wndX := HWND(childlist[i]);
|
||||
PreHandleCtl(wndX);
|
||||
end;
|
||||
EnumerateChildWindows(wnd, Self.PreHandleCtl);
|
||||
dfm1.Ident := 0;
|
||||
dfm1.WriteLn('end');
|
||||
InStream.Position := 0;
|
||||
@ -190,29 +164,18 @@ begin
|
||||
ObjectTextToResource(InStream, OutStream);
|
||||
|
||||
// finalization
|
||||
childlist.Free;
|
||||
DFM1.Free;
|
||||
end;
|
||||
|
||||
procedure TDfmBuilder.HandleUnknown(wnd: HWND; style: integer);
|
||||
var
|
||||
class_name: array [0..100] of char;
|
||||
childlist: TList;
|
||||
EnumParams: TEnumParams;
|
||||
i: integer;
|
||||
begin
|
||||
// since we don't know what window we're after write the class name
|
||||
GetClassName(wnd, class_name, 100);
|
||||
dfm1.WriteStringProp('Caption', class_name);
|
||||
childlist := TList.Create;
|
||||
EnumParams.List := childlist;
|
||||
EnumParams.ParentWnd := wnd;
|
||||
EnumChildWindows(wnd, @EnumChildrenProc, integer(@EnumParams));
|
||||
for i := 0 to childlist.Count - 1 do
|
||||
begin
|
||||
PreHandleCtl(HWND(childlist[i]));
|
||||
end;
|
||||
childlist.Free;
|
||||
EnumerateChildWindows(wnd, Self.PreHandleCtl);
|
||||
end;
|
||||
|
||||
procedure TDfmBuilder.HandleButton(wnd: HWND; style: integer);
|
||||
|
||||
66
WindowEnumerator.pas
Normal file
66
WindowEnumerator.pas
Normal file
@ -0,0 +1,66 @@
|
||||
unit WindowEnumerator;
|
||||
|
||||
{$mode Delphi}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows;
|
||||
|
||||
type
|
||||
TWndConsumer = procedure (wnd: HWND) of object;
|
||||
|
||||
procedure EnumerateChildWindows(wnd: HWND; consumer: TWndConsumer);
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
TWindowEnumerator = class
|
||||
private
|
||||
wnd: HWND;
|
||||
consumer: TWndConsumer;
|
||||
class function MyEnumChildrenProc(wnd: HWND; lp: LPARAM): BOOL; static; stdcall;
|
||||
procedure Add(wnd: HWND);
|
||||
public
|
||||
constructor Create(wnd: HWND; consumer: TWndConsumer);
|
||||
procedure Run;
|
||||
end;
|
||||
|
||||
procedure EnumerateChildWindows(wnd: HWND; consumer: TWndConsumer);
|
||||
var
|
||||
enumerator: TWindowEnumerator;
|
||||
begin
|
||||
enumerator := TWindowEnumerator.Create(wnd, consumer);
|
||||
try
|
||||
enumerator.Run;
|
||||
finally
|
||||
enumerator.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TWindowEnumerator.Create(wnd: HWND; consumer: TWndConsumer);
|
||||
begin
|
||||
Self.wnd := wnd;
|
||||
Self.consumer := consumer;
|
||||
end;
|
||||
|
||||
procedure TWindowEnumerator.Run;
|
||||
begin
|
||||
EnumChildWindows(wnd, @TWindowEnumerator.MyEnumChildrenProc, LPARAM(Self));
|
||||
end;
|
||||
|
||||
class function TWindowEnumerator.MyEnumChildrenProc(wnd: HWND; lp: LPARAM): BOOL; static; stdcall;
|
||||
var
|
||||
me: TWindowEnumerator;
|
||||
begin
|
||||
me := TWindowEnumerator(lp);
|
||||
me.Add(wnd);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TWindowEnumerator.Add(wnd: HWND);
|
||||
begin
|
||||
consumer(wnd);
|
||||
end;
|
||||
|
||||
end.
|
||||
@ -32,7 +32,7 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
uses DfmEngine, StyleNames;
|
||||
uses StyleNames, WindowEnumerator;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
@ -208,33 +208,44 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
TTreeNodeChildConsumer = class
|
||||
private
|
||||
ParentNode: TTreeNode;
|
||||
ChildrenRootNode: TTreeNode;
|
||||
ChildCount: Integer;
|
||||
Form: TResults;
|
||||
public
|
||||
constructor Create(Form: TResults; ParentNode: TTreeNode);
|
||||
procedure Consume(wnd: HWND);
|
||||
end;
|
||||
|
||||
constructor TTreeNodeChildConsumer.Create(Form: TResults; ParentNode: TTreeNode);
|
||||
begin
|
||||
Self.Form := Form;
|
||||
Self.ParentNode := ParentNode;
|
||||
Self.ChildrenRootNode := nil;
|
||||
Self.ChildCount := 0;
|
||||
end;
|
||||
|
||||
procedure TTreeNodeChildConsumer.Consume(wnd: HWND);
|
||||
var
|
||||
node2: TTreeNode;
|
||||
begin
|
||||
if not Assigned(ChildrenRootNode) then
|
||||
ChildrenRootNode := Form.TreeView1.Items.AddChild(ParentNode, 'Children information');
|
||||
Inc(ChildCount);
|
||||
node2 := Form.TreeView1.Items.AddChild(ChildrenRootNode, 'Child #' + IntToStr(ChildCount));
|
||||
Form.GetWinInfo(integer(wnd), node2);
|
||||
end;
|
||||
|
||||
procedure TResults.GetWinInfoChildren(wnd: HWND; ParentNode: TTreeNode);
|
||||
var
|
||||
i: integer;
|
||||
node1, node2: TTreeNode;
|
||||
childlist: TList;
|
||||
EnumParams: TEnumParams;
|
||||
class_name: String;
|
||||
consumer: TTreeNodeChildConsumer;
|
||||
begin
|
||||
childlist := TList.Create;
|
||||
|
||||
EnumParams.List := childlist;
|
||||
EnumParams.ParentWnd := wnd;
|
||||
EnumChildWindows(wnd, @EnumChildrenProc, integer(@EnumParams));
|
||||
|
||||
with TreeView1.Items do
|
||||
begin
|
||||
if childlist.Count > 0 then
|
||||
begin
|
||||
node1 := AddChild(ParentNode, 'Children information');
|
||||
for i := 1 to childlist.Count do
|
||||
begin
|
||||
node2 := AddChild(node1, 'Child #' + IntToStr(i));
|
||||
GetWinInfo(integer(childlist[i - 1]), node2);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
childlist.Free;
|
||||
consumer := TTreeNodeChildConsumer.Create(Self, ParentNode);
|
||||
EnumerateChildWindows(wnd, consumer.Consume);
|
||||
consumer.Free;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user