This commit is contained in:
mgkim 2025-12-30 16:10:29 +09:00
parent 58a4e1d98d
commit 49d948d7bc
2835 changed files with 1171089 additions and 0 deletions

View File

@ -0,0 +1,57 @@
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
*.res
#
# Type library file (binary). In old Delphi versions it should be stored.
# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
#*.tlb
#
# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
# Uncomment this if you are not using diagrams or use newer Delphi version.
#*.ddp
#
# Visual LiveBindings file. Added in Delphi XE2.
# Uncomment this if you are not using LiveBindings Designer.
#*.vlb
#
# Deployment Manager configuration file for your project. Added in Delphi XE2.
# Uncomment this if it is not mobile development and you do not use remote debug feature.
#*.deployproj
#
# Delphi compiler-generated binaries (safe to delete)
#*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
# Delphi autogenerated files (duplicated info)
*.cfg
*Resource.rc
# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk
# Delphi history and backups
__history/
*.~*
# Castalia statistics file
*.stat

View File

@ -0,0 +1,41 @@
version 2.2(Jun 9, 2020):
+Added support for older Delphi version: Now the minimal supported Delphi version is D7.
+Added support for FPC.
+Added recursive section feature: EnterRecursiveSection/ExitRecursiveSection.
+Added param/tag feature for all InterceptCreate functions.
+Added GetTrampolineParam function to get user param.
+Added GetCreatorThreadIdFromTrampoline function to get thread id that created the hook/trampoline.
+Added detection for non valid trampoline pointer.
+Added unittest.
+Replaced BeginHooks/BeginUnHooks by BeginTransaction.
+Replaced EndHooks/EndUnHooks by EndTransaction.
+Replaced GetNHook by GetHookCount.
+Replaced TDetours<T> by TIntercept<T,U>/TIntercept<T>
+Fixed many bugs related to MultiBytesNop.
+Fixed wrong displacement value for some branch instructions on x64.
+Fixed wrong offset size on x86 for GetJmpType function.
+Removed v1 compatibility.
+Now the library does not rely on Object.
+Code refactoring.
Jan 24,2015:
+Added support for vtable patching.
+Added GetNHook/IsHooked support for Interface.
Jan 20,2015:
+Added support to hook Delphi Interface by name.
Version2 , Mahdi Safsafi:
+Many bug fix.
+Added new hooking model architecture.
+Added multi hook support.
+Added COM hook support.
+Added instruction maping feature.
+Added hook detecting feature.
+Added BeginHooks/EndHooks.
+Added BeginUnHooks/EndUnHooks.
+Added IDetours interface.
+Added MultiNop instructions support.
+Generate better opcodes.
+Improved support for x64.
+Improved AllocMemAt function.

View File

@ -0,0 +1,35 @@
rem *****************************************
rem * Delphi CleanUp Batch. *
rem * *
rem * Clean identcache,local,dcu,exe, *
rem * map,drc files. *
rem * Clean hidden __history folder. *
rem * *
rem * Author: Mahdi Safsafi *
rem *****************************************
@echo off
Setlocal EnableDelayedExpansion
Del "*.identcache" /s/q
Del "*.local" /s/q
Del "*.dcu" /s/q
Del "*.exe" /s/q
Del "*.drc" /s/q
Del "*.map" /s/q
set mustdel=false
For /r %%f in (.) do (
set "mustdel=false"
if %%~nf==Win32 (
if exist "%%~ff\Debug\" set "mustdel=true"
if exist "%%~ff\Release\" set "mustdel=true"
) else if %%~nf==Win64 (
if exist "%%~ff\Debug\" set "mustdel=true"
if exist "%%~ff\Release\" set "mustdel=true"
)
if %%~nf==__history set "mustdel=true"
if !mustdel!==true (
if exist "%%~ff" rd /s/q "%%~ff"
)
)

View File

@ -0,0 +1,13 @@
program D7;
uses
Forms,
uMain in 'uMain.pas' {Main};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TMain, Main);
Application.Run;
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,45 @@
object Main: TMain
Left = 192
Top = 125
Width = 238
Height = 191
BorderStyle = bsSizeToolWin
Caption = 'Main'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object BtnHook: TButton
Left = 46
Top = 24
Width = 131
Height = 25
Caption = 'Hook'
TabOrder = 0
OnClick = BtnHookClick
end
object BtnMsgBox: TButton
Left = 46
Top = 64
Width = 131
Height = 25
Caption = 'MsgBox'
TabOrder = 1
OnClick = BtnMsgBoxClick
end
object BtnUnhook: TButton
Left = 46
Top = 104
Width = 131
Height = 25
Caption = 'Unhook'
TabOrder = 2
OnClick = BtnUnhookClick
end
end

View File

@ -0,0 +1,80 @@
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DDetours;
type
TMain = class(TForm)
BtnHook: TButton;
BtnMsgBox: TButton;
BtnUnhook: TButton;
procedure BtnHookClick(Sender: TObject);
procedure BtnMsgBoxClick(Sender: TObject);
procedure BtnUnhookClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Main: TMain;
implementation
{$R *.dfm}
type TMessageBox = function (hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
var TrampolineMessageBox : TMessageBox;
function InterceptMessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
var
Self: TMain;
begin
Self := GetTrampolineParam(TrampolineMessageBox);
Self.Caption := 'MessageBox hooked !';
Result := TrampolineMessageBox(hWnd, 'this text was hooked', 'this title was hooked', MB_ICONWARNING);
end;
procedure TMain.FormCreate(Sender: TObject);
begin
BtnUnHook.Enabled := False;
end;
procedure TMain.BtnHookClick(Sender: TObject);
begin
TrampolineMessageBox := InterceptCreate(@MessageBox, @InterceptMessageBox, Self);
BtnUnHook.Enabled := True;
BtnHook.Enabled := False;
end;
procedure TMain.BtnMsgBoxClick(Sender: TObject);
begin
MessageBox(0, 'text', 'caption', 0);
end;
procedure TMain.BtnUnHookClick(Sender: TObject);
begin
if Assigned(TrampolineMessageBox) then
begin
InterceptRemove(@TrampolineMessageBox);
TrampolineMessageBox := nil;
BtnHook.Enabled := True;
BtnUnHook.Enabled := False;
end;
end;
initialization
finalization
if Assigned(TrampolineMessageBox) then
InterceptRemove(@TrampolineMessageBox);
end.

View File

@ -0,0 +1,18 @@
program Demo1;
uses
Vcl.Forms,
uMain in 'uMain.pas' {Main},
CPUID in '..\..\..\Source\CPUID.pas',
DDetours in '..\..\..\Source\DDetours.pas',
InstDecode in '..\..\..\Source\InstDecode.pas',
LegacyTypes in '..\..\..\Source\LegacyTypes.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMain, Main);
Application.Run;
end.

View File

@ -0,0 +1,845 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{F3F06688-F7C7-4A42-B09B-18B38AB06934}</ProjectGuid>
<ProjectVersion>18.7</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>Demo1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<SanitizedProjectName>Demo1</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;StyleControls_dxe103Rio;vclFireDAC;IndySystem;tethering;svnui;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;TeeDB;FireDAC;vcltouch;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;inetdb;FMXTee;MyIdePlugin;soaprtl;DbxCommonDriver;FmxTeeUI;ibxpress;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;ibxbindings;fmxobj;vclwinx;vclib;rtl;Tee;DbxClientDriver;dclAbsDBd26;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;TeeUI;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;vclAbsDBd26;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;StyleControls_dxe103Rio;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;TeeDB;FireDAC;vcltouch;vcldb;bindcompfmx;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;inetdb;FMXTee;soaprtl;DbxCommonDriver;FmxTeeUI;ibxpress;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;ibxbindings;fmxobj;vclwinx;vclib;rtl;Tee;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;TeeUI;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uMain.pas">
<Form>Main</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="..\..\..\Source\CPUID.pas"/>
<DCCReference Include="..\..\..\Source\DDetours.pas"/>
<DCCReference Include="..\..\..\Source\InstDecode.pas"/>
<DCCReference Include="..\..\..\Source\LegacyTypes.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Application</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Demo1.dpr</Source>
</Source>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="Win32\Debug\Demo1.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>Demo1.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,45 @@
object Main: TMain
Left = 0
Top = 0
BorderStyle = bsToolWindow
Caption = 'Main'
ClientHeight = 134
ClientWidth = 257
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object BtnHook: TButton
Left = 48
Top = 16
Width = 161
Height = 25
Caption = 'Hook'
TabOrder = 0
OnClick = BtnHookClick
end
object BtnMsgBox: TButton
Left = 48
Top = 55
Width = 161
Height = 25
Caption = 'MessageBox'
TabOrder = 1
OnClick = BtnMsgBoxClick
end
object BtnUnHook: TButton
Left = 48
Top = 91
Width = 161
Height = 25
Caption = 'Unhook'
TabOrder = 2
OnClick = BtnUnHookClick
end
end

View File

@ -0,0 +1,81 @@
unit uMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, DDetours;
type
TMain = class(TForm)
BtnHook: TButton;
BtnMsgBox: TButton;
BtnUnHook: TButton;
procedure BtnHookClick(Sender: TObject);
procedure BtnUnHookClick(Sender: TObject);
procedure BtnMsgBoxClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Main: TMain;
implementation
{$R *.dfm}
type
TMessageBox = function(hWnd: hWnd; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall;
var
TrampolineMessageBox: TMessageBox = nil;
function InterceptMessageBox(hWnd: hWnd; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall;
var
Self: TMain;
begin
Self := GetTrampolineParam(TrampolineMessageBox);
Self.Caption := 'MessageBox hooked !';
Result := TrampolineMessageBox(hWnd, 'this text was hooked', 'this title was hooked', MB_ICONWARNING);
end;
procedure TMain.FormCreate(Sender: TObject);
begin
BtnUnHook.Enabled := False;
end;
procedure TMain.BtnHookClick(Sender: TObject);
begin
TrampolineMessageBox := InterceptCreate(@MessageBox, @InterceptMessageBox, Self);
BtnUnHook.Enabled := True;
BtnHook.Enabled := False;
end;
procedure TMain.BtnMsgBoxClick(Sender: TObject);
begin
MessageBox(0, 'text', 'caption', 0);
end;
procedure TMain.BtnUnHookClick(Sender: TObject);
begin
if Assigned(TrampolineMessageBox) then
begin
InterceptRemove(@TrampolineMessageBox);
TrampolineMessageBox := nil;
BtnHook.Enabled := True;
BtnUnHook.Enabled := False;
end;
end;
initialization
finalization
if Assigned(TrampolineMessageBox) then
InterceptRemove(@TrampolineMessageBox);
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="Demo1"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="Demo1.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="umain.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Main"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMain"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="Demo1"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\..\..\Source"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,22 @@
program Demo1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, uMain
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TMain, Main);
Application.Run;
end.

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="11"/>
<BuildModes Active="Default"/>
<Units Count="4">
<Unit0>
<Filename Value="Demo1.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="20"/>
</Unit0>
<Unit1>
<Filename Value="umain.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Main"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMain"/>
<IsVisibleTab Value="True"/>
<TopLine Value="40"/>
<CursorPos X="38" Y="50"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="C:\lazarus\fpc\3.0.4\source\rtl\win\wininc\ascdef.inc"/>
<EditorIndex Value="2"/>
<TopLine Value="248"/>
<CursorPos Y="257"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\..\..\Source\DDetours.pas"/>
<EditorIndex Value="1"/>
<TopLine Value="2291"/>
<CursorPos Y="2299"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit3>
</Units>
<JumpHistory Count="21" HistoryIndex="20">
<Position1>
<Filename Value="umain.pas"/>
</Position1>
<Position2>
<Filename Value="umain.pas"/>
<Caret Line="37" Column="21" TopLine="25"/>
</Position2>
<Position3>
<Filename Value="umain.pas"/>
<Caret Line="34" Column="28" TopLine="24"/>
</Position3>
<Position4>
<Filename Value="umain.pas"/>
<Caret Line="50" Column="6" TopLine="37"/>
</Position4>
<Position5>
<Filename Value="umain.pas"/>
<Caret Line="9" Column="20"/>
</Position5>
<Position6>
<Filename Value="umain.pas"/>
<Caret Line="49" TopLine="39"/>
</Position6>
<Position7>
<Filename Value="umain.pas"/>
<Caret Line="68" Column="42" TopLine="53"/>
</Position7>
<Position8>
<Filename Value="umain.pas"/>
<Caret Line="53" Column="5" TopLine="44"/>
</Position8>
<Position9>
<Filename Value="umain.pas"/>
<Caret Line="61" Column="9" TopLine="45"/>
</Position9>
<Position10>
<Filename Value="umain.pas"/>
<Caret Line="53" Column="5" TopLine="45"/>
</Position10>
<Position11>
<Filename Value="umain.pas"/>
<Caret Line="56" Column="51" TopLine="45"/>
</Position11>
<Position12>
<Filename Value="umain.pas"/>
<Caret Line="53" Column="54" TopLine="45"/>
</Position12>
<Position13>
<Filename Value="umain.pas"/>
<Caret Line="4" Column="2"/>
</Position13>
<Position14>
<Filename Value="umain.pas"/>
<Caret Line="69" Column="20" TopLine="54"/>
</Position14>
<Position15>
<Filename Value="umain.pas"/>
<Caret Line="70" Column="35" TopLine="54"/>
</Position15>
<Position16>
<Filename Value="umain.pas"/>
<Caret Line="75" Column="21" TopLine="59"/>
</Position16>
<Position17>
<Filename Value="umain.pas"/>
<Caret Line="74" TopLine="60"/>
</Position17>
<Position18>
<Filename Value="umain.pas"/>
<Caret Line="75" TopLine="60"/>
</Position18>
<Position19>
<Filename Value="umain.pas"/>
<Caret Line="74" TopLine="60"/>
</Position19>
<Position20>
<Filename Value="umain.pas"/>
<Caret Line="80" TopLine="64"/>
</Position20>
<Position21>
<Filename Value="umain.pas"/>
<Caret Line="48" Column="25" TopLine="35"/>
</Position21>
</JumpHistory>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0" ActiveMode=""/>
</RunParams>
</ProjectSession>
</CONFIG>

View File

@ -0,0 +1,39 @@
object Main: TMain
Left = 256
Height = 137
Top = 145
Width = 242
BorderStyle = bsToolWindow
Caption = 'Main'
ClientHeight = 137
ClientWidth = 242
OnCreate = FormCreate
LCLVersion = '2.0.8.0'
object BtnHook: TButton
Left = 49
Height = 27
Top = 23
Width = 141
Caption = 'Hook'
OnClick = BtnHookClick
TabOrder = 0
end
object BtnMsgBox: TButton
Left = 48
Height = 25
Top = 56
Width = 141
Caption = 'MessageBox'
OnClick = BtnMsgBoxClick
TabOrder = 1
end
object BtnUnhook: TButton
Left = 49
Height = 26
Top = 88
Width = 141
Caption = 'Unhook'
OnClick = BtnUnhookClick
TabOrder = 2
end
end

View File

@ -0,0 +1,90 @@
unit uMain;
{$mode Delphi}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
Windows, DDetours;
type
{ TMain }
TMain = class(TForm)
BtnHook: TButton;
BtnMsgBox: TButton;
BtnUnhook: TButton;
procedure BtnHookClick(Sender: TObject);
procedure BtnMsgBoxClick(Sender: TObject);
procedure BtnUnhookClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
Main: TMain;
implementation
{$R *.lfm}
type
TMessageBox = function(hWnd: HWND; lpText: LPCSTR; lpCaption: LPCSTR;
uType: UINT): longint; stdcall;
var
TrampolineMessageBox: TMessageBox = nil;
function InterceptMessageBox(hWnd: HWND; lpText: LPCSTR; lpCaption: LPCSTR;
uType: UINT): longint; stdcall;
var
Form: TMain;
begin
Form := GetTrampolineParam(TrampolineMessageBox);
Form.Caption := 'MessageBox Hooked!';
Result := TrampolineMessageBox(hWnd, 'this text was hooked.',
'this caption was hooked.', MB_ICONEXCLAMATION);
end;
{ TMain }
procedure TMain.BtnHookClick(Sender: TObject);
begin
BtnUnhook.Enabled := True;
BtnHook.Enabled := False;
@TrampolineMessageBox := InterceptCreate(@MessageBox, @InterceptMessageBox, Self);
end;
procedure TMain.BtnMsgBoxClick(Sender: TObject);
begin
MessageBox(0, 'text', 'caption', 0);
end;
procedure TMain.BtnUnhookClick(Sender: TObject);
begin
BtnHook.Enabled := True;
BtnUnHook.Enabled := False;
if Assigned(TrampolineMessageBox) then
begin
InterceptRemove(@TrampolineMessageBox);
TrampolineMessageBox := nil;
end;
end;
procedure TMain.FormCreate(Sender: TObject);
begin
BtnUnhook.Enabled := False;
end;
initialization
finalization
if Assigned(TrampolineMessageBox) then
InterceptRemove(@TrampolineMessageBox);
end.

View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -0,0 +1,39 @@
![Version](https://img.shields.io/badge/version-v2.2-yellow.svg)
![License](https://img.shields.io/github/license/MahdiSafsafi/DDetours)
![Lang](https://img.shields.io/github/languages/top/MahdiSafsafi/DDetours.svg)
The **DDetours** is a library allowing you to hook Delphi and Windows API functions. It provides an easy way to insert and remove hook.
## What's new in Version 2.2 ? ##
* Support for FPC and older Delphi version notably D7.
* Support for recursive section.
* Support for custom parameter/tag for each trampoline function.
* See CHANGELOG for complete changes.
## Features : ##
* Supports **x86** and **x64** architecture.
* Supports <u><b>multiple hook</b></u> for a single function.
* Supports Delphi 7/2005-2010/XE-Rio(Delphi 10.3).
* Supports Lazarus/FPC.
* Supports recursive function inside the hook function.
* Supports hooking interfaces methods by **MethodName** or **MethodIndex**.
* Supports COM **vtable** patching.
* Supports hooking object methods.
* Allows calling the original function via <u><b>Trampoline/NextHook</b></u> function.
* **COM**/**Interfaces**/**win32api** support.
* Thread-safe for hooking and unhooking.
* 64 bit address is supported.
* The library does not use any external library.
* The library can insert and remove the hook at any time.
* The library contains InstDecode library, that allows you to decode CPU instructions (x86/x64).
This project contains two sub project : **DDetours** and **InstDecode*** library.
The InstDecode Library is a library that can decode both (x86/x64) instructions. You can consider it as a small disassembler routine.
It can decode instruction and getting information about the instruction (size of instruction, displacement, immediate data, jump address,..) without displaying mnemonics making it very faster and very small in size.
These two libraries were coded in pure Pascal language with Delphi XE7.
See the [Wiki](https://github.com/MahdiSafsafi/DDetours/wiki) page for more information about how to use the library.
Please, if you find any bug, feel free to report it.

View File

@ -0,0 +1,285 @@
// **************************************************************************************************
// CPUID for Delphi.
// Unit CPUID
// https://github.com/MahdiSafsafi/DDetours
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License, v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at
// https://mozilla.org/MPL/2.0/.
// **************************************************************************************************
unit CPUID;
{$IFDEF FPC}
{$MODE DELPHI}
{$WARN 4055 OFF}
{$WARN 4082 OFF}
{$WARN 5057 OFF}
{$ENDIF FPC}
interface
{$I DDetoursDefs.inc}
uses
SysUtils
{$IFNDEF FPC}, LegacyTypes{$ENDIF FPC}
;
type
{ Do not change registers order ! }
TCPUIDStruct = packed record
rEAX: Cardinal; { EAX Register }
rEBX: Cardinal; { EBX Register }
rEDX: Cardinal; { EDX Register }
rECX: Cardinal; { ECX Register }
end;
PCPUIDStruct = ^TCPUIDStruct;
procedure CallCPUID(ID: NativeUInt; var CPUIDStruct: TCPUIDStruct);
function IsCPUIDSupported(): Boolean;
type
TCPUVendor = (vUnknown, vIntel, vAMD, vNextGen);
TCPUEncoding = set of (REX, VEX, EVEX);
TCPUInstructions = set of (iMultiNop);
var
CPUVendor: TCPUVendor;
CPUEncoding: TCPUEncoding;
CPUInsts: TCPUInstructions;
implementation
var
CPUIDSupported: Boolean = False;
function ___IsCPUIDSupported: Boolean;
asm
{$IFDEF CPUX64}
PUSH RCX
MOV RCX,RCX
PUSHFQ
POP RAX
MOV RCX, RAX
XOR RAX, $200000
PUSH RAX
POPFQ
PUSHFQ
POP RAX
XOR RAX, RCX
SHR RAX, 21
AND RAX, 1
PUSH RCX
POPFQ
POP RCX
{$ELSE !CPUX64}
PUSH ECX
PUSHFD
POP EAX { EAX = EFLAGS }
MOV ECX, EAX { Save the original EFLAGS value . }
{
CPUID is supported only if we can modify
bit 21 of EFLAGS register !
}
XOR EAX, $200000
PUSH EAX
POPFD { Set the new EFLAGS value }
PUSHFD
POP EAX { Read EFLAGS }
{
Check if the 21 bit was modified !
If so ==> Return True .
else ==> Return False.
}
XOR EAX, ECX
SHR EAX, 21
AND EAX, 1
PUSH ECX
POPFD { Restore original EFLAGS value . }
POP ECX
{$ENDIF CPUX64}
end;
procedure ___CallCPUID(const ID: NativeInt; var CPUIDStruct);
asm
{
ALL REGISTERS (rDX,rCX,rBX) MUST BE SAVED BEFORE
EXECUTING CPUID INSTRUCTION !
}
{$IFDEF CPUX64}
PUSH R9
PUSH RBX
PUSH RDX
MOV RAX,RCX
MOV R9,RDX
CPUID
{$IFNDEF FPC}
MOV R9.TCPUIDStruct.rEAX,EAX
MOV R9.TCPUIDStruct.rEBX,EBX
MOV R9.TCPUIDStruct.rECX,ECX
MOV R9.TCPUIDStruct.rEDX,EDX
{$ELSE FPC}
MOV [R9].TCPUIDStruct.rEAX,EAX
MOV [R9].TCPUIDStruct.rEBX,EBX
MOV [R9].TCPUIDStruct.rECX,ECX
MOV [R9].TCPUIDStruct.rEDX,EDX
{$ENDIF !FPC}
POP RDX
POP RBX
POP R9
{$ELSE !CPUX64}
PUSH EDI
PUSH ECX
PUSH EBX
MOV EDI,EDX
CPUID
{$IFNDEF FPC}
MOV EDI.TCPUIDStruct.rEAX,EAX
MOV EDI.TCPUIDStruct.rEBX,EBX
MOV EDI.TCPUIDStruct.rECX,ECX
MOV EDI.TCPUIDStruct.rEDX,EDX
{$ELSE FPC}
MOV [EDI].TCPUIDStruct.rEAX,EAX
MOV [EDI].TCPUIDStruct.rEBX,EBX
MOV [EDI].TCPUIDStruct.rECX,ECX
MOV [EDI].TCPUIDStruct.rEDX,EDX
{$ENDIF !FPC}
POP EBX
POP ECX
POP EDI
{$ENDIF CPUX64}
end;
function ___IsAVXSupported: Boolean;
asm
{
Checking for AVX support requires 3 steps:
1) Detect CPUID.1:ECX.OSXSAVE[bit 27] = 1
=> XGETBV enabled for application use
2) Detect CPUID.1:ECX.AVX[bit 28] = 1
=> AVX instructions supported.
3) Issue XGETBV and verify that XCR0[2:1] = 11b
=> XMM state and YMM state are enabled by OS.
}
{ Steps : 1 and 2 }
{$IFDEF CPUX64}
MOV RAX, 1
PUSH RCX
PUSH RBX
PUSH RDX
{$ELSE !CPUX64}
MOV EAX, 1
PUSH ECX
PUSH EBX
PUSH EDX
{$ENDIF CPUX64}
CPUID
AND ECX, $018000000
CMP ECX, $018000000
JNE @@NOT_SUPPORTED
XOR ECX,ECX
{
Delphi does not support XGETBV !
=> We need to use the XGETBV opcodes !
}
DB $0F DB $01 DB $D0 // XGETBV
{ Step :3 }
AND EAX, $06
CMP EAX, $06
JNE @@NOT_SUPPORTED
MOV EAX, 1
JMP @@END
@@NOT_SUPPORTED:
XOR EAX,EAX
@@END:
{$IFDEF CPUX64}
POP RDX
POP RBX
POP RCX
{$ELSE !CPUX64}
POP EDX
POP EBX
POP ECX
{$ENDIF CPUX64}
end;
procedure CallCPUID(ID: NativeUInt; var CPUIDStruct: TCPUIDStruct);
begin
FillChar(CPUIDStruct, SizeOf(TCPUIDStruct), #0);
if not CPUIDSupported then
raise Exception.Create('CPUID instruction not supported.')
else
___CallCPUID(ID, CPUIDStruct);
end;
function IsCPUIDSupported: Boolean;
begin
Result := CPUIDSupported;
end;
type
TVendorName = array [0 .. 12] of AnsiChar;
function GetVendorName(): TVendorName;
var
Info: PCPUIDStruct;
P: PByte;
begin
Result := '';
if not IsCPUIDSupported then
Exit;
Info := GetMemory(SizeOf(TCPUIDStruct));
CallCPUID(0, Info^);
P := PByte(NativeInt(Info) + 4); // Skip EAX !
Move(P^, PByte(@Result[0])^, 12);
FreeMemory(Info);
end;
procedure __Init__;
var
vn: TVendorName;
Info: TCPUIDStruct;
r: Cardinal;
begin
CPUVendor := vUnknown;
{$IFDEF CPUX64}
CPUEncoding := [REX];
{$ELSE !CPUX64}
CPUEncoding := [];
{$ENDIF CPUX64}
CPUInsts := [];
if IsCPUIDSupported then
begin
vn := GetVendorName();
if vn = 'GenuineIntel' then
CPUVendor := vIntel
else if vn = 'AuthenticAMD' then
CPUVendor := vAMD
else if vn = 'NexGenDriven' then
CPUVendor := vNextGen;
CallCPUID(1, Info);
r := Info.rEAX and $F00;
case r of
$F00, $600:
Include(CPUInsts, iMultiNop);
end;
if ___IsAVXSupported then
Include(CPUEncoding, VEX);
end;
end;
initialization
CPUIDSupported := ___IsCPUIDSupported;
__Init__;
end.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
{.$DEFINE HOOK_INTERNAL_FUNCTIONS} // hook internal functions.
{$IFDEF FPC}
{$ASMMODE INTEL}
{$ELSE !FPC}
{$T-}
{$IF CompilerVersion >= 17.0}
{$DEFINE DELPHI_2005_UP}
{$IFEND}
{$IF CompilerVersion >= 18.5}
{$DEFINE DELPHI_2007_UP}
{$IFEND}
{$IF CompilerVersion >= 20}
{$DEFINE DELPHI_2009_UP}
{$IFEND}
{$IF CompilerVersion >= 21}
{$DEFINE DELPHI_2010_UP}
{$IFEND}
{$IF CompilerVersion >= 22}
{$DEFINE DELPHI_XE_UP}
{$IFEND}
{$IF CompilerVersion >= 23}
{$DEFINE DELPHI_XE2_UP}
{$IFEND}
{$IF CompilerVersion >= 33}
{$DEFINE DELPHI_RIO_UP}
{$IFEND}
{$IFDEF DELPHI_2005_UP}
{$DEFINE SUPPORTS_INLINE}
{$ENDIF}
{$IFDEF DELPHI_XE2_UP}
{$DEFINE SUPPORTS_RTTI}
{$DEFINE SUPPORTS_GENERICS}
{$DEFINE RENAMED_NAMESPACE}
{$ENDIF}
{$ENDIF FPC}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
// **************************************************************************************************
//
// https://github.com/MahdiSafsafi/DDetours
//
// **************************************************************************************************
unit LegacyTypes;
interface
{$I DDetoursDefs.inc}
type
{$IFNDEF FPC}
{$IFNDEF DELPHI_XE_UP}
NativeInt = Integer;
NativeUInt = Cardinal;
PNativeInt = ^NativeInt;
PNativeUInt = ^NativeUInt;
{$IFDEF MSWINDOWS}
TThreadID = LongWord;
{$ENDIF MSWINDOWS}
{$ENDIF DELPHI_XE_UP}
{$ENDIF FPC}
Int8 = Shortint;
Int16 = Smallint;
Int32 = Integer;
UInt8 = Byte;
UInt16 = Word;
UInt32 = Cardinal;
PInt8 = ^Int8;
PInt16 = ^Int16;
PInt32 = ^Int32;
PInt64 = ^Int64;
PUInt8 = ^UInt8;
PUInt16 = ^UInt16;
PUInt32 = ^UInt32;
PUInt64 = ^UInt64;
SIZE_T = NativeUInt;
implementation
end.

View File

@ -0,0 +1,130 @@
// **************************************************************************************************
// Part of x86 Instruction Decode Library [InstDecode]
//
// https://github.com/MahdiSafsafi/DDetours
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License, v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at
// https://mozilla.org/MPL/2.0/.
// **************************************************************************************************
{ Reference : Intel® 64 and IA-32 Architectures Software Developers Manual Vol 2 }
type
TModRmFlagsArray = array [Byte] of Byte;
PModRmFlagsArray = ^TModRmFlagsArray;
{
ModRMFlags :
Bits:4 3 2 1 0 .
Bit 0 : Set ==> Register Indirect Addressing Mode .
Bit 1 : Set ==> Displacement 8 bit .
Bit 2 : Set ==> Displacement 16 bit .
Bit 3 : Set ==> Displacement 32 bit.
Bit 4 : Set ==> SIB Used .
Values:
$00 ==> Register .
$01 ==> Register Indirect Addressing Mode with No Displacement .
$03 ==> Register Indirect Addressing Mode + 8 bit Displacement .
$04 ==> 16 bit Displacement only without register .
$05 ==> Register Indirect Addressing Mode + 16 bit Displacement .
$08 ==> 32 bit Displacement only without register .
$09 ==> Register Indirect Addressing Mode + 32 bit Displacement .
$11 ==> Register Indirect Addressing Mode + SIB .
$13 ==> Register Indirect Addressing Mode + SIB + 8 bit Displacement .
$19 ==> Register Indirect Addressing Mode + SIB + 32 bit Displacement .
}
const
ModRM16Flags: TModRmFlagsArray = (
{ => Mod=00b <= }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
$01, $01, $01, $01, $01, $01, $04, $01, { 00 }
{ => Mod=01b <= }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
$03, $03, $03, $03, $03, $03, $03, $03, { 01 }
{ => Mod=10b <= }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
$05, $05, $05, $05, $05, $05, $05, $05, { 10 }
{ => Mod=11b <= }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00 { 11 }
);
ModRM32Flags: TModRmFlagsArray = (
{ => Mod=00b <= }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
$01, $01, $01, $01, $11, $08, $01, $01, { 00 }
{ => Mod=01b <= }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
$03, $03, $03, $03, $13, $03, $03, $03, { 01 }
{ => Mod=10b <= }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
$09, $09, $09, $09, $19, $09, $09, $09, { 10 }
{ => Mod=11b <= }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00, { 11 }
$00, $00, $00, $00, $00, $00, $00, $00 { 11 }
);
ModRmFlags: array [0 .. 3] of PModRmFlagsArray = ( //
nil,
@ModRM16Flags, { AddrMode 16-bits }
@ModRM32Flags, { AddrMode 32-bits }
@ModRM32Flags { AddrMode 64-bits }
);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
{ TlHelp32 types for fpc }
const
TH32CS_SNAPHEAPLIST = $00000001;
TH32CS_SNAPPROCESS = $00000002;
TH32CS_SNAPTHREAD = $00000004;
TH32CS_SNAPMODULE = $00000008;
TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST or TH32CS_SNAPPROCESS or
TH32CS_SNAPTHREAD or TH32CS_SNAPMODULE;
TH32CS_INHERIT = $80000000;
TLS_OUT_OF_INDEXES = DWORD($FFFFFFFF); // FPC does not declare TLS_OUT_OF_INDEXES.
type
tagTHREADENTRY32 = record
dwSize: DWORD;
cntUsage: DWORD;
th32ThreadID: DWORD;
th32OwnerProcessID: DWORD;
tpBasePri: Longint;
tpDeltaPri: Longint;
dwFlags: DWORD;
end;
THREADENTRY32 = tagTHREADENTRY32;
PTHREADENTRY32 = ^tagTHREADENTRY32;
LPTHREADENTRY32 = ^tagTHREADENTRY32;
TThreadEntry32 = tagTHREADENTRY32;
TThread32First = function (hSnapshot: THandle; var lpte: TThreadEntry32): BOOL stdcall;
TThread32Next = function (hSnapshot: THandle; var lpte: TThreadENtry32): BOOL stdcall;
TCreateToolhelp32Snapshot = function (dwFlags, th32ProcessID: DWORD): THandle; stdcall;

View File

@ -0,0 +1,59 @@
program Test;
{$IFNDEF TESTINSIGHT}
{$APPTYPE CONSOLE}
{$ENDIF}{$STRONGLINKTYPES ON}
uses
System.SysUtils,
{$IFDEF TESTINSIGHT}
TestInsight.DUnitX,
{$ENDIF }
DUnitX.Loggers.Console,
DUnitX.Loggers.Xml.NUnit,
DUnitX.TestFramework,
uTest in 'uTest.pas';
var
runner : ITestRunner;
results : IRunResults;
logger : ITestLogger;
nunitLogger : ITestLogger;
begin
{$IFDEF TESTINSIGHT}
TestInsight.DUnitX.RunRegisteredTests;
exit;
{$ENDIF}
try
//Check command line options, will exit if invalid
TDUnitX.CheckCommandLine;
//Create the test runner
runner := TDUnitX.CreateRunner;
//Tell the runner to use RTTI to find Fixtures
runner.UseRTTI := True;
//tell the runner how we will log things
//Log to the console window
logger := TDUnitXConsoleLogger.Create(true);
runner.AddLogger(logger);
//Generate an NUnit compatible XML File
nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile);
runner.AddLogger(nunitLogger);
runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests;
//Run tests
results := runner.Execute;
if not results.AllPassed then
System.ExitCode := EXIT_ERRORS;
{$IFNDEF CI}
//We don't want this happening when running under CI.
if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then
begin
System.Write('Done.. press <Enter> key to quit.');
System.Readln;
end;
{$ENDIF}
except
on E: Exception do
System.Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@ -0,0 +1,779 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{AE7FD8B6-27D8-45EA-B53E-B9F470DA9BA0}</ProjectGuid>
<ProjectVersion>18.7</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>Test.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<DCC_UnitSearchPath>$(DUnitX);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<SanitizedProjectName>Test</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_UsePackage>DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;IndyIPServer;IndySystem;tethering;fmxFireDAC;FireDAC;bindcompfmx;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;FmxTeeUI;ibxpress;fmx;FireDACIBDriver;xmlrtl;soapmidas;ibxbindings;rtl;DbxClientDriver;CustomIPTransport;dbexpress;IndyCore;bindcomp;dsnap;FireDACCommon;IndyIPClient;RESTBackendComponents;soapserver;dbxcds;bindengine;CloudService;dsnapxml;dbrtl;IndyProtocols;FireDACCommonDriver;inet;$(DCC_UsePackage)</DCC_UsePackage>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;StyleControls_dxe103Rio;vclFireDAC;IndySystem;tethering;svnui;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;TeeDB;FireDAC;vcltouch;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;inetdb;FMXTee;MyIdePlugin;soaprtl;DbxCommonDriver;FmxTeeUI;ibxpress;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;ibxbindings;fmxobj;vclwinx;vclib;rtl;Tee;DbxClientDriver;dclAbsDBd26;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;TeeUI;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;vclAbsDBd26;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;StyleControls_dxe103Rio;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;TeeDB;FireDAC;vcltouch;vcldb;bindcompfmx;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;inetdb;FMXTee;soaprtl;DbxCommonDriver;FmxTeeUI;ibxpress;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;ibxbindings;fmxobj;vclwinx;vclib;rtl;Tee;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;TeeUI;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uTest.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Console</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Test.dpr</Source>
</Source>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\Test.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>Test.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,149 @@
unit uTest;
interface
uses
DUnitX.TestFramework, DDetours;
type
[TestFixture]
TDDetours = class(TObject)
public
[Setup]
procedure Setup;
[TearDown]
procedure TearDown;
// Sample Methods
// Simple single Test
[Test]
procedure Test1;
[Test]
procedure Test2;
[Test]
procedure Test3;
[Test]
procedure Test4;
end;
implementation
const
Pi = 3.14;
const
NewPi = 3.14159265359;
type
TAdd = function(a, b: Integer): Integer;
TSub = function(a, b: Integer): Integer;
TGetPi = function(): Extended;
var
TrampolineAdd: TAdd = nil;
TrampolineSub: TSub = nil;
TrampolineGetPi: TGetPi = nil;
FInterceptSub: TIntercept<TSub, Integer>;
function Add(a, b: Integer): Integer;
begin
Result := a + b;
end;
function Sub(a, b: Integer): Integer;
begin
Result := a - b;
end;
function GetPi(): Extended;
begin
Result := Pi;
end;
function InterceptAdd(a, b: Integer): Integer;
begin
Result := TrampolineAdd(a, b);
end;
function InterceptSub(a, b: Integer): Integer;
var
Param: Integer;
begin
Param := Integer(GetTrampolineParam(TrampolineSub));
Result := TrampolineSub(a, Param);
end;
function InterceptSub2(a, b: Integer): Integer;
begin
Result := FInterceptSub.TrampoLine(a, FInterceptSub.Param);
end;
function InterceptGetPi(): Extended;
begin
Result := NewPi;
end;
procedure TDDetours.Setup;
begin
end;
procedure TDDetours.TearDown;
begin
end;
procedure TDDetours.Test1;
var
a, b, c: Integer;
begin
a := 3;
b := 2;
c := a + b;
TrampolineAdd := InterceptCreate(@Add, @InterceptAdd);
Assert.AreEqual(Add(a, b), c);
InterceptRemove(@TrampolineAdd);
Assert.AreEqual(Add(a, b), c);
end;
procedure TDDetours.Test2;
var
a, b, c: Integer;
Param: Pointer;
begin
a := 3;
b := 2;
c := a - b;
Param := Pointer(0);
TrampolineSub := InterceptCreate(@Sub, @InterceptSub, Param, DefaultInterceptOptions);
Assert.AreEqual(Sub(a, b), a);
InterceptRemove(@TrampolineSub);
Assert.AreEqual(Sub(a, b), c);
end;
procedure TDDetours.Test3;
begin
TrampolineAdd := InterceptCreate(@GetPi, @InterceptGetPi);
Assert.AreEqual(GetPi(), NewPi);
InterceptRemove(@TrampolineAdd);
Assert.AreEqual(GetPi(), Pi);
end;
procedure TDDetours.Test4;
var
a, b, c: Integer;
begin
a := 3;
b := 2;
c := a - b;
FInterceptSub := TIntercept<TSub, Integer>.Create(Sub, InterceptSub2, 0);
Assert.AreEqual(Sub(a, b), a);
FInterceptSub.Free();
Assert.AreEqual(Sub(a, b), c);
end;
initialization
TDUnitX.RegisterTestFixture(TDDetours);
end.

57
EM.Lib/DelphiUIAutomation/.gitignore vendored Normal file
View File

@ -0,0 +1,57 @@
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
#*.res
#
# Type library file (binary). In old Delphi versions it should be stored.
# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
#*.tlb
#
# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
# Uncomment this if you are not using diagrams or use newer Delphi version.
#*.ddp
#
# Visual LiveBindings file. Added in Delphi XE2.
# Uncomment this if you are not using LiveBindings Designer.
#*.vlb
#
# Deployment Manager configuration file for your project. Added in Delphi XE2.
# Uncomment this if it is not mobile development and you do not use remote debug feature.
#*.deployproj
#
# Delphi compiler-generated binaries (safe to delete)
*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
# Delphi autogenerated files (duplicated info)
*.cfg
*Resource.rc
# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk
# Delphi history and backups
__history/
*.~*
# Castalia statistics file
*.stat

View File

@ -0,0 +1,127 @@
JHC Systems Limited
Individual Contributor Licence Agreement
Thank you for your interest in JHC Systems Limited software. In
order to clarify the intellectual property licence granted with
Contributions from any person or entity, JHC Systems Limited must
have a Contributor Licence Agreement ("CLA") on file that has been
signed by each Contributor, indicating agreement to the licence terms
below. This licence is for your protection as a Contributor as well
as the protection of JHC Systems Limited and its users; it does not
change your rights to use your own Contributions for any other purpose.
If you have not already done so, please complete and sign, then scan
and email a pdf file of this Agreement to ian.haines@jhc.co.uk.
Please read this document carefully before signing and keep a copy
for your records.
Full name: ______________________________________________________
(optional) Public name: _________________________________________
Mailing Address: ________________________________________________
________________________________________________
Country: ______________________________________________________
Telephone: ______________________________________________________
E-Mail: ______________________________________________________
You accept and agree to the following terms and conditions for Your
present and future Contributions submitted to JHC Systems Limited.
Except for the licence granted herein to JHC Systems Limited and
recipients of software distributed by JHC Systems Limited, You
reserve all right, title, and interest in and to Your Contributions.
1. Definitions.
"You" (or "Your") shall mean the copyright owner or legal entity
authorized by the copyright owner that is making this Agreement
with JHC Systems Limited. For legal entities, the entity making a
Contribution and all other entities that control, are controlled
by, or are under common control with that entity are considered to
be a single Contributor. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"Contribution" shall mean any original work of authorship,
including any modifications or additions to an existing work, that
is intentionally submitted by You to JHC Systems Limited for inclusion
in, or documentation of, any of the products owned or managed by
JHC Systems Limited (the "Work"). For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written
communication sent to JHC Systems Limited or its representatives,
including but not limited to communication on electronic mailing
lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, JHC Systems Limited for the purpose of
discussing and improving the Work, but excluding communication that
is conspicuously marked or otherwise designated in writing by You
as "Not a Contribution."
2. Grant of Copyright Licence. Subject to the terms and conditions of
this Agreement, You hereby grant to JHC Systems Limited and to
recipients of software distributed by JHC Systems Limited a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright licence to reproduce, prepare derivative works of,
publicly display, publicly perform, sublicence, and distribute Your
Contributions and such derivative works.
3. Grant of Patent Licence. Subject to the terms and conditions of
this Agreement, You hereby grant to JHC Systems Limited and to
recipients of software distributed by JHC Systems Limited a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent licence to make, have
made, use, offer to sell, sell, import, and otherwise transfer the
Work, where such licence applies only to those patent claims
licensable by You that are necessarily infringed by Your
Contribution(s) alone or by combination of Your Contribution(s)
with the Work to which such Contribution(s) was submitted. If any
entity institutes patent litigation against You or any other entity
(including a cross-claim or counterclaim in a lawsuit) alleging
that your Contribution, or the Work to which you have contributed,
constitutes direct or contributory patent infringement, then any
patent licences granted to that entity under this Agreement for
that Contribution or Work shall terminate as of the date such
litigation is filed.
4. You represent that you are legally entitled to grant the above
licence. If your employer(s) has rights to intellectual property
that you create that includes your Contributions, you represent
that you have received permission to make Contributions on behalf
of that employer, that your employer has waived such rights for
your Contributions to JHC Systems Limited, or that your employer has
executed a separate Corporate CLA with JHC Systems Limited.
5. You represent that each of Your Contributions is Your original
creation (see section 7 for submissions on behalf of others). You
represent that Your Contribution submissions include complete
details of any third-party licence or other restriction (including,
but not limited to, related patents and trademarks) of which you
are personally aware and which are associated with any part of Your
Contributions.
6. You are not expected to provide support for Your Contributions,
except to the extent You desire to provide support. You may provide
support for free, for a fee, or not at all. Unless required by
applicable law or agreed to in writing, You provide Your
Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied, including, without
limitation, any warranties or conditions of TITLE, NON-
INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
7. Should You wish to submit work that is not Your original creation,
You may submit it to JHC Systems Limited separately from any
Contribution, identifying the complete details of its source and of
any licence or other restriction (including, but not limited to,
related patents, trademarks, and licence agreements) of which you
are personally aware, and conspicuously marking the work as
"Submitted on behalf of a third-party: [named here]".
8. You agree to notify JHC Systems Limited of any facts or circumstances
of which you become aware that would make these representations
inaccurate in any respect.
Please sign: __________________________________ Date: ________________

View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -0,0 +1,5 @@
DelphiUIAutomation
Copyright 2015 (C) JHC Systems Limited
This product includes software developed at
JHC Systems Limited (http://www.jhc.co.uk/).

View File

@ -0,0 +1,215 @@
# DelphiUIAutomation
Delphi classes that wrap the [MS UIAutomation library](https://msdn.microsoft.com/en-us/library/vstudio/ms753388(v=vs.100).aspx).
DelphiUIAutomation is a framework for automating rich client applications based on Win32 (and specifically tested with Delphi XE5). It is written in Delphi XE5 and it requires no use of scripting languages.
Tests and automation programs using DelphiUIAutomation can be written with Delphi and used in any testing framework available to Delphi.
It provides a consistent object-oriented API, hiding the complexity of Microsoft's UIAutomation library and windows messages.
## Getting started
The DelphiUIAutomation library is a wrapper for the UIAutomationClient library, which has been extracted into the UIAutomationClient_TLB source file. As the generated code is large and complex, this has been wrapped up in a number of units, each providing classes that encapsulate part of this library (together with other utility methods).
### Initialise the libray
```pascal
TUIAuto.CreateUIAuto; // Initialise the library
```
### Launching an application
The TAutomationApplication class provides functionality to start and attach to an application. There are 3 class methods provided to do this.
* Launch - this will launch the application supplied, and pass in any supplied arguments
* Attach - this will attach to an already launched application, based on the executable name
* LaunchOrAttach - this will either attach to an already launched application, or launch the application.
The snippet below will check whether the Project1.exe is running, and attach if it is, or it will start the application, and then attach to it.
```pascal
Application := TAutomationApplication.LaunchOrAttach(
'democlient\Win32\Debug\Project1.exe',
''
```
When attached to an application, it is possible to call further methods on it
* Kill - Will kill the process associated with the application
* WaitWhileBusy - Waits for the application to be idle, this has an optional timeout (in milliseconds) associated with it
* SaveScreenshot - Takes a screenshot of the application, and then saves this to a file.
### Getting hold of a window
To get a 'desktop' window (i.e. one that appears in the Windows tasks bar), then the TAutomationDesktop class provides a class function that returns a TAutomationWindow object.
```pascal
var
notepad : IAutomationWindow;
...
notepad := TAutomationDesktop.GetDesktopWindow('Untitled - Notepad');
notepad.Focus;
```
This will find (it is there) a window that has the given title, and set focus to it. This window is independant of the overalll application, and might not even be associated with the same application that is being automated.
To get an 'application' window, i.e. one associated with another window, first the parent window must be found, and then the target child can be found using the ''Window'' method. In the example below, the child window 'Security' of the notepad window is searched for.
```pascal
var
security : IAutomationWindow
...
security := notepad.Window('Security');
```
### Finding a control
Each control contained in a window can be identified by the index of that control OR sometimes (this depends on the control type) by the text associated with it. For example, in order to get the textbox associated with the connection window (and assuming that it is the 1st Edit box on the window), the following code will find the editbox, and change the text to be USER1.
```pascal
var
user : IAutomationEditBox;
user := connect.GetEditBoxByIndex(0);
user.Text := 'USER1';
```
### Invoking actions on controls
In order to click the 'OK' button associated with the connection window, it can be found by the text associated with the button, the following code will find the button, and call the click event.
```pascal
var
btnOK : IAutomationButton;
...
btnOK := connect.GetButton('OK');
btnOk.Click;
```
# Current supported controls
The currently supported controls are ...
* TButton
* TCheckBox
* TComboBox
* TEditBox
* TRadioButton
* TStatusBar
* TStringGrid (using an extended TStringGrid control that implements UIAutomation patterns)
* TPageControl
* TTab
* TTextBox
* TTreeView and TTreeViewItem
[More details, and the status of currently supported controls](https://github.com/jhc-systems/DelphiUIAutomation/wiki/CurrentSupportedControls)
# Added Automation Support for Controls
Many Delphi controls do not implement the automatin interfaces in the same manner as Visual Studio does in WPF, so that the Automation ID and Name are not 'properly' populated, so the controls can only be found by knowing their position within the tree, and cannot be found via the name or ID. The controls below extend the basic controls to export these values, amongst other properties.
## TEdit & TCombobox
The [controls sub-project](https://github.com/jhc-systems/DelphiUIAutomation/tree/master/controls) extends the automation properties of the TEdit and TComboBox, to simulate the way that WPF populates the Automation ID and the name with the NAME of the actual control, not a random value.
## TStringGrid
The [controls sub-project](https://github.com/jhc-systems/DelphiUIAutomation/tree/master/controls) allows the automation of some of the elements of the TStringGrid. It extends the control to allow it to interact with the MS-UIAutomation libraries.
```pascal
var
grid : IAutomationStringGrid;
items : TObjectList<TAutomationStringGridItem>;
item : TAutomationStringGridItem;
item1 : IAutomationStringGridItem;
...
// Get the first string grid associated with the window
grid := enquiry.GetStringGridByIndex(0);
// Show what the value is (i.e. the contents of the selected cell)
writeln ('Value is ' + grid.Value);
// Get the cell at 3,3 and shows it's value
writeln ('Item @ 3-3 is ' +grid.GetItem(3,3).Name);
// Get the selected cell
item := grid.Selected;
// Show the value of the selected cell (should be the same as the Grid's value
writeln ('Selected is ' + item.Name);
// Get the list of column headers (i.e. first fixed row)
write ('Column Headers : ');
items := grid.ColumnHeaders;
for item in items do
begin
writeln (item.Name);
end;
// Select the item at 2,4
item1 := grid.GetItem(2,4);
// Show that selection has changed.
writeln ('Selected is ' + grid.Selected.Name);
```
## TTreeView and TTreeViewItem
```pascal
// Get the 0th treeview
tv1 := enquiry.getTreeViewByIndex(0);
// Get the item with the following text
tvi := tv1.GetItem('Sub-SubItem');
// Select the item
tvi.select;
```
## Navigating to specific elements in the StringGrid and right-clicking
As the automation does not expose the cells fully (as they do not technically exist in the TStringGrid), it is necessary to do the following ..
```pascal
// Get the grid item
item := grid.GetItem(3,3);
// Select it
item.Select;
// Create a mouse to move the pointer
mouse := TAutomationMouse.Create;
// Get the bounding rectangle of the item (this is relative to the grid)
itemRect := item.BoundingRectangle;
// Get the overall grid bounding rectangle
gridRect := grid.BoundingRectangle;
// Move to the correct location, offsetting to make sure the mouse point is inside the cells itself
mouse.Location := TPoint.Create(gridRect.left + itemRect.left +15, gridRect.Top + itemRect.top +15);
mouse.LeftClick;
mouse.RightClick;
```
# Contributors
* [Mark Humphreys](https://github.com/markhumphreysjhc)
* Robert Deutschmann - Example Howto and AutomatedButton
# License
Apache Version 2.0 Copyright (C) 2015
See license.txt for details.
# See also
* [Microsoft Accessibility](https://msdn.microsoft.com/en-us/library/vstudio/ms753388(v=vs.100).aspx)
* [UIAutomation for Powershell](http://uiautomation.codeplex.com/documentation)
* [TestStack.White](https://github.com/TestStack/White)
* [UI Automation - A wrapper around Microsoft's UI Automation libraries.](https://github.com/vijayakumarsuraj/UIAutomation)

View File

@ -0,0 +1,165 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-17 JHC Systems Limited }
{ }
{ Author: Robert Deutschmann <robert.deutschmann@ekor.ch> }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedButton;
interface
uses
UIAutomationCore_TLB,
messages,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TAutomatedButton = class(TButton,
IValueProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedButton]);
end;
{ TAutomatedButton }
function TAutomatedButton.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
//if (patternID = UIA_ValuePatternID) then
if (patternID = UIA_InvokePatternId) then
begin
pRetVal := self;
end;
end;
function TAutomatedButton.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_ButtonControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedButton.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedButton.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedButton.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedButton.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.Text;
end;
function TAutomatedButton.SetValue(val: PWideChar): HResult;
begin
self.Text := val;
Result := S_OK;
end;
procedure TAutomatedButton.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,211 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedCombobox;
interface
uses
UIAutomationCore_TLB,
messages,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TAutomatedCombobox = class(TCombobox,
IValueProvider,
IExpandCollapseProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
// IExpandCollapseProvider
function Expand: HResult; stdcall;
function Collapse: HResult; stdcall;
function Get_ExpandCollapseState(out pRetVal: ExpandCollapseState): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedCombobox]);
end;
{ TAutomatedCombobox }
function TAutomatedCombobox.Collapse: HResult;
begin
if (self.DroppedDown) then
self.DroppedDown := false;
result := S_OK;
end;
function TAutomatedCombobox.Expand: HResult;
begin
if (not self.DroppedDown) then
self.DroppedDown := true;
result := S_OK;
end;
function TAutomatedCombobox.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if (patternID = UIA_ValuePatternID) or
(patternID = UIA_ExpandCollapsePatternId) then
begin
pRetVal := self;
end;
end;
function TAutomatedCombobox.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_ComboboxControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedCombobox.Get_ExpandCollapseState(
out pRetVal: ExpandCollapseState): HResult;
begin
if self.DroppedDown then
pRetVal := ExpandCollapseState_Expanded
else
pRetVal := ExpandCollapseState_Collapsed;
result := S_OK;
end;
function TAutomatedCombobox.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedCombobox.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedCombobox.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedCombobox.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.Text;
end;
function TAutomatedCombobox.SetValue(val: PWideChar): HResult;
var
idx : integer;
begin
Result := S_OK;
if (self.Style = csDropDownList) then
begin
// try and find the value in the list
idx := self.items.indexOf(val);
if (idx <> -1) then
self.ItemIndex := idx
else
Result := S_FALSE;
end
else
self.Text := val;
end;
procedure TAutomatedCombobox.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,46 @@
package AutomatedControls;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
vcl;
contains
UIAutomationCore_TLB in 'UIAutomationCore_TLB.pas',
AutomatedStringGrid in 'AutomatedStringGrid.pas',
AutomatedEdit in 'AutomatedEdit.pas',
AutomatedCombobox in 'AutomatedCombobox.pas',
AutomatedMaskEdit in 'AutomatedMaskEdit.pas',
AutomatedStaticText in 'AutomatedStaticText.pas',
AutomatedCustomPanel in 'AutomatedCustomPanel.pas',
AutomatedButton in 'AutomatedButton.pas',
AutomatedStringGridItem in 'AutomatedStringGridItem.pas';
end.

View File

@ -0,0 +1,923 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{33C4540D-6125-4624-8186-8877092F8503}</ProjectGuid>
<MainSource>AutomatedControls.dpk</MainSource>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Package</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>AutomatedControls</SanitizedProjectName>
<GenDll>true</GenDll>
<GenPackage>true</GenPackage>
<DCC_CBuilderOutput>All</DCC_CBuilderOutput>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<DCC_UsePackage>rtl;$(DCC_UsePackage);$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>rtl;vcl;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>rtl;vcl;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="rtl.dcp"/>
<DCCReference Include="vcl.dcp"/>
<DCCReference Include="UIAutomationCore_TLB.pas"/>
<DCCReference Include="AutomatedStringGrid.pas"/>
<DCCReference Include="AutomatedEdit.pas"/>
<DCCReference Include="AutomatedCombobox.pas"/>
<DCCReference Include="AutomatedMaskEdit.pas"/>
<DCCReference Include="AutomatedStaticText.pas"/>
<DCCReference Include="AutomatedCustomPanel.pas"/>
<DCCReference Include="AutomatedButton.pas"/>
<DCCReference Include="AutomatedStringGridItem.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Package</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">AutomatedControls.dpk</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2057</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
<VersionInfoKeys Name="package"/>
<VersionInfoKeys Name="label"/>
<VersionInfoKeys Name="versionCode"/>
<VersionInfoKeys Name="versionName"/>
<VersionInfoKeys Name="persistent"/>
<VersionInfoKeys Name="restoreAnyVersion"/>
<VersionInfoKeys Name="installLocation"/>
<VersionInfoKeys Name="largeHeap"/>
<VersionInfoKeys Name="theme"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k190.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp190.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k190.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp190.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="4">
<DeployFile LocalName="..\..\..\..\..\Public\Documents\Embarcadero\Studio\18.0\Bpl\AutomatedControls.bpl" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,46 @@
package AutomatedControlsTokyo;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
vcl;
contains
UIAutomationCore_TLB in 'UIAutomationCore_TLB.pas',
AutomatedStringGrid in 'AutomatedStringGrid.pas',
AutomatedEdit in 'AutomatedEdit.pas',
AutomatedCombobox in 'AutomatedCombobox.pas',
AutomatedMaskEdit in 'AutomatedMaskEdit.pas',
AutomatedStaticText in 'AutomatedStaticText.pas',
AutomatedCustomPanel in 'AutomatedCustomPanel.pas',
AutomatedButton in 'AutomatedButton.pas',
AutomatedStringGridItem in 'AutomatedStringGridItem.pas';
end.

View File

@ -0,0 +1,927 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{33C4540D-6125-4624-8186-8877092F8503}</ProjectGuid>
<MainSource>AutomatedControlsTokyo.dpk</MainSource>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Package</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>AutomatedControlsTokyo</SanitizedProjectName>
<GenDll>true</GenDll>
<GenPackage>true</GenPackage>
<DCC_CBuilderOutput>All</DCC_CBuilderOutput>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<DCC_UsePackage>rtl;$(DCC_UsePackage);$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>rtl;vcl;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>rtl;vcl;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="rtl.dcp"/>
<DCCReference Include="vcl.dcp"/>
<DCCReference Include="UIAutomationCore_TLB.pas"/>
<DCCReference Include="AutomatedStringGrid.pas"/>
<DCCReference Include="AutomatedEdit.pas"/>
<DCCReference Include="AutomatedCombobox.pas"/>
<DCCReference Include="AutomatedMaskEdit.pas"/>
<DCCReference Include="AutomatedStaticText.pas"/>
<DCCReference Include="AutomatedCustomPanel.pas"/>
<DCCReference Include="AutomatedButton.pas"/>
<DCCReference Include="AutomatedStringGridItem.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Package</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">AutomatedControlsTokyo.dpk</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2057</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
<VersionInfoKeys Name="package"/>
<VersionInfoKeys Name="label"/>
<VersionInfoKeys Name="versionCode"/>
<VersionInfoKeys Name="versionName"/>
<VersionInfoKeys Name="persistent"/>
<VersionInfoKeys Name="restoreAnyVersion"/>
<VersionInfoKeys Name="installLocation"/>
<VersionInfoKeys Name="largeHeap"/>
<VersionInfoKeys Name="theme"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="4">
<DeployFile LocalName="..\..\..\..\..\Public\Documents\Embarcadero\Studio\19.0\Bpl\AutomatedControlsTokyo.bpl" Configuration="Debug" Class="ProjectOutput"/>
<DeployFile LocalName="C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutomatedControlsTokyo.bpl" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>AutomatedControlsTokyo.bpl</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,174 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016-17 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedCustomPanel;
interface
uses
UIAutomationCore_TLB,
messages,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls;
type
TAutomatedCustomPanel = class(TCustomPanel,
IValueProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
function GetValue:String; virtual;
procedure SetTheValue(const AValue: String); virtual;
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedCustomPanel]);
end;
{ TAutomatedCustomPanel }
function TAutomatedCustomPanel.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if (patternID = UIA_ValuePatternID) then
begin
pRetVal := self;
end;
end;
function TAutomatedCustomPanel.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_PaneControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedCustomPanel.GetValue: String;
begin
result := self.Text;
end;
procedure TAutomatedCustomPanel.SetTheValue (const AValue: String);
begin
self.SetValue(PWideChar(AValue));
end;
function TAutomatedCustomPanel.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedCustomPanel.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedCustomPanel.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedCustomPanel.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.GetValue;
end;
function TAutomatedCustomPanel.SetValue(val: PWideChar): HResult;
begin
self.Text := val;
Result := S_OK;
end;
procedure TAutomatedCustomPanel.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,162 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedEdit;
interface
uses
UIAutomationCore_TLB,
messages,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TAutomatedEdit = class(TEdit,
IValueProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedEdit]);
end;
{ TAutomatedEdit }
function TAutomatedEdit.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if (patternID = UIA_ValuePatternID) then
begin
pRetVal := self;
end;
end;
function TAutomatedEdit.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_EditControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedEdit.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedEdit.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedEdit.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedEdit.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.Text;
end;
function TAutomatedEdit.SetValue(val: PWideChar): HResult;
begin
self.Text := val;
Result := S_OK;
end;
procedure TAutomatedEdit.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,163 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedMaskEdit;
interface
uses
UIAutomationCore_TLB,
messages,
mask,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TAutomatedMaskEdit = class(TMaskEdit,
IValueProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedMaskEdit]);
end;
{ TAutomatedMaskEdit }
function TAutomatedMaskEdit.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if (patternID = UIA_ValuePatternID) then
begin
pRetVal := self;
end;
end;
function TAutomatedMaskEdit.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_EditControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedMaskEdit.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedMaskEdit.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedMaskEdit.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedMaskEdit.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.Text;
end;
function TAutomatedMaskEdit.SetValue(val: PWideChar): HResult;
begin
self.Text := val;
Result := S_OK;
end;
procedure TAutomatedMaskEdit.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,162 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedStaticText;
interface
uses
UIAutomationCore_TLB,
messages,
ActiveX,
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TAutomatedStaticText = class(TStaticText,
IValueProvider,
IRawElementProviderSimple)
private
{ Private declarations }
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
{ Protected declarations }
public
{ Public declarations }
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
published
{ Published declarations }
end;
procedure Register;
implementation
uses
windows;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedStaticText]);
end;
{ TAutomatedStaticText }
function TAutomatedStaticText.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if (patternID = UIA_ValuePatternID) then
begin
pRetVal := self;
end;
end;
function TAutomatedStaticText.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_AutomationIdPropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_TextControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedStaticText.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedStaticText.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
pRetVal := 0; // Maybe?
Result := S_OK;
end;
function TAutomatedStaticText.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedStaticText.Get_Value(out pRetVal: WideString): HResult;
begin
Result := S_OK;
pRetVal := self.Text;
end;
function TAutomatedStaticText.SetValue(val: PWideChar): HResult;
begin
self.Text := val;
Result := S_OK;
end;
procedure TAutomatedStaticText.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,391 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-17 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedStringGrid;
interface
uses
AutomatedStringGridItem,
UIAutomationCore_TLB,
windows,
messages,
classes,
ActiveX,
grids;
type
TAutomatedStringGrid = class(TStringGrid,
ISelectionProvider,
IGridProvider,
ITableProvider,
IInvokeProvider,
IValueProvider,
IRawElementProviderSimple,
IRawElementProviderSimple2)
private
FRawElementProviderSimple : IRawElementProviderSimple;
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
protected
function GetCol: Integer; virtual;
function GetRow: Integer; virtual;
function GetColumnCount: integer; virtual;
function GetRowCount: integer; virtual;
function GetCell(column: integer; row: integer) : String; virtual;
function GetCanMultipleSelect: Integer; virtual;
function CreateCell(ACount, ARow: integer; AValue: String; ARect: TRect) : IAutomatedStringGridItem; virtual;
public
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// ISelectionProvider
///<remarks>
/// Will return the selected row (if possible)
///</remarks>
function GetSelection(out pRetVal: PSafeArray): HResult; virtual; stdcall;
function Get_CanSelectMultiple(out pRetVal: Integer): HResult; stdcall;
function Get_IsSelectionRequired(out pRetVal: Integer): HResult; stdcall;
// IInvokeProvider
function Invoke: HResult; stdcall;
// IRawElementProviderSimple2
function ShowContextMenu: HResult; virtual; stdcall;
// IValueProvider
function SetValue(val: PWideChar): HResult; stdcall;
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
// IGridProvider
function GetItem(row: SYSINT; column: SYSINT; out pRetVal: IRawElementProviderSimple): HResult; stdcall;
function Get_RowCount(out pRetVal: SYSINT): HResult; stdcall;
function Get_ColumnCount(out pRetVal: SYSINT): HResult; stdcall;
// ITableProvider
function GetRowHeaders(out pRetVal: PSafeArray): HResult; stdcall;
function GetColumnHeaders(out pRetVal: PSafeArray): HResult; stdcall;
function Get_RowOrColumnMajor(out pRetVal: RowOrColumnMajor): HResult; stdcall;
end;
procedure Register;
implementation
uses
dialogs,
sysutils,
Variants;
procedure Register;
begin
RegisterComponents('Automation', [TAutomatedStringGrid]);
end;
{ TAutomationStringGrid }
function TAutomatedStringGrid.GetColumnHeaders(
out pRetVal: PSafeArray): HResult;
var
intf : IAutomatedStringGridItem;
outBuffer : PSafeArray;
unk : IUnknown;
Bounds : array [0..0] of TSafeArrayBound;
count : integer;
begin
pRetVal := nil;
// is a cell selected?
if (self.FixedRows <> 0) then
begin
bounds[0].lLbound := 0;
bounds[0].cElements := self.getColumnCount;
outBuffer := SafeArrayCreate(VT_UNKNOWN, 1, @Bounds);
for count := 0 to self.getColumnCount -1 do
begin
intf := self.CreateCell(count, 0, self.getCell(count, 0), self.CellRect(count, 0));
if intf <> nil then
begin
unk := intf as IUnknown;
Result := SafeArrayPutElement(&outBuffer, count, Pointer(unk)^);
if Result <> S_OK then
begin
SafeArrayDestroy(outBuffer);
pRetVal := nil;
result := E_OUTOFMEMORY;
exit;
end
end;
end;
pRetVal := outBuffer;
result := S_OK;
end
else
begin
pRetVal := nil;
result := S_FALSE;
end;
end;
function TAutomatedStringGrid.getCell(column: integer; row: integer) : String;
begin
result := self.Cells[column, row];
end;
function TAutomatedStringGrid.GetItem(row, column: SYSINT;
out pRetVal: IRawElementProviderSimple): HResult;
var
intf : IRawElementProviderSimple;
begin
result := S_OK;
intf := self.CreateCell(column, row, self.getCell(column, row), self.CellRect(column, row)).asIRawElementProviderSimple;
pRetVal := intf;
end;
function TAutomatedStringGrid.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
result := S_OK;
pRetval := nil;
if ((patternID = UIA_InvokePatternId) or
(patternID = UIA_ValuePatternId) or
(patternID = UIA_TablePatternId) or
(patternID = UIA_GridPatternId) or
(patternID = UIA_SelectionPatternId)) then
begin
pRetVal := self;
end;
end;
function TAutomatedStringGrid.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else if(propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.Name);
result := S_OK;
end
else if (propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varInteger;
TVarData(pRetVal).VInteger := UIA_DataGridControlTypeId;
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedStringGrid.GetRowHeaders(out pRetVal: PSafeArray): HResult;
begin
pRetVal := nil;
result := S_FALSE;
end;
function TAutomatedStringGrid.CreateCell(ACount, ARow: integer; AValue: String; ARect: TRect) : IAutomatedStringGridItem;
begin
result := TAutomatedStringGridItem.create(self, ACount, ARow, AValue, ARect);
end;
function TAutomatedStringGrid.GetSelection(out pRetVal: PSafeArray): HResult;
var
intf : IAutomatedStringGridItem;
outBuffer : PSafeArray;
unk : IUnknown;
Bounds : array [0..0] of TSafeArrayBound;
count : integer;
iRow : integer;
begin
pRetVal := nil;
iRow := Self.Row;
// is a cell selected?
if (iRow > -1) then
begin
bounds[0].lLbound := 0;
bounds[0].cElements := self.getColumnCount;
outBuffer := SafeArrayCreate(VT_UNKNOWN, 1, @Bounds);
for count := 0 to self.getColumnCount -1 do
begin
intf := self.CreateCell(count, iRow, self.getCell(count, iRow), self.CellRect(count, iRow));
if intf <> nil then
begin
unk := intf as IUnknown;
Result := SafeArrayPutElement(&outBuffer, count, Pointer(unk)^);
if Result <> S_OK then
begin
SafeArrayDestroy(outBuffer);
pRetVal := nil;
result := E_OUTOFMEMORY;
exit;
end
end;
end;
pRetVal := outBuffer;
result := S_OK;
end
else
begin
pRetVal := nil;
result := S_FALSE;
end;
end;
function TAutomatedStringGrid.getCanMultipleSelect: Integer;
begin
result := 0;
end;
function TAutomatedStringGrid.Get_CanSelectMultiple(out pRetVal: Integer): HResult;
begin
pRetVal := self.getCanMultipleSelect;
result := S_OK;
end;
function TAutomatedStringGrid.Get_ColumnCount(out pRetVal: SYSINT): HResult;
begin
pRetVal := self.getColumnCount;
result := S_OK;
end;
function TAutomatedStringGrid.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := UiaHostProviderFromHwnd (self.Handle, pRetVal);
end;
function TAutomatedStringGrid.Get_IsSelectionRequired(out pRetVal: Integer): HResult;
begin
pRetVal := 0;
result := S_OK;
end;
function TAutomatedStringGrid.Get_ProviderOptions(out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedStringGrid.Get_RowCount(out pRetVal: SYSINT): HResult;
begin
pretVal := self.getRowCount;
result := S_OK;
end;
function TAutomatedStringGrid.getRowCount: integer;
begin
result := self.rowCount;
end;
function TAutomatedStringGrid.getColumnCount: integer;
begin
result := self.colCount;
end;
function TAutomatedStringGrid.Get_RowOrColumnMajor(
out pRetVal: RowOrColumnMajor): HResult;
begin
pRetVal := RowOrColumnMajor_RowMajor;
result := S_OK;
end;
function TAutomatedStringGrid.Invoke: HResult;
begin
PostMessage(self.Handle, WM_LBUTTONDBLCLK, Integer(self),0);
result := S_OK;
end;
function TAutomatedStringGrid.SetValue(val: PWideChar): HResult;
begin
self.Cells[self.Col, self.Row] := val;
result := S_OK;
end;
function TAutomatedStringGrid.Get_Value(out pRetVal: WideString): HResult;
begin
pRetVal := self.getCell(self.Col, self.Row);
result := S_OK;
end;
function TAutomatedStringGrid.getCol: Integer;
begin
result := self.Col;
end;
function TAutomatedStringGrid.getRow: Integer;
begin
result := self.Row;
end;
function TAutomatedStringGrid.ShowContextMenu: HResult;
begin
// Descendant classes can implement this
result := S_OK;
end;
function TAutomatedStringGrid.Get_IsReadOnly(out pRetVal: Integer): HResult;
begin
// pRetVal := self
pRetVal := 0;
result := S_OK;
end;
procedure TAutomatedStringGrid.WMGetObject(var Message: TMessage);
begin
if (Message.Msg = WM_GETOBJECT) then
begin
QueryInterface(IID_IRawElementProviderSimple, FRawElementProviderSimple);
message.Result := UiaReturnRawElementProvider(self.Handle, Message.WParam, Message.LParam, FRawElementProviderSimple);
end
else
Message.Result := DefWindowProc(self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
end.

View File

@ -0,0 +1,368 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-17 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit AutomatedStringGridItem;
interface
uses
ActiveX,
types,
UIAutomationCore_TLB,
classes;
type
IAutomatedStringGridItem = interface
['{86427F3B-A5DD-4553-84DE-2A724D9E4DA5}']
function asIRawElementProviderSimple: IRawElementProviderSimple;
end;
type
TAutomatedStringGridItem = class (TInterfacedPersistent,
IRawElementProviderSimple,
ISelectionItemProvider,
IValueProvider,
IRawElementProviderFragment,
IGridItemProvider,
IInvokeProvider,
IAutomatedStringGridItem,
IRawElementProviderSimple2)
strict private
FOwner : TComponent;
FValue: string;
FRow: integer;
FColumn: integer;
FSelected : boolean;
FCellRect : TRect;
private
procedure SetColumn(const Value: integer);
procedure SetRow(const Value: integer);
procedure SetTheValue(const Value: string);
procedure SetSelected(const Value: boolean);
function GetSelected : boolean;
function GetTheValue: string;
protected
procedure SelectCell; virtual;
public
property Row : integer read FRow write SetRow;
property Column : integer read FColumn write SetColumn;
property Value : string read GetTheValue write SetTheValue;
property Selected : boolean read GetSelected write SetSelected;
property CellRect : TRect read FCellRect write FCellRect;
property Owner : TComponent read FOwner write FOwner;
// IRawElementProviderSimple
function Get_ProviderOptions(out pRetVal: ProviderOptions): HResult; stdcall;
function GetPatternProvider(patternId: SYSINT; out pRetVal: IUnknown): HResult; stdcall;
function GetPropertyValue(propertyId: SYSINT; out pRetVal: OleVariant): HResult; stdcall;
function Get_HostRawElementProvider(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IInvokeProvider
function Invoke: HResult; virtual; stdcall;
// ISelectionItemProvider
function Select: HResult; stdcall;
function AddToSelection: HResult; stdcall;
function RemoveFromSelection: HResult; stdcall;
function Get_IsSelected(out pRetVal: Integer): HResult; stdcall;
function Get_SelectionContainer(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IRawElementProviderSimple2
function ShowContextMenu: HResult; virtual; stdcall;
// IValueProvider
function Get_Value(out pRetVal: WideString): HResult; stdcall;
function SetValue(val: PWideChar): HResult; stdcall;
function Get_IsReadOnly(out pRetVal: Integer): HResult; stdcall;
// IGridItemProvider
function Get_row(out pRetVal: SYSINT): HResult; stdcall;
function Get_column(out pRetVal: SYSINT): HResult; stdcall;
function Get_RowSpan(out pRetVal: SYSINT): HResult; stdcall;
function Get_ColumnSpan(out pRetVal: SYSINT): HResult; stdcall;
function Get_ContainingGrid(out pRetVal: IRawElementProviderSimple): HResult; stdcall;
// IRawElementProviderFragment
function Navigate(direction: NavigateDirection; out pRetVal: IRawElementProviderFragment): HResult; stdcall;
function GetRuntimeId(out pRetVal: PSafeArray): HResult; stdcall;
function get_BoundingRectangle(out pRetVal: UiaRect): HResult; stdcall;
function GetEmbeddedFragmentRoots(out pRetVal: PSafeArray): HResult; stdcall;
function SetFocus: HResult; stdcall;
function Get_FragmentRoot(out pRetVal: IRawElementProviderFragmentRoot): HResult; stdcall;
constructor Create(AOwner: TComponent; ACol, ARow : integer; AValue : String; ACellRect : TRect);
function asIRawElementProviderSimple: IRawElementProviderSimple;
end;
implementation
uses
AutomatedStringGrid,
sysutils;
{ TAutomatedStringGridItem }
function TAutomatedStringGridItem.AddToSelection: HResult;
begin
result := (self as ISelectionItemProvider).Select;
end;
constructor TAutomatedStringGridItem.Create(AOwner: TComponent; ACol, ARow : integer; AValue : String; ACellRect : TRect);
begin
inherited create;
self.Owner := AOwner;
self.CellRect := ACellRect;
self.Column := ACol;
self.Row := ARow;
self.Value := AValue;
self.Selected := false;
end;
function TAutomatedStringGridItem.GetEmbeddedFragmentRoots(
out pRetVal: PSafeArray): HResult;
begin
result := S_FALSE;
end;
function TAutomatedStringGridItem.GetPatternProvider(patternId: SYSINT;
out pRetVal: IInterface): HResult;
begin
pRetval := nil;
result := S_FALSE;
if ((patternID = UIA_SelectionItemPatternId) or
(patternID = UIA_GridItemPatternId) or
(patternID = UIA_InvokePatternId) or
(patternID = UIA_ValuePatternId)) then
begin
pRetVal := self;
result := S_OK;
end
end;
function TAutomatedStringGridItem.Invoke: HResult;
begin
result := S_OK;
end;
function TAutomatedStringGridItem.GetPropertyValue(propertyId: SYSINT;
out pRetVal: OleVariant): HResult;
begin
if(propertyId = UIA_ControlTypePropertyId) then
begin
TVarData(pRetVal).VType := varWord;
TVarData(pRetVal).VWord := UIA_DataItemControlTypeId;
result := S_OK;
end
else if (propertyId = UIA_NamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := PWideChar(self.Value);
result := S_OK;
end
else if(propertyId = UIA_ClassNamePropertyId) then
begin
TVarData(pRetVal).VType := varOleStr;
TVarData(pRetVal).VOleStr := pWideChar(self.ClassName);
result := S_OK;
end
else
result := S_FALSE;
end;
function TAutomatedStringGridItem.GetRuntimeId(
out pRetVal: PSafeArray): HResult;
begin
result := S_FALSE;
end;
function TAutomatedStringGridItem.GetSelected: boolean;
begin
result := FSelected;
end;
function TAutomatedStringGridItem.GetTheValue: string;
begin
result := self.FValue;
end;
function TAutomatedStringGridItem.get_BoundingRectangle(
out pRetVal: UiaRect): HResult;
begin
pRetVal.left := self.FCellRect.Left;
pRetVal.top := self.FCellRect.Top;
// Not sure about these
pRetVal.width := self.FCellRect.Right;
pRetVal.height := self.FCellRect.Bottom;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_HostRawElementProvider(
out pRetVal: IRawElementProviderSimple): HResult;
begin
pRetVal := nil;
result := S_OK;
end;
function TAutomatedStringGridItem.ShowContextMenu: HResult;
begin
result := S_FALSE;
end;
function TAutomatedStringGridItem.Get_IsReadOnly(
out pRetVal: Integer): HResult;
begin
pRetVal := 1;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_IsSelected(
out pRetVal: Integer): HResult;
begin
result := S_OK;
if self.FSelected then
pRetVal := 0
else
pRetVal := 1;
end;
function TAutomatedStringGridItem.Get_ProviderOptions(
out pRetVal: ProviderOptions): HResult;
begin
pRetVal:= ProviderOptions_ServerSideProvider;
Result := S_OK;
end;
function TAutomatedStringGridItem.Get_Value(out pRetVal: WideString): HResult;
begin
pRetVal := self.FValue;
result := S_OK;
end;
function TAutomatedStringGridItem.Navigate(direction: NavigateDirection;
out pRetVal: IRawElementProviderFragment): HResult;
begin
result := S_FALSE;
end;
function TAutomatedStringGridItem.RemoveFromSelection: HResult;
begin
result := (self as ISelectionItemProvider).RemoveFromSelection;
end;
procedure TAutomatedStringGridItem.SelectCell;
begin
self.FSelected := true;
end;
function TAutomatedStringGridItem.Select: HResult;
begin
self.SelectCell;
result := S_OK;
end;
procedure TAutomatedStringGridItem.SetColumn(const Value: integer);
begin
FColumn := Value;
end;
function TAutomatedStringGridItem.SetFocus: HResult;
begin
result := S_FALSE;
end;
procedure TAutomatedStringGridItem.SetRow(const Value: integer);
begin
FRow := Value;
end;
procedure TAutomatedStringGridItem.SetSelected(const Value: boolean);
begin
FSelected := Value;
end;
function TAutomatedStringGridItem.SetValue(val: PWideChar): HResult;
begin
result := S_OK;
self.FValue := val;
end;
procedure TAutomatedStringGridItem.SetTheValue(const Value: string);
begin
FValue := Value;
end;
function TAutomatedStringGridItem.Get_row(out pRetVal: SYSINT): HResult;
begin
pRetVal := self.Row;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_column(out pRetVal: SYSINT): HResult;
begin
pRetVal := self.Column;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_RowSpan(out pRetVal: SYSINT): HResult;
begin
pRetVal := 1;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_SelectionContainer(
out pRetVal: IRawElementProviderSimple): HResult;
begin
result := S_FALSE;
// pRetVal := FOwner as IRawElementProviderSimple;
end;
function TAutomatedStringGridItem.Get_ColumnSpan(out pRetVal: SYSINT): HResult;
begin
pRetVal := 1;
result := S_OK;
end;
function TAutomatedStringGridItem.Get_ContainingGrid(out pRetVal: IRawElementProviderSimple): HResult;
begin
// pRetVal := FOwner as IRawElementProviderSimple;
result := S_FALSE;
end;
function TAutomatedStringGridItem.Get_FragmentRoot(
out pRetVal: IRawElementProviderFragmentRoot): HResult;
begin
result := S_FALSE;
end;
function TAutomatedStringGridItem.asIRawElementProviderSimple: IRawElementProviderSimple;
begin
result := (self as IRawElementProviderSimple);
end;
end.

View File

@ -0,0 +1,17 @@
program AutomationDemo;
uses
Vcl.Forms,
DemoForm in 'DemoForm.pas' {Form2},
AutomatedCombobox in 'AutomatedCombobox.pas';
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := True;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm2, Form2);
Application.Run;
end.

View File

@ -0,0 +1,182 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{E7A33E10-330F-47C9-9B76-0BE6B3422C93}</ProjectGuid>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>AutomationDemo.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>AutomationDemo</SanitizedProjectName>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<DCC_UsePackage>madBasic_;FireDACASADriver;FireDACSqliteDriver;bindcompfmx;DBXSqliteDriver;vcldbx;FireDACPgDriver;FireDACODBCDriver;VersionInfo190;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;FireDACCommon;bindcomp;TeeDB;vclib;inetdbbde;DBXInterBaseDriver;Tee;DataSnapCommon;DocGen190;vclFireDAC;madDisAsm_;xmlrtl;svnui;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;XACompPackage190;FireDACCommonDriver;MetropolisUILiveTile;soaprtl;bindengine;vclactnband;vcldb;bindcompdbx;vcldsnap;bindcompvcl;FMXTee;TeeUI;vclie;advchartd190;fmxFireDAC;FireDACADSDriver;vcltouch;madExcept_;NMWrappers190;CustomIPTransport;vclribbon;VclSmp;FireDAC;dsnap;IndyIPServer;Intraweb;fmxase;vcl;IndyCore;VCLRESTComponents;IndyIPCommon;CloudService;CodeSiteExpressPkg;dsnapcon;FireDACIBDriver;FmxTeeUI;inet;fmxobj;FireDACMySQLDriver;vclx;inetdbxpress;svn;fmxdae;RESTComponents;bdertl;FireDACMSAccDriver;adortl;dbexpress;IndyIPClient;$(DCC_UsePackage)</DCC_UsePackage>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<DCC_UsePackage>FireDACASADriver;FireDACSqliteDriver;bindcompfmx;DBXSqliteDriver;FireDACPgDriver;FireDACODBCDriver;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;FireDACCommon;bindcomp;TeeDB;vclib;DBXInterBaseDriver;Tee;DataSnapCommon;vclFireDAC;xmlrtl;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;FireDACCommonDriver;MetropolisUILiveTile;soaprtl;bindengine;vclactnband;vcldb;bindcompdbx;vcldsnap;bindcompvcl;FMXTee;TeeUI;vclie;fmxFireDAC;FireDACADSDriver;vcltouch;CustomIPTransport;vclribbon;VclSmp;FireDAC;dsnap;IndyIPServer;Intraweb;fmxase;vcl;IndyCore;VCLRESTComponents;IndyIPCommon;CloudService;dsnapcon;FireDACIBDriver;FmxTeeUI;inet;fmxobj;FireDACMySQLDriver;vclx;inetdbxpress;fmxdae;RESTComponents;FireDACMSAccDriver;adortl;dbexpress;IndyIPClient;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<BT_BuildType>Debug</BT_BuildType>
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="DemoForm.pas">
<Form>Form2</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="AutomatedCombobox.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2057</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
<VersionInfoKeys Name="package"/>
<VersionInfoKeys Name="label"/>
<VersionInfoKeys Name="versionCode"/>
<VersionInfoKeys Name="versionName"/>
<VersionInfoKeys Name="persistent"/>
<VersionInfoKeys Name="restoreAnyVersion"/>
<VersionInfoKeys Name="installLocation"/>
<VersionInfoKeys Name="largeHeap"/>
<VersionInfoKeys Name="theme"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">AutomationDemo.dpr</Source>
</Source>
</Delphi.Personality>
<Deployment Version="4"/>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
<ActiveXProjectInfo>
<version>1</version>
</ActiveXProjectInfo>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

Binary file not shown.

View File

@ -0,0 +1,48 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{30B89B8D-5E1A-4D22-9F6D-4D7E6DFD908E}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Projects Include="AutomatedControls.dproj">
<Dependencies/>
</Projects>
<Projects Include="AutomationDemo.dproj">
<Dependencies/>
</Projects>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Default.Personality/>
</BorlandProject>
</ProjectExtensions>
<Target Name="AutomatedControls">
<MSBuild Projects="AutomatedControls.dproj"/>
</Target>
<Target Name="AutomatedControls:Clean">
<MSBuild Projects="AutomatedControls.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomatedControls:Make">
<MSBuild Projects="AutomatedControls.dproj" Targets="Make"/>
</Target>
<Target Name="AutomationDemo">
<MSBuild Projects="AutomationDemo.dproj"/>
</Target>
<Target Name="AutomationDemo:Clean">
<MSBuild Projects="AutomationDemo.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomationDemo:Make">
<MSBuild Projects="AutomationDemo.dproj" Targets="Make"/>
</Target>
<Target Name="Build">
<CallTarget Targets="AutomatedControls;AutomationDemo"/>
</Target>
<Target Name="Clean">
<CallTarget Targets="AutomatedControls:Clean;AutomationDemo:Clean"/>
</Target>
<Target Name="Make">
<CallTarget Targets="AutomatedControls:Make;AutomationDemo:Make"/>
</Target>
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
</Project>

View File

@ -0,0 +1,79 @@
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 506
ClientWidth = 684
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
DesignSize = (
684
506)
PixelsPerInch = 96
TextHeight = 13
object StringGrid1: TAutomatedStringGrid
Left = 8
Top = 8
Width = 668
Height = 369
Anchors = [akLeft, akTop, akRight, akBottom]
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goFixedRowClick]
PopupMenu = PopupMenu1
TabOrder = 0
end
object AutomatedEdit1: TAutomatedEdit
Left = 144
Top = 408
Width = 121
Height = 21
TabOrder = 1
Text = 'AutomatedEdit1'
end
object Edit1: TEdit
Left = 144
Top = 435
Width = 121
Height = 21
TabOrder = 2
Text = 'Edit1'
end
object ComboBox1: TComboBox
Left = 368
Top = 435
Width = 145
Height = 21
TabOrder = 3
Text = 'ComboBox1'
end
object AutomatedCombobox1: TAutomatedCombobox
Left = 368
Top = 408
Width = 145
Height = 21
TabOrder = 4
Text = 'AutomatedCombobox1'
end
object PopupMenu1: TPopupMenu
OnPopup = PopupMenu1Popup
Left = 384
Top = 232
object Hello1: TMenuItem
Caption = 'Hello'
end
object here1: TMenuItem
Caption = 'There'
end
object Everyyone1: TMenuItem
Caption = 'Everyone'
end
object item1: TMenuItem
Caption = '<item>'
end
end
end

View File

@ -0,0 +1,75 @@
unit DemoForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ComCtrls,
Vcl.DBGrids, Vcl.DBCGrids, Vcl.Menus, Vcl.StdCtrls,
Vcl.Buttons, AutomatedStringGrid, AutomatedEdit, AutomatedCombobox;
type
TForm2 = class(TForm)
StringGrid1: TAutomatedStringGrid;
PopupMenu1: TPopupMenu;
Hello1: TMenuItem;
here1: TMenuItem;
Everyyone1: TMenuItem;
item1: TMenuItem;
AutomatedEdit1: TAutomatedEdit;
Edit1: TEdit;
ComboBox1: TComboBox;
AutomatedCombobox1: TAutomatedCombobox;
procedure FormCreate(Sender: TObject);
procedure StringGrid1DblClick(Sender: TObject);
procedure PopupMenu1Popup(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
begin
StringGrid1.ColCount := 10;
StringGrid1.RowCount := 6;
// StringGrid1.Cells[0, 0] := 'Top Left';
//StringGrid1.cell
StringGrid1.Cells[1, 0] := 'First';
StringGrid1.Cells[2, 0] := 'Second';
StringGrid1.Cells[3, 0] := 'Third';
StringGrid1.Cells[4, 0] := 'Forth';
StringGrid1.Cells[5, 0] := '5th';
StringGrid1.Cells[6, 0] := 'Thith';
StringGrid1.Cells[7, 0] := '7th';
StringGrid1.Cells[8, 0] := '8th';
StringGrid1.Cells[9, 0] := 'Last';
StringGrid1.Cells[1, 1] := 'Hello11';
StringGrid1.Cells[1, 3] := 'Hello13';
StringGrid1.Cells[3, 3] := 'Hello33';
StringGrid1.Cells[3, 4] := 'Hello34';
StringGrid1.Cells[2, 4] := 'Hello24';
StringGrid1.Cells[2, 9] := 'Hello29';
end;
procedure TForm2.PopupMenu1Popup(Sender: TObject);
begin
item1.caption := 'Cell : ' + IntToStr(StringGrid1.Row) + IntToStr(StringGrid1.Col);
end;
procedure TForm2.StringGrid1DblClick(Sender: TObject);
begin
ShowMessage(StringGrid1.Cells[StringGrid1.Row, StringGrid1.Col]);
end;
end.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
program AutomationDemo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
generics.collections,
System.SysUtils,
System.Types,
DelphiUIAutomation.Automation in '..\source\DelphiUIAutomation.Automation.pas',
DelphiUIAutomation.Base in '..\source\DelphiUIAutomation.Base.pas',
DelphiUIAutomation.Client in '..\source\DelphiUIAutomation.Client.pas',
DelphiUIAutomation.Clipboard in '..\source\DelphiUIAutomation.Clipboard.pas',
DelphiUIAutomation.Exception in '..\source\DelphiUIAutomation.Exception.pas',
DelphiUIAutomation.Keyboard in '..\source\DelphiUIAutomation.Keyboard.pas',
DelphiUIAutomation.Mouse in '..\source\DelphiUIAutomation.Mouse.pas',
DelphiUIAutomation.Processes in '..\source\DelphiUIAutomation.Processes.pas',
DelphiUIAutomation.ScreenShot in '..\source\DelphiUIAutomation.ScreenShot.pas',
DelphiUIAutomation.Utils in '..\source\DelphiUIAutomation.Utils.pas',
UIAutomationClient_TLB in '..\source\UIAutomationClient_TLB.pas',
DelphiUIAutomation.AndCondition in '..\source\Conditions\DelphiUIAutomation.AndCondition.pas',
DelphiUIAutomation.Condition in '..\source\Conditions\DelphiUIAutomation.Condition.pas',
DelphiUIAutomation.ControlTypeCondition in '..\source\Conditions\DelphiUIAutomation.ControlTypeCondition.pas',
DelphiUIAutomation.FalseCondition in '..\source\Conditions\DelphiUIAutomation.FalseCondition.pas',
DelphiUIAutomation.NameCondition in '..\source\Conditions\DelphiUIAutomation.NameCondition.pas',
DelphiUIAutomation.OrCondition in '..\source\Conditions\DelphiUIAutomation.OrCondition.pas',
DelphiUIAutomation.TrueCondition in '..\source\Conditions\DelphiUIAutomation.TrueCondition.pas',
DelphiUIAutomation.Button in '..\source\Controls\DelphiUIAutomation.Button.pas',
DelphiUIAutomation.Checkbox in '..\source\Controls\DelphiUIAutomation.Checkbox.pas',
DelphiUIAutomation.ComboBox in '..\source\Controls\DelphiUIAutomation.ComboBox.pas',
DelphiUIAutomation.Container.Intf in '..\source\controls\DelphiUIAutomation.Container.Intf.pas',
DelphiUIAutomation.Container in '..\source\Controls\DelphiUIAutomation.Container.pas',
DelphiUIAutomation.Desktop in '..\source\controls\DelphiUIAutomation.Desktop.pas',
DelphiUIAutomation.EditBox in '..\source\Controls\DelphiUIAutomation.EditBox.pas',
DelphiUIAutomation.Hyperlink in '..\source\Controls\DelphiUIAutomation.Hyperlink.pas',
DelphiUIAutomation.ListItem in '..\source\Controls\DelphiUIAutomation.ListItem.pas',
DelphiUIAutomation.Panel.Intf in '..\source\Controls\DelphiUIAutomation.Panel.Intf.pas',
DelphiUIAutomation.Panel in '..\source\Controls\DelphiUIAutomation.Panel.pas',
DelphiUIAutomation.RadioButton in '..\source\Controls\DelphiUIAutomation.RadioButton.pas',
DelphiUIAutomation.Statusbar in '..\source\Controls\DelphiUIAutomation.Statusbar.pas',
DelphiUIAutomation.StringGrid in '..\source\Controls\DelphiUIAutomation.StringGrid.pas',
DelphiUIAutomation.StringGridItem in '..\source\Controls\DelphiUIAutomation.StringGridItem.pas',
DelphiUIAutomation.Tab.Intf in '..\source\Controls\DelphiUIAutomation.Tab.Intf.pas',
DelphiUIAutomation.Tab in '..\source\Controls\DelphiUIAutomation.Tab.pas',
DelphiUIAutomation.TabItem in '..\source\Controls\DelphiUIAutomation.TabItem.pas',
DelphiUIAutomation.TextBox in '..\source\Controls\DelphiUIAutomation.TextBox.pas',
DelphiUIAutomation.ControlTypeIDs in '..\source\Ids\DelphiUIAutomation.ControlTypeIDs.pas',
DelphiUIAutomation.PatternIDs in '..\source\Ids\DelphiUIAutomation.PatternIDs.pas',
DelphiUIAutomation.PropertyIDs in '..\source\Ids\DelphiUIAutomation.PropertyIDs.pas',
DelphiUIAutomation.Menu in '..\source\Controls\Menus\DelphiUIAutomation.Menu.pas',
DelphiUIAutomation.MenuItem in '..\source\Controls\Menus\DelphiUIAutomation.MenuItem.pas',
DelphiUIAutomation.Window in '..\source\Controls\DelphiUIAutomation.Window.pas',
DelphiUIAutomation.TreeView in '..\source\Controls\DelphiUIAutomation.TreeView.pas';
var
application: IAutomationApplication;
enquiry : IAutomationWindow;
tb1, tb2 : IAutomationEditBox;
eb0: IAutomationTextBox;
Tab: IAutomationTab;
Statusbar: IAutomationStatusBar;
check: IAutomationCheckBox;
radio: IAutomationRadioButton;
// eb2 : IAutomationEditBox;
cb1: IAutomationCombobox;
cb2: IAutomationCombobox;
tv1: IAutomationTreeView;
tvi: IAutomationTreeViewItem;
exit1: IAutomationMenuItem;
menu: IAutomationMenu;
begin
ReportMemoryLeaksOnShutdown := DebugHook <> 0;
TUIAuto.CreateUIAuto;
// First launch the application
application := TAutomationApplication.LaunchOrAttach
('C:\taskToCSG\EM.Lib\DelphiUIAutomation\demo\democlient\Win32\Debug\Project1.exe', '');
application.WaitWhileBusy;
// Now wait for a very long time for the enquiry screen to come up
enquiry := TAutomationDesktop.GetDesktopWindow('Form1');
enquiry.Focus;
// Select the correct tab
Tab := enquiry.GetTabByIndex(0);
Tab.SelectTabPage('Second Tab'); // 3 is the magic number
tb1 := Tab.GetEditBoxByIndex(0);
writeln(tb1.Text);
tb2 := enquiry.GetEditBoxByName('AutomatedEdit1');
writeln(tb2.Text);
check := enquiry.GetCheckboxByIndex(0);
check.toggle;
radio := enquiry.GetRadioButtonByIndex(2);
radio.Select;
// Now see whether we can get the statusbar
Statusbar := enquiry.Statusbar;
eb0 := Statusbar.GetTextBoxByIndex(1);
writeln('Text is ' + eb0.Text);
// Now get and set the text in an editbox, by name
cb1 := enquiry.GetComboboxByName('AutomatedCombobox1');
writeln('Combo text is ' + cb1.Text);
cb1.Text := 'Replacements';
cb1 := enquiry.GetComboboxByName('AutomatedCombobox1');
writeln('Combo text is ' + cb1.Text);
cb2 := enquiry.GetComboboxByName('AutomatedCombobox2');
writeln('Combo2 text is ' + cb2.Text);
cb2.Text := 'First';
cb2 := enquiry.GetComboboxByName('AutomatedCombobox2');
writeln('Combo2 text is ' + cb2.Text);
cb2.Text := 'No there';
cb2 := enquiry.GetComboboxByName('AutomatedCombobox2');
writeln('Combo2 text is ' + cb2.Text);
cb2.Text := 'Third';
cb2 := enquiry.GetComboboxByName('AutomatedCombobox2');
writeln('Combo2 text is ' + cb2.Text);
// Now try and get stuff from TreeView
tv1 := enquiry.getTreeViewByIndex(0);
tvi := tv1.GetItem('Sub-SubItem');
tvi.select;
menu := enquiry.GetMainMenu;
exit1 := menu.MenuItem('File|Exit');
if assigned(exit1) then
exit1.Click;
WriteLn('Press key to exit');
ReadLn;
application.Kill;
end.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,50 @@
[ExpressSkins]
Default=1
ShowNotifications=1
Enabled=1
dxSkinBlack=1
dxSkinBlue=1
dxSkinBlueprint=1
dxSkinCaramel=1
dxSkinCoffee=1
dxSkinDarkRoom=1
dxSkinDarkSide=1
dxSkinDevExpressDarkStyle=1
dxSkinDevExpressStyle=1
dxSkinFoggy=1
dxSkinGlassOceans=1
dxSkinHighContrast=1
dxSkiniMaginary=1
dxSkinLilian=1
dxSkinLiquidSky=1
dxSkinLondonLiquidSky=1
dxSkinMcSkin=1
dxSkinMetropolis=1
dxSkinMetropolisDark=1
dxSkinMoneyTwins=1
dxSkinOffice2007Black=1
dxSkinOffice2007Blue=1
dxSkinOffice2007Green=1
dxSkinOffice2007Pink=1
dxSkinOffice2007Silver=1
dxSkinOffice2010Black=1
dxSkinOffice2010Blue=1
dxSkinOffice2010Silver=1
dxSkinOffice2013DarkGray=1
dxSkinOffice2013LightGray=1
dxSkinOffice2013White=1
dxSkinPumpkin=1
dxSkinSeven=1
dxSkinSevenClassic=1
dxSkinSharp=1
dxSkinSharpPlus=1
dxSkinSilver=1
dxSkinSpringTime=1
dxSkinStardust=1
dxSkinSummer2008=1
dxSkinTheAsphaltWorld=1
dxSkinsDefaultPainters=1
dxSkinValentine=1
dxSkinVS2010=1
dxSkinWhiteprint=1
dxSkinXmas2008Blue=1

View File

@ -0,0 +1,149 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
program AutomationLibraryDemo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
generics.collections,
System.SysUtils,
System.Types,
dialogs,
UIAutoWrapper in 'UIAutoWrapper.pas';
var
wrapper: TUIAutoWrapper;
window: Pointer;
popup: Pointer;
tab: Pointer;
tb1, tb2 : Pointer;
check: Pointer;
cb1, cb2: Pointer;
grid: Pointer;
cellValue : String;
begin
WriteLn('Creating wrapper');
wrapper := TUIAutoWrapper.create;
WriteLn('Created wrapper');
// WriteLn('Press key to continue');
// ReadLn;
try
ReportMemoryLeaksOnShutdown := DebugHook <> 0;
// Should do something here
wrapper.Launch('C:\taskToCSG\EM.Lib\DelphiUIAutomation\demo\democlient\Win32\Debug\Project1.exe', '');
wrapper.Initialize;
wrapper.WaitWhileBusy;
// Now wait for a very long time for the enquiry screen to come up
window := wrapper.GetDesktopWindow('Form1');
wrapper.Focus(window);
wrapper.Maximize(window);
tab := wrapper.GetTab(window, 0);
wrapper.SelectTab(tab, 'Second Tab');
tb1 := wrapper.GetEditBox(tab, 0);
writeLn(wrapper.GetText(tb1));
// tb2 := wrapper.GetEditBox(window, 'AutomatedEdit1');
// writeLn(wrapper.GetText(tb2));
check := wrapper.GetCheckBox(window, 0);
wrapper.Toggle(check);
wrapper.SelectRadioButton(window, 2);
writeln('Getting status bar, etc.');
// Now see whether we can get the statusbar and associated text
writeln('Text is ' + wrapper.GetStatusBarText(window, 1));
writeln('Getting Combobox');
cb1 := wrapper.GetComboBox(window, 'AutomatedCombobox1');
writeln('Got combobox');
writeLn(wrapper.GetText(cb1));
wrapper.SetText(cb1, 'Helloo');
writeLn('Value is now - ' + wrapper.GetText(cb1));
cb2 := wrapper.GetComboBox(window, 'AutomatedCombobox2');
writeln('Combo2 text is ' + wrapper.GetText(cb2));
wrapper.SetText(cb2, 'First');
cb2 := wrapper.GetComboBox(window, 'AutomatedCombobox2');
writeln('Combo2 text is ' + wrapper.GetText(cb2));
wrapper.SetText(cb2, 'No there');
cb2 := wrapper.GetComboBox(window, 'AutomatedCombobox2');
writeln('Combo2 text is ' + wrapper.GetText(cb2));
wrapper.SetText(cb2, 'Third');
cb2 := wrapper.GetComboBox(window, 'AutomatedCombobox2');
writeln('Combo2 text is ' + wrapper.GetText(cb2));
// Now try and get stuff to a TreeView
wrapper.SelectTreeViewItem (window, 0, 'Sub-SubItem');
wrapper.ClickMenu(window, 'File|Exit');
// Now look for the popup
writeln('Finding Window');
popup := wrapper.GetWindow(window, 'Project1');
writeln('Found Window');
wrapper.ClickButton(popup, 'OK');
writeln('clicked button');
writeln('Data grid');
// Get window again
window := wrapper.GetDesktopWindow('Form1');
grid := wrapper.GetDataGrid(window, 0);
writeln('Got datagrid');
cellValue := wrapper.GetCellValue(grid, 3,3);
writeln('Value is = "' + cellValue + '"');
WriteLn('Press key to continue');
ReadLn;
finally
WriteLn('About to kill');
wrapper.Kill;
WriteLn('Killed');
wrapper.Finalize;
wrapper.free;
end;
end.

View File

@ -0,0 +1,940 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{8E50F74F-7F89-4312-9A18-700B93DB67AC}</ProjectGuid>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>AutomationLibraryDemo.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<SanitizedProjectName>AutomationLibraryDemo</SanitizedProjectName>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<DCC_UsePackage>FireDACASADriver;FireDACSqliteDriver;bindcompfmx;DBXSqliteDriver;FireDACPgDriver;FireDACODBCDriver;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;FireDACCommon;bindcomp;DBXInterBaseDriver;DataSnapCommon;xmlrtl;ibxpress;DbxCommonDriver;IndyProtocols;dbxcds;DBXMySQLDriver;FireDACCommonDriver;soaprtl;bindengine;bindcompdbx;FMXTee;fmxFireDAC;FireDACADSDriver;CustomIPTransport;FireDAC;dsnap;IndyIPServer;fmxase;IndyCore;IndyIPCommon;CloudService;FireDACIBDriver;FmxTeeUI;inet;fmxobj;FireDACMySQLDriver;inetdbxpress;fmxdae;RESTComponents;FireDACMSAccDriver;dbexpress;IndyIPClient;$(DCC_UsePackage);$(DCC_UsePackage)</DCC_UsePackage>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
<DCC_UsePackage>madBasic_;FireDACASADriver;FireDACSqliteDriver;bindcompfmx;DBXSqliteDriver;vcldbx;FireDACPgDriver;FireDACODBCDriver;VersionInfo190;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;FireDACCommon;bindcomp;TeeDB;vclib;inetdbbde;DBXInterBaseDriver;Tee;DataSnapCommon;DocGen190;vclFireDAC;madDisAsm_;xmlrtl;svnui;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;XACompPackage190;FireDACCommonDriver;MetropolisUILiveTile;soaprtl;bindengine;vclactnband;vcldb;bindcompdbx;vcldsnap;bindcompvcl;FMXTee;TeeUI;vclie;advchartd190;fmxFireDAC;FireDACADSDriver;vcltouch;madExcept_;NMWrappers190;CustomIPTransport;vclribbon;VclSmp;FireDAC;dsnap;IndyIPServer;Intraweb;fmxase;vcl;IndyCore;VCLRESTComponents;IndyIPCommon;CloudService;CodeSiteExpressPkg;dsnapcon;FireDACIBDriver;FmxTeeUI;inet;fmxobj;FireDACMySQLDriver;vclx;inetdbxpress;svn;fmxdae;RESTComponents;bdertl;FireDACMSAccDriver;adortl;dbexpress;IndyIPClient;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>FireDACASADriver;FireDACSqliteDriver;bindcompfmx;DBXSqliteDriver;FireDACPgDriver;FireDACODBCDriver;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;FireDACCommon;bindcomp;TeeDB;vclib;DBXInterBaseDriver;Tee;DataSnapCommon;vclFireDAC;xmlrtl;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;FireDACCommonDriver;MetropolisUILiveTile;soaprtl;bindengine;vclactnband;vcldb;bindcompdbx;vcldsnap;bindcompvcl;FMXTee;TeeUI;vclie;fmxFireDAC;FireDACADSDriver;vcltouch;CustomIPTransport;vclribbon;VclSmp;FireDAC;dsnap;IndyIPServer;Intraweb;fmxase;vcl;IndyCore;VCLRESTComponents;IndyIPCommon;CloudService;dsnapcon;FireDACIBDriver;FmxTeeUI;inet;fmxobj;FireDACMySQLDriver;vclx;inetdbxpress;fmxdae;RESTComponents;FireDACMSAccDriver;adortl;dbexpress;IndyIPClient;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Define>WIN64;$(DCC_Define)</DCC_Define>
<Manifest_File>(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_UNIT_PLATFORM>false</DCC_UNIT_PLATFORM>
<DCC_SYMBOL_PLATFORM>false</DCC_SYMBOL_PLATFORM>
<DCC_DebugInformation>true</DCC_DebugInformation>
<DCC_MapFile>3</DCC_MapFile>
<DCC_Define>INVESTIGATION;$(DCC_Define)</DCC_Define>
<Manifest_File>None</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="UIAutoWrapper.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2057</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
<VersionInfoKeys Name="package"/>
<VersionInfoKeys Name="label"/>
<VersionInfoKeys Name="versionCode"/>
<VersionInfoKeys Name="versionName"/>
<VersionInfoKeys Name="persistent"/>
<VersionInfoKeys Name="restoreAnyVersion"/>
<VersionInfoKeys Name="installLocation"/>
<VersionInfoKeys Name="largeHeap"/>
<VersionInfoKeys Name="theme"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">AutomationLibraryDemo.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="4">
<DeployFile LocalName="Win32\Debug\AutomationLibraryDemo.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
<UnitTesting>
<TestProjectName>C:\Users\humphreysm.JHCLLP\Documents\Embarcadero\Studio\Projects\DUIA\demo\Test\AutomationDemoTests.dproj</TestProjectName>
</UnitTesting>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,96 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{1E70C34A-A56D-4FBC-BA5E-081EEF70B3C2}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Projects Include="..\controls\AutomatedControls.dproj">
<Dependencies/>
</Projects>
<Projects Include="democlient\Project1.dproj">
<Dependencies/>
</Projects>
<Projects Include="..\library\UIAutomation.dproj">
<Dependencies/>
</Projects>
<Projects Include="AutomationDemo.dproj">
<Dependencies/>
</Projects>
<Projects Include="..\tests\AutomationTests.dproj">
<Dependencies/>
</Projects>
<Projects Include="AutomationLibraryDemo.dproj">
<Dependencies/>
</Projects>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Default.Personality/>
</BorlandProject>
</ProjectExtensions>
<Target Name="AutomatedControls">
<MSBuild Projects="..\controls\AutomatedControls.dproj"/>
</Target>
<Target Name="AutomatedControls:Clean">
<MSBuild Projects="..\controls\AutomatedControls.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomatedControls:Make">
<MSBuild Projects="..\controls\AutomatedControls.dproj" Targets="Make"/>
</Target>
<Target Name="Project1">
<MSBuild Projects="democlient\Project1.dproj"/>
</Target>
<Target Name="Project1:Clean">
<MSBuild Projects="democlient\Project1.dproj" Targets="Clean"/>
</Target>
<Target Name="Project1:Make">
<MSBuild Projects="democlient\Project1.dproj" Targets="Make"/>
</Target>
<Target Name="UIAutomation">
<MSBuild Projects="..\library\UIAutomation.dproj"/>
</Target>
<Target Name="UIAutomation:Clean">
<MSBuild Projects="..\library\UIAutomation.dproj" Targets="Clean"/>
</Target>
<Target Name="UIAutomation:Make">
<MSBuild Projects="..\library\UIAutomation.dproj" Targets="Make"/>
</Target>
<Target Name="AutomationDemo">
<MSBuild Projects="AutomationDemo.dproj"/>
</Target>
<Target Name="AutomationDemo:Clean">
<MSBuild Projects="AutomationDemo.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomationDemo:Make">
<MSBuild Projects="AutomationDemo.dproj" Targets="Make"/>
</Target>
<Target Name="AutomationTests">
<MSBuild Projects="..\tests\AutomationTests.dproj"/>
</Target>
<Target Name="AutomationTests:Clean">
<MSBuild Projects="..\tests\AutomationTests.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomationTests:Make">
<MSBuild Projects="..\tests\AutomationTests.dproj" Targets="Make"/>
</Target>
<Target Name="AutomationLibraryDemo">
<MSBuild Projects="AutomationLibraryDemo.dproj"/>
</Target>
<Target Name="AutomationLibraryDemo:Clean">
<MSBuild Projects="AutomationLibraryDemo.dproj" Targets="Clean"/>
</Target>
<Target Name="AutomationLibraryDemo:Make">
<MSBuild Projects="AutomationLibraryDemo.dproj" Targets="Make"/>
</Target>
<Target Name="Build">
<CallTarget Targets="AutomatedControls;Project1;UIAutomation;AutomationDemo;AutomationTests;AutomationLibraryDemo"/>
</Target>
<Target Name="Clean">
<CallTarget Targets="AutomatedControls:Clean;Project1:Clean;UIAutomation:Clean;AutomationDemo:Clean;AutomationTests:Clean;AutomationLibraryDemo:Clean"/>
</Target>
<Target Name="Make">
<CallTarget Targets="AutomatedControls:Make;Project1:Make;UIAutomation:Make;AutomationDemo:Make;AutomationTests:Make;AutomationLibraryDemo:Make"/>
</Target>
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
</Project>

Binary file not shown.

View File

@ -0,0 +1,431 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit UIAutoWrapper;
interface
const
{$IFDEF WIN64}
DLL_UIAUTO = 'UIAutomation64.dll';
{$ELSE}
DLL_UIAUTO = 'UIAutomation.dll';
{$ENDIF}
type
// TODO: Better names for these types please
TSimpleFunc = procedure; stdcall;
TLaunchFunc = procedure (const val1, val2: String);
TStringFunc = function (const value: String): Pointer;
TPointerFunc = procedure (handle: Pointer);
TSelectTabFunc = procedure (handle: Pointer; text: String);
TGetTabFunc = function (handle: Pointer; value: Integer): Pointer;
TGetEditBoxByNameFunc = function (handle: Pointer; text: String): Pointer;
TGetTextFunc = function (handle: Pointer): String;
TToggleFunc = procedure (handle: Pointer);
TGetStatusBarFunc = function (handle: Pointer): Pointer;
TSetTextFunc = procedure (handle: Pointer; text: String);
TGetMenuItemFunc = function (parent: Pointer; handle: Pointer; text: String): Pointer;
TGetStatusbarTextFunc = function (handle: Pointer; value: Integer): String;
TClickFunc = procedure(handle: Pointer; text: String);
TSelectTreeViewItemFunc = procedure (handle: Pointer; item: Integer; text: String);
TRadioButtonSelectFunc = procedure (handle: Pointer; item: Integer);
TGetGridFunc = function (parent: Pointer; item: Integer) : Pointer;
TGetCellValueFunc = function (parent: Pointer; x, y: Integer): String;
TUIAutoWrapper = class
private
dllHandle : THandle;
launchOrAttachFunc: TLaunchFunc;
killFunc: TSimpleFunc;
initializeFunc: TSimpleFunc;
finalizeFunc: TSimpleFunc;
waitWhileBusyFunc: TSimpleFunc;
getDesktopWindowFunc: TStringFunc;
getWindowFunc: TGetEditBoxByNameFunc;
maximizeFunc: TPointerFunc;
selectTabFunc: TSelectTabFunc;
getTabFunc: TGetTabFunc;
getCheckBoxFunc: TGetTabFunc;
getEditBoxFunc: TGetTabFunc;
getTextBoxFunc: TGetTabFunc;
getEditBoxByNameFunc: TGetEditBoxByNameFunc;
getTextFunc: TGetTextFunc;
getTextFromTextFunc: TGetTextFunc;
toggleFunc: TToggleFunc;
getStatusbarTextFunc: TGetStatusbarTextFunc;
getComboBoxByNameFunc: TGetEditBoxByNameFunc;
getComboBoxFunc: TGetTabFunc;
setTextFunc: TSetTextFunc;
selectTreeViewItemFunc: TSelectTreeViewItemFunc;
selectRadioButtonFunc: TRadioButtonSelectFunc;
clickMenuItemFunc : TClickFunc;
clickButtonFunc : TClickFunc;
getGridFunc: TGetGridFunc;
getCellValueFunc : TGetCellValueFunc;
public
constructor Create(sDllPath: String = '');
destructor Destroy; override;
procedure Launch(const val1, val2: String);
procedure Kill;
procedure Initialize;
procedure Finalize;
procedure WaitWhileBusy;
function GetDesktopWindow(const name: String) : Pointer;
function GetWindow(parent: Pointer; const name: String) : Pointer;
procedure Maximize(handle: Pointer);
procedure Focus(handle: Pointer);
procedure SelectTab(handle: Pointer; text: String);
function GetTab(handle: Pointer; item: integer): Pointer;
function GetEditBox(handle: Pointer; item: Integer): pointer; overload;
function GetEditBox(handle: Pointer; name: String): pointer; overload;
function GetTextBox(handle: Pointer; item: Integer): pointer;
function GetText(handle: Pointer): String;
function GetTextFromText(handle: Pointer): String;
function GetCheckBox(handle: Pointer; index: Integer): Pointer;
procedure Toggle(handle: Pointer);
function GetStatusbarText(handle: Pointer; item: Integer): String;
function GetComboBox(handle: Pointer; item: Integer): Pointer; overload;
function GetComboBox(handle: Pointer; name: String): Pointer; overload;
procedure SetText(handle: Pointer; text: String);
procedure SelectTreeViewItem(parent: Pointer; item: Integer; name: String);
procedure ClickMenu(parent: Pointer; value: String);
procedure SelectRadioButton(handle: Pointer; index: Integer);
procedure ClickButton(parent: Pointer; name: String);
function GetDataGrid(parent: Pointer; item: Integer): Pointer;
function GetCellValue(parent: Pointer; x, y: Integer): String;
end;
implementation
uses
dialogs,
windows, Tocsg.Path;
{ TUIAutoWrapper }
procedure TUIAutoWrapper.ClickMenu(parent: Pointer; value: String);
begin
writeln('About to click on ' + value);
self.clickMenuItemFunc(parent, value);
writeln('Clicked ' + value);
end;
constructor TUIAutoWrapper.Create(sDllPath: String = '');
begin
WriteLn('Loading DLL');
if sDllPath = '' then
sDllPath := GetRunExePathDir + DLL_UIAUTO;
dllHandle := LoadLibrary(PChar(sDllPath));
WriteLn('Loaded DLL');
if dllHandle <> 0 then
begin
@launchOrAttachFunc := getProcAddress(dllHandle, 'LaunchOrAttach');
if not Assigned (launchOrAttachFunc) then
WriteLn('"LaunchOrAttach" function not found') ;
@killFunc := getProcAddress(dllHandle, 'Kill');
if not Assigned (killFunc) then
WriteLn('"Kill" function not found') ;
@clickMenuItemFunc := getProcAddress(dllHandle, 'ClickMenuItem');
if not Assigned (clickMenuItemFunc) then
WriteLn('"ClickMenuItem" function not found') ;
@initializeFunc := getProcAddress(dllHandle, 'Initialize');
if not Assigned (initializeFunc) then
WriteLn('"Initialise" function not found') ;
@finalizeFunc := getProcAddress(dllHandle, 'Finalize');
if not Assigned (finalizeFunc) then
WriteLn('"Finalize" function not found') ;
@waitWhileBusyFunc := getProcAddress(dllHandle, 'WaitWhileBusy');
if not Assigned (waitWhileBusyFunc) then
WriteLn('"WaitWhileBusy" function not found');
@getDesktopWindowFunc := getProcAddress(dllHandle, 'GetDesktopWindow');
if not Assigned (getDesktopWindowFunc) then
WriteLn('"GetDesktopWindow" function not found');
@selectTabFunc := getProcAddress(dllHandle, 'SelectTab');
if not Assigned (selectTabFunc) then
WriteLn('"SelectTab" function not found');
@getTabFunc := getProcAddress(dllHandle, 'GetTab');
if not Assigned (getTabFunc) then
WriteLn('"GetTab" function not found');
@maximizeFunc := getProcAddress(dllHandle, 'Maximize');
if not Assigned (maximizeFunc) then
WriteLn('"Maximize" function not found');
@getEditBoxByNameFunc := getProcAddress(dllHandle, 'GetEditBoxByName');
if not Assigned (getEditBoxByNameFunc) then
WriteLn('"GetEditBoxByName" function not found');
@getEditBoxFunc := getProcAddress(dllHandle, 'GetEditBox');
if not Assigned (getEditBoxFunc) then
WriteLn('"GetEditBox" function not found');
@getTextFunc := getProcAddress(dllHandle, 'GetText');
if not Assigned (getTextFunc) then
WriteLn('"GetText" function not found');
@getCheckBoxFunc := getProcAddress(dllHandle, 'GetCheckBox');
if not Assigned (getCheckBoxFunc) then
WriteLn('"GetCheckBox" function not found');
@toggleFunc := getProcAddress(dllHandle, 'Toggle');
if not Assigned (toggleFunc) then
WriteLn('"Toggle" function not found');
@getStatusbarTextFunc := getProcAddress(dllHandle, 'GetStatusBarText');
if not Assigned (getStatusbarTextFunc) then
WriteLn('"GetStatusBarText" function not found');
@getTextBoxFunc := getProcAddress(dllHandle, 'GetTextBox');
if not Assigned (getTextBoxFunc) then
WriteLn('"GetTextBox" function not found');
@getTextFromTextFunc := getProcAddress(dllHandle, 'GetTextFromText');
if not Assigned (getTextFromTextFunc) then
WriteLn('"GetTextFromText" function not found');
@getComboBoxByNameFunc := getProcAddress(dllHandle, 'GetComboBoxByName');
if not Assigned (getComboBoxByNameFunc) then
WriteLn('"GetComboBoxByName" function not found');
@getComboBoxFunc := getProcAddress(dllHandle, 'GetComboBox');
if not Assigned (getComboBoxFunc) then
WriteLn('"GetComboBox" function not found');
@setTextFunc := getProcAddress(dllHandle, 'SetText');
if not Assigned (setTextFunc) then
WriteLn('"SetText" function not found');
@selectTreeViewItemFunc := getProcAddress(dllHandle, 'SelectTreeViewItem');
if not Assigned (selectTreeViewItemFunc) then
WriteLn('"SelectTreeViewItem" function not found');
@selectRadioButtonFunc := getProcAddress(dllHandle, 'SelectRadioButton');
if not Assigned (selectRadioButtonFunc) then
WriteLn('"SelectRadioButton" function not found');
@clickButtonFunc := getProcAddress(dllHandle, 'ClickButton');
if not Assigned (clickButtonFunc) then
WriteLn('"ClickButton" function not found');
@getWindowFunc := getProcAddress(dllHandle, 'GetWindow');
if not Assigned (getWindowFunc) then
WriteLn('"GetWindow" function not found');
@getGridFunc := getProcAddress(dllHandle, 'GetGrid');
if not Assigned (getGridFunc) then
WriteLn('"GetGrid" function not found');
@getCellValueFunc := getProcAddress(dllHandle, 'GetCellValue');
if not Assigned (getCellValueFunc) then
WriteLn('"GetCellValue" function not found');
end
else
begin
WriteLn('Dll not found') ;
Exit;
end;
end;
destructor TUIAutoWrapper.Destroy;
begin
FreeLibrary(dllHandle);
inherited Destroy;
end;
procedure TUIAutoWrapper.Finalize;
begin
self.FinalizeFunc;
end;
procedure TUIAutoWrapper.Initialize;
begin
self.InitializeFunc;
end;
procedure TUIAutoWrapper.WaitWhileBusy;
begin
self.waitWhileBusyFunc;
end;
function TUIAutoWrapper.GetDesktopWindow(const name: String) : Pointer;
begin
result := self.getDesktopWindowFunc(name);
end;
procedure TUIAutoWrapper.ClickButton(parent: Pointer; name: String);
begin
self.clickButtonFunc(parent, name);
end;
//wrapper.GetDataGrid(window, 0, 'TAutomationStringGrid');
function TUIAutoWrapper.GetDataGrid(parent: Pointer; item: Integer) : Pointer;
begin
result := self.getGridFunc(parent, item);
end;
function TUIautoWrapper.GetCellValue(parent: Pointer; x,y : Integer) : String;
begin
result := self.getCellValueFunc(parent, x, y);
end;
procedure TUIAutoWrapper.Focus (handle: Pointer);
begin
// Nothing yet.
end;
procedure TUIAutoWrapper.Kill;
begin
self.KillFunc;
end;
procedure TUIautoWrapper.maximize(handle: Pointer);
begin
self.maximizeFunc (handle);
end;
function TUIAutoWrapper.getTab(handle: Pointer; item: Integer): Pointer;
begin
result := self.GetTabFunc(handle, item);
end;
function TUIAutoWrapper.GetEditBox(handle: Pointer; item: Integer): pointer;
begin
result := self.getEditBoxFunc(handle, item);
end;
function TUIAutoWrapper.GetTextBox(handle: Pointer; item: Integer): pointer;
begin
result := self.getTextBoxFunc(handle, item);
end;
function TUIAutoWrapper.GetTextFromText(handle: Pointer): String;
begin
result := self.getTextFromTextFunc(handle);
end;
function TUIAutoWrapper.GetWindow(parent: Pointer; const name: String): Pointer;
begin
result := self.getWindowFunc(parent, name);
end;
function TUIAutoWrapper.GetText(handle: Pointer): String;
begin
result := self.getTextFunc(handle);
end;
function TUIAutoWrapper.GetCheckBox(handle: Pointer; index: Integer): Pointer;
begin
result := self.getCheckBoxFunc(handle, index);
end;
procedure TUIAutoWrapper.SelectRadioButton(handle: Pointer; index: Integer);
begin
self.selectRadioButtonFunc(handle, index);
end;
function TUIAutoWrapper.GetComboBox(handle: Pointer; name: String): Pointer;
begin
result := self.getComboBoxByNameFunc(handle, name);
end;
function TUIAutoWrapper.GetComboBox(handle: Pointer; item: Integer): Pointer;
begin
result := self.getComboBoxFunc(handle, item);
end;
function TUIAutoWrapper.GetStatusBarText(handle: Pointer; item: Integer): String;
begin
result := self.GetStatusBarTextFunc(handle, item);
end;
function TUIAutoWrapper.GetEditBox(handle: Pointer; name: String): pointer;
begin
result := self.getEditBoxByNameFunc(handle, name);
end;
procedure TUIAutoWrapper.SelectTab(handle: Pointer; text: String);
begin
self.SelectTabFunc(handle, text);
end;
procedure TUIAutoWrapper.SelectTreeViewItem(parent: Pointer; item: Integer;
name: String);
begin
self.selectTreeViewItemFunc(parent, item, name);
end;
procedure TUIAutoWrapper.SetText(handle: Pointer; text: String);
begin
self.setTextFunc(handle, text);
end;
procedure TUIAutoWrapper.Toggle(handle: Pointer);
begin
self.ToggleFunc(handle);
end;
procedure TUIAutoWrapper.Launch(const val1, val2: String);
begin
self.launchOrAttachFunc(val1, val2);
end;
end.

View File

@ -0,0 +1,42 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
AutomatedCombobox in '..\..\controls\AutomatedCombobox.pas',
UIAutomationCore_TLB in '..\..\controls\UIAutomationCore_TLB.pas',
AutomatedStringGrid in '..\..\controls\AutomatedStringGrid.pas',
AutomatedEdit in '..\..\controls\AutomatedEdit.pas',
AutomatedMaskEdit in '..\..\controls\AutomatedMaskEdit.pas',
AutomatedStaticText in '..\..\controls\AutomatedStaticText.pas',
DelphiUIAutomation.StringGridItem in '..\..\source\Controls\DelphiUIAutomation.StringGridItem.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,171 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.Menus,
AutomatedCombobox, AutomatedEdit, Vcl.Grids, AutomatedStringGrid, Vcl.Mask,
AutomatedMaskEdit, Vcl.ToolWin, Vcl.ExtCtrls, Vcl.ImgList, System.ImageList,
AutomatedStaticText;
type
TForm1 = class(TForm)
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
StatusBar1: TStatusBar;
ComboBox1: TComboBox;
MainMenu1: TMainMenu;
File1: TMenuItem;
Hel1: TMenuItem;
Exit1: TMenuItem;
About1: TMenuItem;
PopupMenu1: TPopupMenu;
PopupMenu2: TMenuItem;
AutomatedEdit1: TAutomatedEdit;
AutomatedCombobox1: TAutomatedCombobox;
AutomatedCombobox2: TAutomatedCombobox;
AutomatedMaskEdit1: TAutomatedMaskEdit;
RichEdit1: TRichEdit;
TreeView1: TTreeView;
PopupMenu3: TPopupMenu;
Popup11: TMenuItem;
Popup21: TMenuItem;
Edit1: TEdit;
ListBox1: TListBox;
LinkLabel1: TLinkLabel;
Panel6: TPanel;
Panel7: TPanel;
ToolBar1: TToolBar;
ToolButton3: TToolButton;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton4: TToolButton;
Panel8: TPanel;
ToolBar2: TToolBar;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ImageList1: TImageList;
AutomatedStaticText1: TAutomatedStaticText;
AutomatedStringGrid1: TAutomatedStringGrid;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
procedure PopupMenu2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ToolButton1Click(Sender: TObject);
procedure ToolButton5Click(Sender: TObject);
procedure ToolButton7Click(Sender: TObject);
procedure LinkLabel1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage (edit1.Text + ' | ' + edit2.Text);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage ('Cancelled');
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
ShowMessage('Oh well done');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
AutomatedStringGrid1.Cells[0,0] := 'Title 1';
AutomatedStringGrid1.Cells[1,0] := 'Title 2';
AutomatedStringGrid1.Cells[2,0] := 'Title 3';
AutomatedStringGrid1.Cells[3,0] := 'Title 4';
AutomatedStringGrid1.Cells[4,0] := 'Title 5';
AutomatedStringGrid1.Cells[0,1] := 'Row 1, Col 0';
AutomatedStringGrid1.Cells[1,1] := 'Row 1, Col 1';
AutomatedStringGrid1.Cells[2,1] := 'Row 1, Col 2';
AutomatedStringGrid1.Cells[3,1] := 'Row 1, Col 3';
AutomatedStringGrid1.Cells[4,1] := 'Row 1, Col 4';
AutomatedStringGrid1.Cells[0,3] := 'Row 3, Col 0';
AutomatedStringGrid1.Cells[1,3] := 'Row 3, Col 1';
AutomatedStringGrid1.Cells[2,3] := 'Row 3, Col 2';
AutomatedStringGrid1.Cells[3,3] := 'Row 3, Col 3';
AutomatedStringGrid1.Cells[4,3] := 'Row 3, Col 4';
end;
procedure TForm1.LinkLabel1Click(Sender: TObject);
begin
ShowMessage ('LinkLabel1Click');
end;
procedure TForm1.PopupMenu2Click(Sender: TObject);
begin
ShowMessage ('Popup menu clicked');
end;
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
ShowMessage ('ToolButton1Click');
end;
procedure TForm1.ToolButton5Click(Sender: TObject);
begin
ShowMessage ('ToolButton5Click');
end;
procedure TForm1.ToolButton7Click(Sender: TObject);
begin
ShowMessage ('ToolButton7Click');
end;
end.

View File

@ -0,0 +1,449 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
library UIAutomation;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
System.ShareMem,
System.SysUtils,
System.Classes,
UIAutomationClient_TLB in '..\source\UIAutomationClient_TLB.pas',
DelphiUIAutomation.Automation in '..\source\DelphiUIAutomation.Automation.pas',
DelphiUIAutomation.Window in '..\source\Controls\DelphiUIAutomation.Window.pas',
DelphiUIAutomation.Client in '..\source\DelphiUIAutomation.Client.pas',
DelphiUIAutomation.Utils in '..\source\DelphiUIAutomation.Utils.pas',
DelphiUIAutomation.EditBox in '..\source\Controls\DelphiUIAutomation.EditBox.pas',
DelphiUIAutomation.Button in '..\source\Controls\DelphiUIAutomation.Button.pas',
DelphiUIAutomation.ControlTypeIDs in '..\source\Ids\DelphiUIAutomation.ControlTypeIDs.pas',
DelphiUIAutomation.PatternIDs in '..\source\Ids\DelphiUIAutomation.PatternIDs.pas',
DelphiUIAutomation.Mouse in '..\source\DelphiUIAutomation.Mouse.pas',
DelphiUIAutomation.ComboBox in '..\source\Controls\DelphiUIAutomation.ComboBox.pas',
DelphiUIAutomation.PropertyIDs in '..\source\Ids\DelphiUIAutomation.PropertyIDs.pas',
DelphiUIAutomation.Tab in '..\source\Controls\DelphiUIAutomation.Tab.pas',
DelphiUIAutomation.TabItem in '..\source\Controls\DelphiUIAutomation.TabItem.pas',
DelphiUIAutomation.Statusbar in '..\source\Controls\DelphiUIAutomation.Statusbar.pas',
DelphiUIAutomation.Checkbox in '..\source\Controls\DelphiUIAutomation.Checkbox.pas',
DelphiUIAutomation.RadioButton in '..\source\Controls\DelphiUIAutomation.RadioButton.pas',
DelphiUIAutomation.MenuItem in '..\source\Controls\Menus\DelphiUIAutomation.MenuItem.pas',
DelphiUIAutomation.Exception in '..\source\DelphiUIAutomation.Exception.pas',
DelphiUIAutomation.Desktop in '..\source\Controls\DelphiUIAutomation.Desktop.pas',
DelphiUIAutomation.ScreenShot in '..\source\DelphiUIAutomation.ScreenShot.pas',
DelphiUIAutomation.Menu in '..\source\Controls\Menus\DelphiUIAutomation.Menu.pas',
DelphiUIAutomation.Base in '..\source\DelphiUIAutomation.Base.pas',
DelphiUIAutomation.Container in '..\source\Controls\DelphiUIAutomation.Container.pas',
DelphiUIAutomation.Tab.Intf in '..\source\Controls\DelphiUIAutomation.Tab.Intf.pas',
DelphiUIAutomation.Container.Intf in '..\source\Controls\DelphiUIAutomation.Container.Intf.pas',
DelphiUIAutomation.ListItem in '..\source\Controls\DelphiUIAutomation.ListItem.pas',
DelphiUIAutomation.Keyboard in '..\source\DelphiUIAutomation.Keyboard.pas',
DelphiUIAutomation.Hyperlink in '..\source\Controls\DelphiUIAutomation.Hyperlink.pas',
DelphiUIAutomation.TextBox in '..\source\Controls\DelphiUIAutomation.TextBox.pas',
DelphiUIAutomation.Processes in '..\source\DelphiUIAutomation.Processes.pas',
DelphiUIAutomation.Clipboard in '..\source\DelphiUIAutomation.Clipboard.pas',
DelphiUIAutomation.StringGrid in '..\source\Controls\DelphiUIAutomation.StringGrid.pas',
DelphiUIAutomation.Panel.Intf in '..\source\Controls\DelphiUIAutomation.Panel.Intf.pas',
DelphiUIAutomation.StringGridItem in '..\source\Controls\DelphiUIAutomation.StringGridItem.pas',
DelphiUIAutomation.Panel in '..\source\Controls\DelphiUIAutomation.Panel.pas',
DelphiUIAutomation.TreeView in '..\source\Controls\DelphiUIAutomation.TreeView.pas',
DelphiUIAutomation.Condition in '..\source\Conditions\DelphiUIAutomation.Condition.pas',
DelphiUIAutomation.AndCondition in '..\source\Conditions\DelphiUIAutomation.AndCondition.pas',
DelphiUIAutomation.OrCondition in '..\source\Conditions\DelphiUIAutomation.OrCondition.pas',
DelphiUIAutomation.FalseCondition in '..\source\Conditions\DelphiUIAutomation.FalseCondition.pas',
DelphiUIAutomation.TrueCondition in '..\source\Conditions\DelphiUIAutomation.TrueCondition.pas',
DelphiUIAutomation.NameCondition in '..\source\Conditions\DelphiUIAutomation.NameCondition.pas',
DelphiUIAutomation.ControlTypeCondition in '..\source\Conditions\DelphiUIAutomation.ControlTypeCondition.pas',
Dialogs;
{$R *.res}
var
application: IAutomationApplication;
procedure Initialize; export;
begin
TUIAuto.CreateUIAuto;
end;
procedure Finalize; export;
begin
TUIAuto.DestroyUIAuto;
end;
procedure LaunchOrAttach(const val1, val2 : String); export;
begin
application := TAutomationApplication.LaunchOrAttach (val1, val2);
end;
procedure Kill; export;
begin
application.Kill;
end;
function GetDesktopWindow(const value: String): Pointer; export;
var
window: TAutomationWindow;
begin
window := TAutomationDesktop.GetDesktopWindow(value);
result := window.GetHandle;
end;
function GetWindow(parent: Pointer; const value: String): Pointer; export;
var
window : IAutomationWindow;
popup : IAutomationWindow;
elem : IUIAutomationElement;
begin
elem := TUIAuto.GetElementFromHandle(parent);
window := TAutomationWindow.Create(elem, false);
popup := window.Window(value);
result := popup.GetHandle;
end;
procedure WaitWhileBusy; export;
begin
application.WaitWhileBusy;
end;
procedure Maximize(handle: Pointer); export;
var
window : IAutomationWindow;
elem : IUIAutomationElement;
begin
elem := TUIAuto.GetElementFromHandle(handle);
window := TAutomationWindow.Create(elem, false);
window.Maximize;
end;
procedure SelectTab(handle: Pointer; text: String); export;
var
elem : IUIAutomationElement;
tab : IAutomationTab;
begin
elem := TUIAuto.GetElementFromHandle(handle);
tab := TAutomationTab.Create(elem);
tab.SelectTabPage(text);
end;
function GetTab(handle: Pointer; item: Integer) : Pointer; export;
var
window : IAutomationWindow;
elem : IUIAutomationElement;
tab : IAutomationTab;
begin
elem := TUIAuto.GetElementFromHandle(handle);
window := TAutomationWindow.Create(elem, false);
tab := window.GetTabByIndex(item);
result := tab.GetHandle;
end;
function GetEditBoxByName(handle: Pointer; name: String) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
eb : IAutomationEditBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
eb := parent.GetEditBoxByName(name);
result := eb.GetHandle;
end;
procedure Toggle(handle: Pointer); export;
var
cb : IAutomationCheckBox;
elem : IUIAutomationElement;
begin
elem := TUIAuto.GetElementFromHandle(handle);
cb := TAutomationCheckBox.Create(elem);
cb.Toggle;
end;
procedure SelectRadioButton(handle: Pointer; index: Integer); export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
rb : IAutomationRadioButton;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
rb := parent.GetRadioButtonByIndex(index);
rb.Select;
end;
function GetCheckBox(handle: Pointer; index: Integer) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
cb : IAutomationCheckBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
cb := parent.GetCheckboxByIndex(index);
result := cb.GetHandle;
end;
function GetTextBox(handle: Pointer; index: Integer) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
tb : IAutomationTextBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
tb := parent.GetTextBoxByIndex(index);
result := tb.GetHandle;
end;
function GetEditBox(handle: Pointer; index: Integer) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
eb : IAutomationEditBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
eb := parent.GetEditBoxByIndex(index);
result := eb.GetHandle;
end;
function GetText(handle: Pointer) : String; export;
var
elem : IUIAutomationElement;
tb : IAutomationEditBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
tb := TAutomationEditBox.Create(elem);
result := tb.Text;
end;
function GetTextFromText(handle: Pointer) : String; export;
var
elem : IUIAutomationElement;
tb : IAutomationTextBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
tb := TAutomationTextBox.Create(elem);
result := tb.Text;
end;
function GetStatusBar(handle: Pointer): Pointer; export;
var
parent : IAutomationWindow;
elem : IUIAutomationElement;
sb : IAutomationStatusBar;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationWindow.Create(elem, false);
sb := parent.StatusBar;
result := sb.GetHandle;
end;
function GetComboBoxByName(handle: Pointer; name: String) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
cb : IAutomationComboBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
cb := parent.GetComboBoxByName(name);
result := cb.GetHandle;
end;
function GetComboBox(handle: Pointer; index: Integer) : Pointer; export;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
cb : IAutomationComboBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
cb := parent.GetComboBoxByIndex(index);
result := cb.GetHandle;
end;
function SetText(handle: Pointer; name: String) : String; export;
var
elem : IUIAutomationElement;
tb : IAutomationEditBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
tb := TAutomationEditBox.Create(elem);
tb.Text := name;
end;
procedure SelectTreeViewItem(handle: Pointer; index: Integer; text: String);
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
tv : IAutomationTreeView;
tvi : IAutomationTreeViewItem;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
tv := parent.GetTreeViewByIndex(index);
tvi := tv.GetItem(text);
tvi.select;
end;
procedure ClickButton(handle: Pointer; name: String) export;
var
parent: IAutomationContainer;
elem : IUIAutomationElement;
btn : IAutomationButton;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationWindow.Create(elem, false);
btn := parent.GetButton(name);
btn.Click;
end;
procedure ClickMenuItem(handle: Pointer; name: String) export;
var
menu : IAutomationMenu;
parent: IAutomationWindow;
elem : IUIAutomationElement;
mi : IAutomationMenuItem;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationWindow.Create(elem, true);
menu := parent.MainMenu;
mi := menu.MenuItem(name);
mi.Click;
end;
function GetStatusBarText(handle: Pointer; index: Integer) : String; export;
var
parent : IAutomationWindow;
elem : IUIAutomationElement;
sb : IAutomationStatusBar;
tb : IAutomationTextBox;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationWindow.Create(elem, false);
sb := parent.StatusBar;
tb := sb.GetTextBoxByIndex(index);
result := tb.Text;
end;
function GetGrid(handle: Pointer; index: Integer) : Pointer;
var
parent : IAutomationContainer;
elem : IUIAutomationElement;
grid : IAutomationStringGrid;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationContainer.Create(elem);
grid := parent.GetStringGridByIndex(index);
result := grid.GetHandle;
end;
function GetCellValue(handle: Pointer; x, y: integer) : String;
var
parent : IAutomationStringGrid;
elem : IUIAutomationElement;
cell : IAutomationStringGridItem;
begin
elem := TUIAuto.GetElementFromHandle(handle);
parent := TAutomationStringGrid.Create(elem);
cell := parent.GetItem(x,y);
result := cell.Name;
end;
exports
GetGrid, GetCellValue,
GetWindow,
ClickButton,
ClickMenuItem, SelectRadioButton,
SelectTreeViewItem,
GetComboBox, GetComboBoxByName, SetText,
GetTextBox, GetTextFromText,
GetStatusBarText, GetEditBoxByName, GetEditBox, GetText, GetCheckBox, Toggle,
Kill, LaunchOrAttach, GetTab, Initialize,
Finalize, GetDesktopWindow, WaitWhileBusy, Maximize, SelectTab;
begin
end.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,65 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.AndCondition;
interface
uses
UIAutomationClient_TLB,
generics.collections,
DelphiUIAutomation.Condition;
type
TAndCondition = class(TInterfacedObject, ICondition)
strict private
conditions : TList<ICondition>;
public
function getCondition : IUIAutomationCondition;
constructor Create(firstCondition, secondCondition: ICondition);
end;
implementation
uses
DelphiUIAutomation.Automation;
{ TAndCondition }
constructor TAndCondition.Create(firstCondition, secondCondition: ICondition);
begin
conditions := TList<ICondition>.create;
conditions.add(firstCondition);
conditions.add(secondCondition);
end;
function TAndCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.createAndCondition(conditions[0].getCondition, conditions[1].getCondition, condition);
result := condition;
end;
end.

View File

@ -0,0 +1,43 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Condition;
interface
uses
UIAutomationClient_TLB;
type
ICondition = interface
['{9548F1A8-5FA7-4318-A22E-B1BE20DFD63A}']
function getCondition : IUIAutomationCondition;
end;
//type
// TCondition = class(TInterfacedObject, ICondition)
// public
// function getCondition : IUIAutomationCondition; virtual; abstract;
// end;
implementation
end.

View File

@ -0,0 +1,61 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.ControlTypeCondition;
interface
uses
UIAutomationClient_TLB,
generics.collections,
activex,
DelphiUIAutomation.Condition;
type
TControlTypeCondition = class(TInterfacedObject, ICondition)
strict private
FpropertyId: SYSINT;
public
function getCondition : IUIAutomationCondition;
constructor Create(propertyId: SYSINT);
end;
implementation
uses
DelphiUIAutomation.PropertyIDs,
DelphiUIAutomation.Automation;
constructor TControlTypeCondition.Create(propertyId: SYSINT);
begin
FpropertyId := propertyId;
end;
function TControlTypeCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, FpropertyId, condition);
result := condition;
end;
end.

View File

@ -0,0 +1,51 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.FalseCondition;
interface
uses
UIAutomationClient_TLB,
DelphiUIAutomation.Condition;
type
TFalseCondition = class(TInterfacedObject, ICondition)
public
function getCondition : IUIAutomationCondition;
end;
implementation
uses
DelphiUIAutomation.Automation;
function TFalseCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.createFalseCondition(condition);
result := condition;
end;
end.

View File

@ -0,0 +1,59 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.NameCondition;
interface
uses
UIAutomationClient_TLB,
generics.collections,
DelphiUIAutomation.Condition;
type
TNameCondition = class(TInterfacedObject, ICondition)
strict private
FName: String;
public
function getCondition : IUIAutomationCondition;
constructor Create(name: String);
end;
implementation
uses
DelphiUIAutomation.PropertyIDs,
DelphiUIAutomation.Automation;
constructor TNameCondition.Create(name: String);
begin
FName := name;
end;
function TNameCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.CreatePropertyCondition(UIA_NamePropertyId, FName, condition);
result := condition;
end;
end.

View File

@ -0,0 +1,62 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.OrCondition;
interface
uses
UIAutomationClient_TLB,
generics.collections,
DelphiUIAutomation.Condition;
type
TOrCondition = class(TInterfacedObject, ICondition)
strict private
conditions : TList<ICondition>;
public
function getCondition : IUIAutomationCondition;
constructor Create(firstCondition, secondCondition: ICondition);
end;
implementation
uses
DelphiUIAutomation.Automation;
constructor TOrCondition.Create(firstCondition, secondCondition: ICondition);
begin
conditions := TList<ICondition>.create;
conditions.add(firstCondition);
conditions.add(secondCondition);
end;
function TOrCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.createOrCondition(conditions[0].getCondition, conditions[1].getCondition, condition);
result := condition;
end;
end.

View File

@ -0,0 +1,53 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2016 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.TrueCondition;
interface
uses
UIAutomationClient_TLB,
DelphiUIAutomation.Condition;
type
TTrueCondition = class(TInterfacedObject, ICondition)
public
function getCondition : IUIAutomationCondition;
end;
implementation
uses
DelphiUIAutomation.Automation;
{ TTrueCondition }
function TTrueCondition.getCondition: IUIAutomationCondition;
var
condition : IUIAutomationCondition;
begin
uiAuto.createTrueCondition(condition);
result := condition;
end;
end.

View File

@ -0,0 +1,94 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Button;
interface
uses
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
type
/// <summary>
/// Interface for a button control
/// </summary>
IAutomationButton = interface
['{BB9FB82C-8794-4355-B0BE-610B03B69822}']
/// <summary>
/// Clicks the button
/// </summary>
function Click : HResult;
/// <summary>
/// Focuses the button
/// </summary>
function Focus : HResult;
end;
/// <summary>
/// Representation of a button control
/// </summary>
TAutomationButton = class (TAutomationBase, IAutomationButton)
private
fInvokePattern : IUIAutomationInvokePattern;
public
/// <summary>
/// Clicks the button
/// </summary>
function Click : HResult;
/// <summary>
/// Focuses the button
/// </summary>
function Focus : HResult;
constructor Create(element : IUIAutomationElement); override;
end;
implementation
uses
types,
DelphiUIAutomation.Mouse,
DelphiUIAutomation.PatternIDs;
{ TAutomationButton }
function TAutomationButton.Click : HResult;
begin
result := FInvokePattern.Invoke;
end;
constructor TAutomationButton.Create(element: IUIAutomationElement);
begin
inherited Create(element);
fInvokePattern := getInvokePattern;
end;
function TAutomationButton.Focus: HResult;
begin
result := FElement.SetFocus;
end;
end.

View File

@ -0,0 +1,113 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Checkbox;
interface
uses
activex,
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
type
IAutomationCheckBox = interface (IAutomationBase)
['{9A290D8D-BAE7-47E6-BE7A-28DF5ADCE5C7}']
///<summary>
/// Performs a toggle action
///</summary>
function Toggle: HRESULT;
///<summary>
/// Gets the toggle state of the checkbox
///</summary>
function ToggleState : TOleEnum;
/// <summary>
/// Focuses the checkbox
/// </summary>
function Focus : HResult;
end;
/// <summary>
/// Represents a checkbox control
/// </summary>
TAutomationCheckBox = class (TAutomationBase, IAutomationCheckBox)
strict private
FTogglePattern : IUIAutomationTogglePattern;
public
///<summary>
/// Performs a toggle action
///</summary>
function Toggle: HRESULT;
///<summary>
/// Gets the toggle state of the checkbox
///</summary>
function ToggleState : TOleEnum;
/// <summary>
/// Focuses the checkbox
/// </summary>
function Focus : HResult;
/// <summary>
/// Constructor for the element.
/// </summary>
constructor Create(element : IUIAutomationElement); override;
end;
implementation
uses
DelphiUIAutomation.Exception,
DelphiUIAutomation.PatternIDs;
{ TAutomationCheckBox }
constructor TAutomationCheckBox.Create(element: IUIAutomationElement);
begin
inherited create(element);
FTogglePattern := GetTogglePattern;
end;
function TAutomationCheckBox.Toggle: HRESULT;
begin
result := self.FTogglePattern.Toggle;
end;
function TAutomationCheckBox.ToggleState: TOleEnum;
var
state : TOleEnum;
begin
self.FTogglePattern.Get_CurrentToggleState(state);
result := state;
end;
function TAutomationCheckBox.Focus: HResult;
begin
result := FElement.SetFocus;
end;
end.

View File

@ -0,0 +1,199 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.ComboBox;
interface
uses
generics.collections,
DelphiUIAutomation.Base,
DelphiUIAutomation.ListItem,
UIAutomationClient_TLB;
type
IAutomationComboBox = interface (IAutomationBase)
['{531C8646-A605-4D6D-BEE0-89E1719D6321}']
///<summary>
/// Gets the text associated with this combobox
///</summary>
function getText: string;
///<summary>
/// Sets the text associated with this combobox
///</summary>
procedure setText(const Value: string);
///<summary>
/// Gets or sets the text associated with this combobox
///</summary>
property Text : string read getText write setText;
end;
/// <summary>
/// Represents a combobox control
/// </summary>
TAutomationComboBox = class (TAutomationBase, IAutomationComboBox)
strict private
FItems : TObjectList<TAutomationListItem>;
FExpandCollapsePattern : IUIAutomationExpandCollapsePattern;
FValuePattern : IUIAutomationValuePattern;
private
///<summary>
/// Gets the text associated with this combobox
///</summary>
function getText: string;
///<summary>
/// Sets the text associated with this combobox
///</summary>
procedure setText(const Value: string);
function getItems: TObjectList<TAutomationListItem>;
procedure InitialiseList;
public
///<summary>
/// Gets or sets the text associated with this combobox
///</summary>
property Text : string read getText write setText;
///<summary>
/// Gets the list of items associated with this combobox
///</summary>
property Items : TObjectList<TAutomationListItem> read getItems;
/// <summary>
/// Call the expand property
/// </summary>
function Expand : HRESULT;
/// <summary>
/// Call the collapse property
/// </summary>
function Collapse : HRESULT;
/// <summary>
/// Constructor for comboboxes.
/// </summary>
constructor Create(element : IUIAutomationElement); override;
/// <summary>
/// Destructor for comboboxes.
/// </summary>
destructor Destroy; override;
end;
implementation
uses
ActiveX,
DelphiUIAutomation.Exception,
DelphiUIAutomation.Automation,
DelphiUIAutomation.ControlTypeIDs,
DelphiUIAutomation.PropertyIDs,
DelphiUIAutomation.PatternIDs,
sysutils;
{ TAutomationComboBox }
constructor TAutomationComboBox.Create(element: IUIAutomationElement);
begin
inherited Create(element);
FExpandCollapsePattern := GetExpandCollapsePattern;
FValuePattern := GetValuePattern;
self.Expand; // Have to expand for the list to be available
InitialiseList;
end;
destructor TAutomationComboBox.Destroy;
begin
FItems.free;
inherited;
end;
procedure TAutomationComboBox.InitialiseList;
var
collection : IUIAutomationElementArray;
itemElement : IUIAutomationElement;
count : integer;
length : integer;
retVal : integer;
item : TAutomationListItem;
begin
FItems := TObjectList<TAutomationListItem>.create;
// Find the elements
collection := self.FindAll(TreeScope_Children);
collection.Get_Length(length);
for count := 0 to length -1 do
begin
collection.GetElement(count, itemElement);
itemElement.Get_CurrentControlType(retVal);
if (retVal = UIA_ListItemControlTypeId) then
begin
item := TAutomationListItem.Create(itemElement);
FItems.Add(item);
end;
end;
end;
function TAutomationComboBox.Expand: HRESULT;
begin
if assigned(FExpandCollapsePattern) then
result := self.FExpandCollapsePattern.Expand
else
result := -1;
end;
function TAutomationComboBox.Collapse: HRESULT;
begin
result := self.FExpandCollapsePattern.Collapse;
end;
function TAutomationComboBox.getItems : TObjectList<TAutomationListItem>;
begin
result := self.FItems;
end;
function TAutomationComboBox.getText: string;
var
value : widestring;
begin
FValuePattern.Get_CurrentValue(value);
Result := trim(value);
end;
procedure TAutomationComboBox.setText(const Value: string);
begin
FValuePattern.SetValue(value);
end;
end.

View File

@ -0,0 +1,111 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Container.Intf;
interface
uses
DelphiUIAutomation.Tab.Intf,
DelphiUIAutomation.TextBox,
DelphiUIAutomation.EditBox,
DelphiUIAutomation.CheckBox,
DelphiUIAutomation.Button,
DelphiUIAutomation.Combobox,
DelphiUIAutomation.Panel.Intf,
DelphiUIAutomation.TreeView,
DelphiUIAutomation.Menu,
DelphiUIAutomation.Base,
DelphiUIAutomation.StringGrid,
DelphiUIAutomation.RadioButton;
type
IAutomationContainer = interface (IAutomationBase)
['{1077F870-7065-4FA9-BCC7-C8D3610CB2C6}']
/// <summary>
/// Finds the tab
/// </summary>
function GetTabByIndex (index : integer) : IAutomationTab;
/// <summary>
/// Finds the textbox, by index
/// </summary>
function GetTextBoxByIndex (index : integer) : IAutomationTextBox;
/// <summary>
/// Finds the combobox, by index
/// </summary>
function GetComboboxByIndex (index : integer) : IAutomationComboBox;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetCheckboxByIndex (index : integer) : IAutomationCheckBox;
/// <summary>
/// Finds the checkbox, by text
/// </summary>
function GetCheckboxByName (const value : string) : IAutomationCheckBox;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetRadioButtonByIndex (index : integer) : IAutomationRadioButton;
/// <summary>
/// Finds a panel, by index
/// </summary>
function GetPanelByIndex (index : integer) : IAutomationPanel;
/// <summary>
/// Finds the button with the title supplied
/// </summary>
function GetButton (const title : string) : IAutomationButton;
/// <summary>
/// Finds the stringgrid, by index
/// </summary>
function GetStringGridByIndex (index : integer) : IAutomationStringGrid;
/// <summary>
/// Finds the editbox, by index
/// </summary>
function GetEditBoxByIndex (index : integer) : IAutomationEditBox;
/// <summary>
/// Finds the editbox, by name
/// </summary>
function GetEditBoxByName (name: String) : IAutomationEditBox;
/// <summary>
/// Finds the combobox, by name
/// </summary>
function GetComboboxByName (name : String) : IAutomationComboBox;
/// <summary>
/// Finds the treeview, by index
/// </summary>
function GetTreeViewByIndex (index : integer): IAutomationTreeView;
end;
implementation
end.

View File

@ -0,0 +1,342 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Container;
interface
uses
DelphiUIAutomation.Tab.Intf,
DelphiUIAutomation.EditBox,
DelphiUIAutomation.TextBox,
DelphiUIAutomation.CheckBox,
DelphiUIAutomation.Container.Intf,
DelphiUIAutomation.panel.Intf,
DelphiUIAutomation.RadioButton,
DelphiUIAutomation.ComboBox,
DelphiUIAutomation.Button,
DelphiUIAutomation.Panel,
DelphiUIAutomation.Menu,
DelphiUIAutomation.Base,
DelphiUIAutomation.TreeView,
DelphiUIAutomation.StringGrid,
UIAutomationClient_TLB;
type
/// <summary>
/// Finds the tab
/// </summary>
TAutomationContainer = class (TAutomationBase, IAutomationContainer)
protected
function GetControlByControlType (index : integer; id : word) : IUIAutomationElement; overload;
function GetControlByControlType (index : integer; id: word; controlType : string) : IUIAutomationElement; overload;
// function GetControlByControlType (title : string; id : word) : IUIAutomationElement; overload;
function GetControlByControlType1 (title : string; id : word) : IUIAutomationElement; overload;
public
/// <summary>
/// Finds the tab
/// </summary>
function GetTabByIndex (index : integer) : IAutomationTab;
/// <summary>
/// Finds the editbox, by index
/// </summary>
function GetEditBoxByIndex (index : integer) : IAutomationEditBox;
/// <summary>
/// Finds the textbox, by index
/// </summary>
function GetTextBoxByIndex(index: integer): IAutomationTextBox;
/// <summary>
/// Finds the combobox, by index
/// </summary>
function GetComboboxByIndex (index : integer) : IAutomationComboBox;
/// <summary>
/// Finds the stringgrid, by index
/// </summary>
function GetStringGridByIndex (index : integer) : IAutomationStringGrid;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetCheckboxByIndex (index : integer) : IAutomationCheckBox;
/// <summary>
/// Finds a panel, by index
/// </summary>
function GetPanelByIndex (index : integer) : IAutomationPanel;
/// <summary>
/// Finds the checkbox, by name
/// </summary>
function GetCheckboxByName(const value: string): IAutomationCheckBox;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetRadioButtonByIndex (index : integer) : IAutomationRadioButton;
/// <summary>
/// Finds the button with the title supplied
/// </summary>
function GetButton (const title : string) : IAutomationButton;
/// <summary>
/// Finds the editbox, by name
/// </summary>
function GetEditBoxByName (name: String) : IAutomationEditBox;
/// <summary>
/// Finds the combobox, by name
/// </summary>
function GetComboboxByName (name : String) : IAutomationComboBox;
/// <summary>
/// Finds the treeview, by index
/// </summary>
function GetTreeViewByIndex (index: Integer): IAutomationTreeView;
end;
implementation
uses
windows,
sysutils,
ActiveX,
DelphiUIAutomation.Tab,
DelphiUIAutomation.Condition,
DelphiUIAutomation.PropertyIDs,
DelphiUIAutomation.ControlTypeIDs,
DelphiUIAutomation.Exception,
DelphiUIAutomation.Automation;
function TAutomationContainer.GetCheckboxByName(const value: string): IAutomationCheckBox;
begin
result := TAutomationCheckBox.Create(GetControlByControlType1(value, UIA_CheckBoxControlTypeId));
end;
function TAutomationContainer.GetEditBoxByIndex(index: integer): IAutomationEditBox;
var
eb : IUIAutomationElement;
begin
eb := GetControlByControlType(index, UIA_EditControlTypeId);
result := TAutomationEditBox.Create(eb);
end;
function TAutomationContainer.GetPanelByIndex(index: integer): IAutomationPanel;
var
tb : IUIAutomationElement;
begin
tb := GetControlByControlType(index, UIA_PaneControlTypeId);
result := TAutomationPanel.Create(tb);
end;
function TAutomationContainer.GetTextBoxByIndex(index: integer): IAutomationTextBox;
var
tb : IUIAutomationElement;
begin
tb := GetControlByControlType(index, UIA_TextControlTypeId);
result := TAutomationTextBox.Create(tb);
end;
function TAutomationContainer.GetTreeViewByIndex(
index: Integer): IAutomationTreeView;
var
treeView : IUIAutomationElement;
begin
treeView := GetControlByControlType(0, UIA_TreeControlTypeId);
result := TAutomationTreeView.Create(treeView);
end;
function TAutomationContainer.GetButton(const title: string): IAutomationButton;
var
btn : IUIAutomationElement;
begin
btn := GetControlByControlType1(title, UIA_ButtonControlTypeId);
result := TAutomationButton.Create(btn);
end;
function TAutomationContainer.GetCheckboxByIndex(index: integer): IAutomationCheckBox;
begin
result := TAutomationCheckBox.Create(GetControlByControlType(index, UIA_CheckBoxControlTypeId));
end;
function TAutomationContainer.GetComboboxByIndex (index : integer) : IAutomationComboBox;
begin
result := TAutomationComboBox.Create(GetControlByControlType(index, UIA_ComboBoxControlTypeId));
end;
function TAutomationContainer.GetControlByControlType1(title: string; id: word): IUIAutomationElement;
var
condition, condition1, condition2: ICondition;
element : IUIAutomationElement;
begin
condition1 := TuiAuto.createNameCondition(title);
condition2 := TuiAuto.createControlTypeCondition(id);
condition := TUIAuto.createAndCondition(condition1, condition2);
self.FElement.FindFirst(TreeScope_Descendants, condition.getCondition, element);
result := element;
end;
function TAutomationContainer.GetControlByControlType(index: integer; id: word;
controlType: string): IUIAutomationElement;
var
element : IUIAutomationElement;
collection : IUIAutomationElementArray;
condition : IUIAutomationCondition;
count : integer;
length : integer;
counter : integer;
varProp : OleVariant;
CName : WideString;
begin
element := nil;
TVariantArg(varProp).vt := VT_I4;
TVariantArg(varProp).lVal := id; // At the moment it is always a pane
UIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, condition);
// Find the element
self.FElement.FindAll(TreeScope_Descendants, condition, collection);
collection.Get_Length(length);
counter := 0;
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentClassName(CName);
if CName = controlType then
begin
if counter = index then
begin
result := element;
break;
end;
inc (counter);
end;
end;
// if result = nil then
// raise EDelphiAutomationException.Create('Unable to find control');
end;
function TAutomationContainer.GetControlByControlType(index : integer; id: word): IUIAutomationElement;
var
element : IUIAutomationElement;
collection : IUIAutomationElementArray;
condition : IUIAutomationCondition;
count : integer;
length : integer;
counter : integer;
varProp : OleVariant;
// For debugging
name : WideString;
begin
element := nil;
TVariantArg(varProp).vt := VT_I4;
TVariantArg(varProp).lVal := id;
UIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, condition);
// Find the element
self.FElement.FindAll(TreeScope_Descendants, condition, collection);
collection.Get_Length(length);
counter := 0;
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentName(name);
OutputDebugString(pwidechar(name));
if counter = index then
begin
result := element;
break;
end;
inc (counter);
end;
// if result = nil then
// raise EDelphiAutomationException.Create('Unable to find control');
end;
function TAutomationContainer.GetRadioButtonByIndex(index: integer): IAutomationRadioButton;
begin
result := TAutomationRadioButton.Create(GetControlByControlType(index, UIA_RadioButtonControlTypeId));
end;
function TAutomationContainer.GetStringGridByIndex(index: integer): IAutomationStringGrid;
begin
result := TAutomationStringGrid.Create(GetControlByControlType(index, UIA_DataGridControlTypeId, 'TAutomationStringGrid'));
end;
function TAutomationContainer.GetTabByIndex (index : integer) : IAutomationTab;
begin
result := TAutomationTab.Create(GetControlByControlType(index, UIA_TabControlTypeId));
end;
function TAutomationContainer.GetEditBoxByName(
name: String): IAutomationEditBox;
var
eb : IUIAutomationElement;
begin
eb := GetControlByControlType1(name, UIA_EditControlTypeId);
result := TAutomationEditBox.Create(eb);
end;
function TAutomationContainer.GetComboboxByName(
name: String): IAutomationComboBox;
var
cb : IUIAutomationElement;
begin
cb := GetControlByControlType1(name, UIA_ComboBoxControlTypeId);
result := TAutomationComboBox.Create(cb);
end;
end.

View File

@ -0,0 +1,207 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Desktop;
interface
uses
windows,
generics.collections,
DelphiUIAutomation.Menu,
DelphiUIAutomation.PropertyIDs,
DelphiUIAutomation.Window;
type
/// <summary>
/// Represents the Windows 'desktop'
/// </summary>
TAutomationDesktop = class
public
/// <summary>
/// Gets the list of desktop windows
/// </summary>
class function GetDesktopWindows : TObjectList<TAutomationWindow>;
/// <summary>
/// Gets the specified desktop windows
/// </summary>
class function GetDesktopWindow (const title : String) : TAutomationWindow; overload;
/// <summary>
/// Gets the specified desktop windows, with a timeout
/// </summary>
class function GetDesktopWindow (const title : String; timeout : DWORD) : TAutomationWindow; overload;
/// <summary>
/// Gets the context menu
/// </summary>
/// <remarks>
/// Yes, it seems to be owned by the desktop
/// </remarks>
class function GetContextMenu(timeout: DWORD = DEFAULT_TIMEOUT) : IAutomationMenu;
end;
implementation
uses
ActiveX,
DelphiUIAutomation.Exception,
DelphiUIAutomation.Condition,
DelphiUIAutomation.Automation,
DelphiUIAutomation.ControlTypeIDs,
UIAutomationClient_TLB,
sysutils;
const
DEFAULT_TIMEOUT = 99999999;
class function TAutomationDesktop.GetDesktopWindow(const title : String): TAutomationWindow;
begin
result := TAutomationDesktop.GetDesktopWindow(title, DEFAULT_TIMEOUT);
end;
class function TAutomationDesktop.GetContextMenu(timeout: DWORD = DEFAULT_TIMEOUT): IAutomationMenu;
var
collection : IUIAutomationElementArray;
condition : IUIAutomationCondition;
element : IUIAutomationElement;
name : WideString;
count, length : integer;
start : DWORD;
aborted : boolean;
function TimedOut : boolean;
begin
result := GetTickCount - start > timeout;
end;
begin
result := nil;
UIAuto.CreateTrueCondition(condition);
start := GetTickCount;
aborted := false;
while (result = nil) and (not aborted) do
begin
aborted := TimedOut;
rootElement.FindAll(TreeScope_Children, condition, collection);
collection.Get_Length(length);
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentName(name);
if name = 'Context' then
begin
result := TAutomationMenu.Create(nil, element);
break;
end;
end;
end;
if result = nil then
raise EDelphiAutomationException.Create('Unable to find context menu');
end;
class function TAutomationDesktop.GetDesktopWindow(const title: String;
timeout: DWORD): TAutomationWindow;
var
collection : IUIAutomationElementArray;
condition : ICondition;
element : IUIAutomationElement;
name : WideString;
count, length : integer;
start : DWORD;
aborted : boolean;
function TimedOut : boolean;
begin
result := GetTickCount - start > timeout;
end;
begin
result := nil;
condition := TUIAuto.CreateTrueCondition;
start := GetTickCount;
aborted := false;
while (result = nil) and (not aborted) do
begin
aborted := TimedOut;
rootElement.FindAll(TreeScope_Children, condition.getCondition, collection);
collection.Get_Length(length);
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentName(name);
if name = title then
begin
result := TAutomationWindow.Create(element, true);
break;
end;
end;
end;
if result = nil then
raise EDelphiAutomationException.Create('Unable to find window');
end;
class function TAutomationDesktop.getDesktopWindows: TObjectList<TAutomationWindow>;
var
res : TObjectList<TAutomationWindow>;
collection : IUIAutomationElementArray;
condition : ICondition;
element : IUIAutomationElement;
name : WideString;
count, length : integer;
begin
res := TObjectList<TAutomationWindow>.create();
condition := TUIAuto.CreateTrueCondition;
rootElement.FindAll(TreeScope_Children, condition.getCondition, collection);
collection.Get_Length(length);
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentName(name);
res.Add(TAutomationWindow.create(element, true));
end;
result := res;
end;
end.

View File

@ -0,0 +1,131 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015-16 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.EditBox;
interface
uses
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
type
IAutomationEditBox = interface (IAutomationBase)
['{CA47F9E7-ACF6-4B5B-9029-10428C52E1FE}']
function getText: string;
procedure setText(const Value: string);
///<summary>
/// Gets or sets the text
///</summary>
property Text : string read getText write setText;
end;
/// <summary>
/// Represents an edit box
/// </summary>
/// <remarks>
/// TEdit for example.
/// </remarks>
TAutomationEditBox = class (TAutomationBase, IAutomationEditBox)
strict private
fValuePattern : IUIAutomationValuePattern;
private
function getIsPassword: boolean;
function getIsReadOnly: boolean;
function getText: string;
procedure setText(const Value: string);
public
///<summary>
/// Gets or sets the text
///</summary>
property Text : string read getText write setText;
///<summary>
/// Gets whether the control is a password control
///</summary>
property IsPassword : boolean read getIsPassword;
///<summary>
/// Gets whether the control is read-only
///</summary>
property IsReadOnly : boolean read getIsReadOnly;
constructor Create(element : IUIAutomationElement); override;
end;
implementation
uses
DelphiUIAutomation.Exception,
DelphiUIAutomation.PatternIDs,
sysutils;
{ TAutomationTextBox }
constructor TAutomationEditBox.Create(element: IUIAutomationElement);
begin
inherited Create(element);
fValuePattern := GetValuePattern;
end;
function TAutomationEditBox.getIsPassword: boolean;
var
retVal : integer;
begin
Felement.Get_CurrentIsPassword(retVal);
result := false;
end;
function TAutomationEditBox.getIsReadOnly: boolean;
begin
result := false;
end;
function TAutomationEditBox.getText: string;
var
value : widestring;
begin
result := '';
if getIsPassword then
begin
raise EDelphiAutomationException.Create('Unable to get text for password editboxes');
end
else
begin
FValuePattern.Get_CurrentValue(value);
Result := trim(value);
end;
end;
procedure TAutomationEditBox.setText(const Value: string);
begin
FValuePattern.SetValue(value);
end;
end.

View File

@ -0,0 +1,72 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Hyperlink;
interface
uses
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
type
/// <summary>
/// Represents a hyperlink
/// </summary>
TAutomationHyperlink = class (TAutomationBase)
public
/// <summary>
/// Selects this tabitem
/// </summary>
/// <remarks>
/// Has to simulate the click
/// </remarks>
procedure Click;
end;
implementation
uses
Winapi.Windows,
DelphiUIAutomation.Mouse;
{ TAutomationHyperlink }
procedure TAutomationHyperlink.Click;
var
rect : tagRect;
mouse : TAutomationMouse;
begin
fElement.Get_CurrentBoundingRectangle(rect);
mouse := TAutomationMouse.Create;
try
mouse.Location := TPoint.Create(rect.top, rect.left);
mouse.LeftClick;
finally
mouse.Free;
end;
end;
end.

View File

@ -0,0 +1,35 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.ListItem;
interface
uses
DelphiUIAutomation.Base;
type
TAutomationListItem = class(TAutomationBase)
end;
implementation
end.

View File

@ -0,0 +1,36 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Panel.Intf;
interface
uses
DelphiUIAutomation.Base;
type
IAutomationPanel = interface (IAutomationBase)
['{AF968E72-22C1-4D91-A65D-20A94CAE4F64}']
end;
implementation
end.

View File

@ -0,0 +1,48 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Panel;
interface
uses
Winapi.Windows,
DelphiUIAutomation.Container.Intf,
DelphiUIAutomation.Panel.Intf,
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
const
DEFAULT_TIMEOUT = 99999999;
type
/// <summary>
/// Represents a window
/// </summary>
TAutomationPanel = class (TAutomationBase, IAutomationPanel)
public
end;
implementation
{ TAutomationPanel }
end.

View File

@ -0,0 +1,73 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.RadioButton;
interface
uses
DelphiUIAutomation.Base,
UIAutomationClient_TLB;
type
IAutomationRadioButton = interface (IAutomationBase)
['{B40E22FF-6E10-4E9C-8900-48C4D1F83F19}']
///<summary>
/// Selects the control
///</summary>
function Select: HRESULT;
end;
/// <summary>
/// Represents a radio button control
/// </summary>
TAutomationRadioButton = class (TAutomationBase, IAutomationRadioButton)
private
FSelectionItemPattern : IUIAutomationSelectionItemPattern;
public
///<summary>
/// Selects the control
///</summary>
function Select: HRESULT;
constructor Create(element : IUIAutomationElement); override;
end;
implementation
uses
DelphiUIAutomation.PatternIDs;
{ TAutomationRadioButton }
constructor TAutomationRadioButton.Create(element: IUIAutomationElement);
begin
inherited Create(element);
FSelectionItemPattern := getSelectionItemPattern;
end;
function TAutomationRadioButton.Select: HRESULT;
begin
result := FSelectionItemPattern.Select;
end;
end.

View File

@ -0,0 +1,52 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Statusbar;
interface
uses
DelphiUIAutomation.Container.Intf,
DelphiUIAutomation.Base,
DelphiUIAutomation.Container,
UIAutomationClient_TLB;
type
IAutomationStatusbar = interface (IAutomationContainer)
['{6C04412C-4FA6-4023-814D-C26C1691B015}']
end;
/// <summary>
/// Represents a statusbar
/// </summary>
TAutomationStatusbar = class (TAutomationContainer, IAutomationStatusbar)
end;
implementation
uses
DelphiUIAutomation.ControlTypeIDs,
DelphiUIAutomation.Automation;
{ TAutomationStatusbar }
end.

View File

@ -0,0 +1,182 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.StringGrid;
interface
uses
Generics.Collections,
DelphiUIAutomation.StringGridItem,
DelphiUIAutomation.Base,
ActiveX,
UIAutomationClient_TLB;
type
IAutomationStringGrid = interface (IAutomationBase)
['{6E151D9C-33C7-4D82-A25C-BED061F3FB61}']
function GetValue: string;
function GetColumnHeaders : TObjectList<TAutomationStringGridItem>;
function GetSelected : IAutomationStringGridItem;
///<summary>
/// Gets or sets the value
///</summary>
property Value : string read GetValue;
function GetItem(row: SYSINT; column: SYSINT) : IAutomationStringGridItem;
property Selected : IAutomationStringGridItem read GetSelected;
property ColumnHeaders : TObjectList<TAutomationStringGridItem> read GetColumnHeaders;
end;
/// <summary>
/// Represents a string grid - as best we can
/// </summary>
TAutomationStringGrid = class (TAutomationBase, IAutomationStringGrid)
strict private
FValuePattern : IUIAutomationValuePattern;
FGridPattern : IUIAutomationGridPattern;
FSelectionPattern : IUIAutomationSelectionPattern;
FTablePattern : IUIAutomationTablePattern;
private
function GetValue: string;
procedure GetPatterns;
function GetSelected : IAutomationStringGridItem;
function GetColumnHeaders : TObjectList<TAutomationStringGridItem>;
public
///<summary>
/// Gets or sets the value
///</summary>
property Value : string read GetValue;
function GetItem(row: SYSINT; column: SYSINT) : IAutomationStringGridItem;
// function GetSelectedText : string;
constructor Create(element : IUIAutomationElement); override;
property ColumnHeaders : TObjectList<TAutomationStringGridItem> read GetColumnHeaders;
property Selected : IAutomationStringGridItem read GetSelected;
end;
implementation
uses
SysUtils,
DelphiUIAutomation.Exception,
DelphiUIAutomation.PatternIDs;
{ TAutomationStringGrid }
constructor TAutomationStringGrid.Create(element: IUIAutomationElement);
begin
inherited create(element);
GetPatterns;
end;
function TAutomationStringGrid.GetColumnHeaders: TObjectList<TAutomationStringGridItem>;
var
collection : IUIAutomationElementArray;
count : integer;
length : integer;
element : IUIAutomationElement;
items : TObjectList<TAutomationStringGridItem>;
begin
FTablePattern.GetCurrentColumnHeaders(collection);
collection.Get_Length(length);
items := TObjectList<TAutomationStringGridItem>.create;
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
items.Add(TAutomationStringGridItem.create(element));
end;
result := items;
end;
function TAutomationStringGrid.GetValue: string;
var
value : WideString;
begin
FValuePattern.Get_CurrentValue(value);
Result := trim(value);
end;
function TAutomationStringGrid.GetItem(row,
column: SYSINT): IAutomationStringGridItem;
var
value : IUIAutomationElement;
begin
FGridPattern.GetItem(row, column, value);
result := TAutomationStringGridItem.create(value);
end;
procedure TAutomationStringGrid.GetPatterns;
begin
FValuePattern := GetValuePattern;
FGRidPattern := GetGridPattern;
FSelectionPattern := GetSelectionPattern;
FTablePattern := GetTablePattern;
end;
function TAutomationStringGrid.GetSelected: IAutomationStringGridItem;
var
collection : IUIAutomationElementArray;
count : integer;
retval : integer;
element : IUIAutomationElement;
length : integer;
item : IAutomationStringGridItem;
begin
FSelectionPattern.GetCurrentSelection(collection);
collection.Get_Length(length);
item := nil;
// There should only be one!
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentControlType(retVal);
item := TAutomationStringGridItem.Create(element);
end;
result := item;
end;
end.

View File

@ -0,0 +1,85 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.StringGridItem;
interface
uses
UIAutomationClient_TLB,
DelphiUIAutomation.Base;
type
IAutomationStringGridItem = interface(IAutomationBase)
['{D4F198BF-2137-4073-B3F2-378601E56854}']
function Select : HResult;
end;
TAutomationStringGridItem = class(TAutomationBase, IAutomationStringGridItem)
strict private
FSelectionItemPattern : IUIAutomationSelectionItemPattern;
FValuePattern : IUIAutomationValuePattern;
private
procedure GetPatterns;
protected
function getName: string; override;
public
function Select : HResult;
constructor Create(element: IUIAutomationElement); override;
end;
implementation
uses
SysUtils,
DelphiUIAutomation.Exception,
DelphiUIAutomation.PatternIDs;
{ TAutomationStringGridItem }
function TAutomationStringGridItem.Select : HResult;
begin
result := self.FSelectionItemPattern.select;
end;
function TAutomationStringGridItem.getName: string;
var
name : widestring;
begin
FValuePattern.Get_CurrentValue(name);
Result := trim(name);
end;
procedure TAutomationStringGridItem.GetPatterns;
begin
FSelectionItemPattern := GetSelectionItemPattern;
FValuePattern := GetValuePattern;
end;
constructor TAutomationStringGridItem.Create(element: IUIAutomationElement);
begin
inherited create(element);
GetPatterns;
end;
end.

View File

@ -0,0 +1,89 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Tab.Intf;
interface
uses
DelphiUIAutomation.TextBox,
DelphiUIAutomation.EditBox,
DelphiUIAutomation.CheckBox,
DelphiUIAutomation.Button,
DelphiUIAutomation.TabItem,
DelphiUIAutomation.Combobox,
DelphiUIAutomation.Base,
DelphiUIAutomation.RadioButton;
type
IAutomationTab = interface (IAutomationBase)
['{542BED07-5345-4E0F-993C-26C121B66371}']
function GetSelectedItem: IAutomationTabItem;
///<summary>
/// Selects the given tab
///</summary>
procedure SelectTabPage(const value : string);
/// <summary>
/// Finds the tab
/// </summary>
function GetTabByIndex (index : integer) : IAutomationTab;
/// <summary>
/// Finds the textbox, by index
/// </summary>
function GetTextBoxByIndex (index : integer) : IAutomationTextBox;
/// <summary>
/// Finds the editbox, by index
/// </summary>
function GetEditBoxByIndex (index : integer) : IAutomationEditBox;
/// <summary>
/// Finds the combobox, by index
/// </summary>
function GetComboboxByIndex (index : integer) : IAutomationComboBox;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetCheckboxByIndex (index : integer) : IAutomationCheckBox;
/// <summary>
/// Finds the checkbox, by index
/// </summary>
function GetRadioButtonByIndex (index : integer) : IAutomationRadioButton;
/// <summary>
/// Finds the button with the title supplied
/// </summary>
function GetButton (const title : string) : IAutomationButton;
/// <summary>
/// Gets the currently selected item
/// </summary>
property SelectedItem : IAutomationTabItem read GetSelectedItem;
end;
implementation
end.

View File

@ -0,0 +1,169 @@
{***************************************************************************}
{ }
{ DelphiUIAutomation }
{ }
{ Copyright 2015 JHC Systems Limited }
{ }
{***************************************************************************}
{ }
{ Licensed under the Apache License, Version 2.0 (the "License"); }
{ you may not use this file except in compliance with the License. }
{ You may obtain a copy of the License at }
{ }
{ http://www.apache.org/licenses/LICENSE-2.0 }
{ }
{ Unless required by applicable law or agreed to in writing, software }
{ distributed under the License is distributed on an "AS IS" BASIS, }
{ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{ See the License for the specific language governing permissions and }
{ limitations under the License. }
{ }
{***************************************************************************}
unit DelphiUIAutomation.Tab;
interface
uses
Generics.Collections,
DelphiUIAutomation.Container,
DelphiUIAutomation.TabItem,
DelphiUIAutomation.Textbox,
DelphiUIAutomation.Tab.Intf,
UIAutomationClient_TLB;
type
/// <summary>
/// Represents a tab control
/// </summary>
/// <remarks>
/// TPageControl for example
/// </remarks>
TAutomationTab = class (TAutomationContainer, IAutomationTab)
strict private
FSelectionPattern : IUIAutomationSelectionPattern;
FTabItems : TObjectList<TAutomationTabItem>;
// FSelectedItem : TAutomationTabItem;
private
function GetSelectedItem: IAutomationTabItem;
public
/// <summary>
/// Creates the representation
/// </summary>
constructor Create(element : IUIAutomationElement); override;
/// <summary>
/// Destructor for the representation.
/// </summary>
destructor Destroy; override;
///<summary>
/// Selects the given tab
///</summary>
procedure SelectTabPage(const value : string);
///<summary>
/// Gets the list of tabitems associated with this tab
///</summary>
property Pages : TObjectList<TAutomationTabItem> read FTabItems;
/// <summary>
/// Gets the currently selected item
/// </summary>
property SelectedItem : IAutomationTabItem read GetSelectedItem;
end;
implementation
uses
types,
DelphiUIAutomation.Mouse,
DelphiUIAutomation.Automation,
DelphiUIAutomation.ControlTypeIDs,
DelphiUIAutomation.PatternIDs;
{ TAutomationTab }
constructor TAutomationTab.Create(element: IUIAutomationElement);
var
collection : IUIAutomationElementArray;
count : integer;
retval : integer;
length : integer;
begin
inherited Create(element);
FSelectionPattern := GetSelectionPattern;
FTabItems := TObjectList<TAutomationTabItem>.create;
// Find the element
collection := self.FindAll(TreeScope_Descendants);
collection.Get_Length(length);
for count := 0 to length -1 do
begin
collection.GetElement(count, element);
element.Get_CurrentControlType(retVal);
if (retval = UIA_TabItemControlTypeId) then
begin
FTabItems.Add(TAutomationTabItem.create(element));
end;
end;
end;
destructor TAutomationTab.Destroy;
begin
FTabItems.free;
inherited;
end;
function TAutomationTab.GetSelectedItem: IAutomationTabItem;
var
unknown: IInterface;
Pattern : IUIAutomationSelectionPattern;
collection : IUIAutomationElementArray;
element : IUIAutomationElement;
length : integer;
begin
fElement.GetCurrentPattern(UIA_SelectionPatternId, unknown);
result := nil;
if (unknown <> nil) then
begin
if unknown.QueryInterface(IID_IUIAutomationSelectionPattern, Pattern) = S_OK then
begin
Pattern.GetCurrentSelection(collection);
collection.Get_Length(length);
// In this case it should be one entry only
collection.GetElement(0, element);
result := TAutomationTabItem.Create(element);
end;
end;
end;
procedure TAutomationTab.SelectTabPage(const value: string);
var
count : integer;
begin
for count := 0 to self.FTabItems.Count -1 do
begin
if self.FTabItems[count].Name = value then
begin
self.FTabItems[count].Select;
// FSelectedItem := self.FTabItems[count];
break;
end;
end;
end;
end.

Some files were not shown because too many files have changed in this diff Show More