diff --git a/Chameleon.lpi b/Chameleon.lpi
index e9cba0c..c476752 100644
--- a/Chameleon.lpi
+++ b/Chameleon.lpi
@@ -45,7 +45,7 @@
-
+
@@ -83,6 +83,11 @@
+
+
+
+
+
diff --git a/DfmEngine.pas b/DfmEngine.pas
index 856c214..35f8ada 100644
--- a/DfmEngine.pas
+++ b/DfmEngine.pas
@@ -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);
diff --git a/WindowEnumerator.pas b/WindowEnumerator.pas
new file mode 100644
index 0000000..084e2c6
--- /dev/null
+++ b/WindowEnumerator.pas
@@ -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.
diff --git a/frmResults.pas b/frmResults.pas
index de2e104..b63a2ca 100644
--- a/frmResults.pas
+++ b/frmResults.pas
@@ -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.