mirror of
https://github.com/ngeor/Chameleon.git
synced 2025-12-19 18:03:44 +01:00
254 lines
6.5 KiB
ObjectPascal
254 lines
6.5 KiB
ObjectPascal
unit frmResults;
|
|
|
|
{$MODE Delphi}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
|
ComCtrls, Menus;
|
|
|
|
type
|
|
TResults = class(TForm)
|
|
popListData: TPopupMenu;
|
|
Savelistdata1: TMenuItem;
|
|
TreeView1: TTreeView;
|
|
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
|
|
procedure Savelistdata1Click(Sender: TObject);
|
|
private
|
|
procedure GetWinInfoText(wnd: HWND; ParentNode: TTreeNode);
|
|
function GetWinInfoClassName(wnd: HWND; ParentNode: TTreeNode): String;
|
|
procedure GetWinInfoStyle(wnd: HWND; ParentNode: TTreeNode);
|
|
procedure GetWinInfoExtendedStyle(wnd: HWND; ParentNode: TTreeNode);
|
|
procedure GetWinInfoPlacement(wnd: HWND; ParentNode: TTreeNode);
|
|
procedure GetWinInfoListData(wnd: HWND; ParentNode: TTreeNode);
|
|
procedure GetWinInfoChildren(wnd: HWND; ParentNode: TTreeNode);
|
|
public
|
|
procedure GetWinInfo(wnd: HWND; ParentNode: TTreeNode);
|
|
end;
|
|
|
|
var
|
|
Results: TResults;
|
|
|
|
implementation
|
|
|
|
uses StyleNames, WindowEnumerator;
|
|
|
|
{$R *.lfm}
|
|
|
|
function GetClassNameAsString(wnd: HWND): String;
|
|
var
|
|
class_name: array [0..100] of Char;
|
|
len: Integer;
|
|
begin
|
|
len := GetClassName(wnd, class_name, 100);
|
|
if len > 0 then
|
|
Result := class_name
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TResults.TreeView1Change(Sender: TObject; Node: TTreeNode);
|
|
begin
|
|
if (Assigned(Node) and (Node.Text = '[List Data]')) then
|
|
TreeView1.PopupMenu := popListData
|
|
else
|
|
TreeView1.PopupMenu := nil;
|
|
end;
|
|
|
|
procedure TResults.Savelistdata1Click(Sender: TObject);
|
|
var
|
|
f: TextFile;
|
|
n: TTreeNode;
|
|
i: Integer;
|
|
|
|
function RemoveTag(const s: String): String;
|
|
var
|
|
pos1: Integer;
|
|
begin
|
|
pos1 := Pos('=', s);
|
|
Result := Copy(s, pos1 + 2, Length(s) - pos1 - 1);
|
|
end;
|
|
|
|
begin
|
|
AssignFile(f, 'c:\listdata.csv');
|
|
Rewrite(f);
|
|
n := TreeView1.Selected;
|
|
for i := 0 to n.Count - 1 do
|
|
begin
|
|
WriteLn(f, i, ';', RemoveTag(n.Items[i].Items[0].Text), ';',
|
|
RemoveTag(n.Items[i].Items[1].Text));
|
|
end;
|
|
CloseFile(f);
|
|
end;
|
|
|
|
procedure TResults.GetWinInfo(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
class_name: String;
|
|
begin
|
|
if IsWindow(wnd) then
|
|
begin
|
|
TreeView1.Items.AddChild(ParentNode, 'Handle = ' + IntToStr(wnd));
|
|
GetWinInfoText(wnd, ParentNode);
|
|
class_name := GetWinInfoClassName(wnd, ParentNode);
|
|
TreeView1.Items.AddChild(ParentNode, 'Parent Handle = ' + IntToStr(GetParent(wnd)));
|
|
GetWinInfoStyle(wnd, ParentNode);
|
|
GetWinInfoExtendedStyle(wnd, ParentNode);
|
|
GetWinInfoPlacement(wnd, ParentNode);
|
|
{ CompareText for case-insensitive comparison }
|
|
if CompareText(class_name, 'COMBOBOX') = 0 then
|
|
begin
|
|
GetWinInfoListData(wnd, ParentNode);
|
|
end;
|
|
GetWinInfoChildren(wnd, ParentNode);
|
|
end
|
|
else
|
|
TreeView1.Items.AddChild(ParentNode, 'Handle = (INVALID HANDLE)');
|
|
end;
|
|
|
|
procedure TResults.GetWinInfoText(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
len: Integer;
|
|
Text: PChar;
|
|
begin
|
|
len := GetWindowTextLength(wnd) + 1;
|
|
GetMem(Text, len);
|
|
GetWindowText(wnd, Text, len);
|
|
TreeView1.Items.AddChild(ParentNode, 'Caption = ' + Text);
|
|
FreeMem(Text);
|
|
end;
|
|
|
|
function TResults.GetWinInfoClassName(wnd: HWND; ParentNode: TTreeNode): String;
|
|
begin
|
|
Result := GetClassNameAsString(wnd);
|
|
TreeView1.Items.AddChild(ParentNode, 'Class name = ' + Result);
|
|
end;
|
|
|
|
procedure TResults.GetWinInfoStyle(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
style: Integer;
|
|
list: TStringList;
|
|
node1: TTreeNode;
|
|
i: Integer;
|
|
begin
|
|
style := GetWindowLong(wnd, GWL_STYLE);
|
|
list := GetWindowStyleNames(style);
|
|
|
|
with TreeView1.Items do
|
|
begin
|
|
node1 := AddChild(ParentNode, 'Style');
|
|
AddChild(node1, 'Value = ' + IntToStr(style));
|
|
|
|
for i := 0 to list.Count - 1 do
|
|
AddChild(node1, list[i]);
|
|
end;
|
|
|
|
list.Free();
|
|
end;
|
|
|
|
procedure TResults.GetWinInfoExtendedStyle(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
style: Integer;
|
|
list: TStringList;
|
|
node1: TTreeNode;
|
|
i: Integer;
|
|
begin
|
|
style := GetWindowLong(wnd, GWL_EXSTYLE);
|
|
list := GetExtendedWindowStyleNames(style);
|
|
|
|
with TreeView1.Items do
|
|
begin
|
|
node1 := AddChild(ParentNode, 'Extended Style');
|
|
AddChild(node1, 'Value = ' + IntToStr(style));
|
|
|
|
for i := 0 to list.Count - 1 do
|
|
AddChild(node1, list[i]);
|
|
end;
|
|
|
|
list.Free();
|
|
end;
|
|
|
|
procedure TResults.GetWinInfoPlacement(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
R1, R2: TRect;
|
|
node1: TTreeNode;
|
|
begin
|
|
GetWindowRect(wnd, R1);
|
|
Windows.GetClientRect(wnd, R2);
|
|
with TreeView1.Items do
|
|
begin
|
|
node1 := AddChild(ParentNode, 'Placement');
|
|
AddChild(node1, 'Left = ' + IntToStr(R1.Left));
|
|
AddChild(node1, 'Top = ' + IntToStr(R1.Top));
|
|
AddChild(node1, 'Width = ' + IntToStr(R1.Right - R1.Left));
|
|
AddChild(node1, 'Height = ' + IntToStr(R1.Bottom - R1.Top));
|
|
AddChild(node1, 'ClientWidth = ' + IntToStr(R2.Right));
|
|
AddChild(node1, 'ClientHeight = ' + IntToStr(R2.Bottom));
|
|
end;
|
|
end;
|
|
|
|
procedure TResults.GetWinInfoListData(wnd: HWND; ParentNode: TTreeNode);
|
|
var
|
|
i, cbcount: Integer;
|
|
node1, node2: TTreeNode;
|
|
itemtext: array [0..300] of Char;
|
|
begin
|
|
with TreeView1.Items do
|
|
begin
|
|
node1 := AddChild(ParentNode, '[List Data]');
|
|
cbcount := SendMessage(wnd, CB_GETCOUNT, 0, 0);
|
|
for i := 1 to cbcount do
|
|
begin
|
|
SendMessage(wnd, CB_GETLBTEXT, i - 1, Longint(@itemtext));
|
|
node2 := AddChild(node1, 'Item #' + IntToStr(i));
|
|
AddChild(node2, 'Text = ' + itemtext);
|
|
AddChild(node2, 'Data = ' +
|
|
IntToStr(SendMessage(wnd, CB_GETITEMDATA, i - 1, 0)));
|
|
end;
|
|
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
|
|
consumer: TTreeNodeChildConsumer;
|
|
begin
|
|
consumer := TTreeNodeChildConsumer.Create(Self, ParentNode);
|
|
EnumerateChildWindows(wnd, consumer.Consume);
|
|
consumer.Free;
|
|
end;
|
|
|
|
end.
|