unit DUAutoExtrMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.ExtCtrls, Vcl.StdCtrls, System.Generics.Collections; type PAtEnt = ^TAtEnt; TAtEnt = record sName: String; nLevel, nCtrlType: Integer; end; TDlgMsaaExtrMain = class(TForm) pnTop: TPanel; vtTree: TVirtualStringTree; btnExtract: TButton; SP1: TSplitter; mmInfo: TMemo; cbTarget: TComboBox; procedure btnExtractClick(Sender: TObject); procedure vtTreeGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); procedure vtTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vtTreeGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); procedure vtTreeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); private { Private declarations } public { Public declarations } end; var DlgMsaaExtrMain: TDlgMsaaExtrMain; implementation uses Tocsg.MSAA, Tocsg.Strings, Winapi.ActiveX, Tocsg.VTUtil, Tocsg.Safe, Tocsg.WndUtil, UIAutomationClient_TLB, DelphiUIAutomation.Automation, DelphiUIAutomation.Base, DelphiUIAutomation.Window, DelphiUIAutomation.Statusbar, DelphiUIAutomation.Condition, DelphiUIAutomation.ControlTypeIDs, Tocsg.Network, Tocsg.Process; {$R *.dfm} procedure TDlgMsaaExtrMain.btnExtractClick(Sender: TObject); var sAdd, sText: String; procedure AddString(s: String); begin if s = sAdd then exit; sAdd := s; SumString(sText, sAdd, #13#10) end; procedure ExtractElements(pPNode: PVirtualNode; Element: IUIAutomationElement; nLevel: Integer); var AutoBase: TAutomationBase; Children: IUIAutomationElementArray; CEle: IUIAutomationElement; nCnt, i: Integer; pNode: PVirtualNode; pData: PAtEnt; begin Guard(AutoBase, TAutomationBase.Create(Element)); pData := VT_AddChildDataN(vtTree, pNode, pPNode); ZeroMemory(pData, SizeOf(TAtEnt)); pData.sName := AutoBase.Name; pData.nLevel := nLevel; pData.nCtrlType := AutoBase.CtrlType; // ¿§Áö ÄÚÆÄÀÏ·µ »çÀ̵å¹Ù = ·¹º§ 7, Name=Copilot, Type=50033 // ¿þÀÏ »çÀ̵å¹Ù = ·¹º§ 1, Naver=À̸§Á¸Àç,ÆäÀÌÁöÀ̸§(NAVER), Type=50030 if pData.nCtrlType = 50040 then begin var R: TRect := AutoBase.BoundingRectangle; MessageBox(Handle, PChar(Format('»çÀ̵å¹Ù? - N=%s, X=%d, Y=%d, W=%d, H=%d', [pData.sName, R.Left, R.Top, R.Width, R.Height])), PChar(Caption), MB_ICONWARNING or MB_OK); end; // case pData.nCtrlType of // UIA_PaneControlTypeId, // notepad++.exe º»¹®... // UIA_HyperlinkControlType, // 50005 // êÁöÇÇÆ¼¿¡¼­ »©¸é ÁÁÀ½ //// UIA_ImageControlTypeId, //// UIA_ListItemControlTypeId, // 50007 // êÁöÇÇÆ¼¿¡¼­ »©¸é ÁÁÀ½ // UIA_ListControlTypeId, // 50008 // UIA_TextControlTypeId, // 50020 // UIA_DataItemControlTypeId {50029} : AddString(pData.sName); //// else AddString(IntToStr(pData.nCtrlType) + ' : ' + pData.sName); // end; AddString(pData.sName); // Children := AutoBase.FindAll(TreeScope_Descendants); Children := AutoBase.FindAll; if Children <> nil then begin Children.Get_Length(nCnt); for i := 0 to nCnt - 1 do begin CEle := nil; Children.GetElement(i, CEle); if CEle <> nil then ExtractElements(pNode, CEle, nLevel + 1); end; end; end; var h: HWND; sTarget: String; UIAuto: TUIAuto; AutoWnd: TAutomationWindow; Children: IUIAutomationElementArray; CEle: IUIAutomationElement; bar: IAutomationStatusbar; nCnt, i: Integer; pData: PAtEnt; pNode, pPNode: PVirtualNode; el: IUIAutomationElement; begin sTarget := Trim(cbTarget.Text); h := FindWindowFromProcessName(sTarget); // Sleep(2000); // h := GetForegroundWindow; if h = 0 then begin MessageBox(Handle, PChar('ÇÁ·Î±×·¥À» ãÀ» ¼ö ¾ø½À´Ï´Ù.'), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; pPNode := nil; vtTree.BeginUpdate; try sText := ''; sAdd := ''; VT_Clear(vtTree); Children := nil; TUIAuto.CreateUIAuto; try el := TUIAuto.GetElementFromHandle(Pointer(h)); if el = nil then exit; Guard(AutoWnd, TAutomationWindow.Create(el, false {true})); // Guard(AutoWnd, TAutomationWindow.Create(el, true)); // mmInfo.Lines.Add(AutoWnd.Name); // bar := AutoWnd.StatusBar; // if bar <> nil then // mmInfo.Lines.Add(bar.Name); pData := VT_AddChildDataN(vtTree, pNode, pPNode); ZeroMemory(pData, SizeOf(TAtEnt)); pData.sName := AutoWnd.Name; pData.nCtrlType := AutoWnd.CtrlType; pData.nLevel := 0; SumString(sText, pData.sName, #13#10); Children := AutoWnd.FindAll; //(TreeScope_Element); if Children <> nil then begin nCnt := 0; Children.Get_Length(nCnt); for i := 0 to nCnt - 1 do begin CEle := nil; Children.GetElement(i, CEle); if CEle <> nil then ExtractElements(pNode, CEle, 1); end; end; // AutoWnd.Focus; // AutoWnd.Maximize; finally TUIAuto.DestroyUIAuto; end; mmInfo.Text := sText; finally VT_ExpandAll(vtTree, true); // VT_ExpandAll(vtTree, false); vtTree.EndUpdate; end; end; // ¹öư Ŭ¸¯ ±¸Çö //var // InvokePattern: IUIAutomationInvokePattern; //begin // // InvokePatternÀ» °¡Á®¿È (¹öư Ŭ¸¯°ú °°Àº µ¿ÀÛ ¼öÇà) // hr := Element.GetCurrentPattern(UIA_InvokePatternId, InvokePattern); // if Succeeded(hr) and (InvokePattern <> nil) then // begin // // ¹öư Ŭ¸¯ ½ÇÇà // hr := InvokePattern.Invoke; // if Succeeded(hr) then // Writeln('¹öưÀ» Ŭ¸¯Çß½À´Ï´Ù.') // else // Writeln('¹öư Ŭ¸¯¿¡ ½ÇÆÐÇß½À´Ï´Ù.'); // end // else // Writeln('Invoke ÆÐÅÏÀ» Áö¿øÇÏÁö ¾Ê´Â ¿ä¼ÒÀÔ´Ï´Ù.'); //end; procedure TDlgMsaaExtrMain.vtTreeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var pData: PAtEnt; begin pData := Sender.GetNodeData(Node); Finalize(pData^); end; procedure TDlgMsaaExtrMain.vtTreeGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); begin HintText := vtTree.Text[Node, Column]; end; procedure TDlgMsaaExtrMain.vtTreeGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); begin NodeDataSize := SizeOf(TAtEnt); end; procedure TDlgMsaaExtrMain.vtTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var pData: PAtEnt; begin if Column = 0 then begin pData := Sender.GetNodeData(Node); CellText := Format('[%d] N=%s, T=%d', [pData.nLevel, pData.sName, pData.nCtrlType]); end; end; end.