Leaderboard
Popular Content
Showing content with the highest reputation on 01/20/2016 in all areas
-
Problem: well, you know how when your total path length exceeds 256 characters, bad things start to happen, right? Solution: somewhere in the Developer Chat forum, i suggested that long paths should be supported natively by AutoIt. this is progressing leisurely, and until completed, i re-wrote most of AutoIt core file management functions to support long paths. the concept is to call the unicode versions of the file management functions in kernel32.dll, and use the unicode prefix \\?\ or \\?\UNC\ where needed. in addition it requires some preparation steps, like creating directory structure, listing files to support wildcards, etc. this UDF was created because i needed a convenient way to make my existing scripts support long paths. so basically, the use of every LFN function is identical to the use of its native equivalent (same parameters and return values). for example, use _LFN_DirCreate() instead of DirCreate(). that's it. it works exactly the same, except when it comes to too long paths; it this case the LFN functions work where the native AutoIt functions fail. Note #1: you do not need to specify the unicode prefix. the UDF functions take care of that. this works: _LFN_DirCreate("C:\some\ridiculously\long\path\over\260\characters") you don't need this: _LFN_DirCreate("\\?\C:\some\ridiculously\long\path\over\260\characters") Note #2: _LFN_FileCopy lost its unique flags, and is now utilizing the native function FileCopy. Demonstration: hereunder, as well as the UDF, is a demo script of all of this UDF main functions. download the UDF itself (name it "LFN.au3") and the demo script to the same folder, and run the script. note that after each command the script pauses with a MsgBox, so you can review the results of the operation. do feel free to extend the demo script with more flags combinations. it creates long paths in C:\TEMP\LFN, so it won't be too hard to cleanup later once you are done with your tests. tested on file systems: fixed NTFS, removable NTFS, network ext4 Status: testing phase is complete. this UDF is now in production. enjoy! Latest Updates (release notes): post #39 - UDF v5.2 and demo script post #38 - script converter the script converter is GUI-based, with a clear display of the conversion: original/converted lines displayed side-by-side, tooltip to show the context of the converted lines showing 10 lines before and after: also the icon for the LFN conversion script, if you wish to compile: LFN_Script_Converter_NG.ico hope you appreciate the icon design : Downloads: the UDF: #include-Once ; #INDEX# ======================================================================================================================= ; Title .........: LFN ; AutoIt Version : 3.3.14.2 ; UDF Version ...: 5.2 ; Status ........: Production ; Language ......: English ; Description ...: Standard file management functions rewritten to overcome the MAX_PATH limitation of 256 characters by: ; - prepending the unicode prefix \\?\ or \\?\UNC\ where needed ; - calling kernel32 DLL with the unicode versions of the relevant functions ; - validating directory structure before calling the DLL ; - applying wildcards where not supported by the DLL ; - full compliance of parameters and return values with the equivalent native AutoIt functions: ; -- there may be additional use of @extended or @error when required ; -- there may be additional values that existing parameters can accept ; This UDF was created because: ; - not all of the above conditions are met by the WinAPIEx UDF ; - there was a need for convenient way to make existing scripts support long file names ; Native AutoIt functions that did not find their place in this UDF: ; FileChangeDir - couldn't get it to work. ; FileCreateNTFSLink - not sure what it is and what it does. ; FileCreateShortcut - couldn't get it to work. ; FileGetShortcut - couldn't get FileCreateShortcut to work, so didn't proceed here. ; FileInstall - couldn't get it to work. ; FileOpenDialog - couldn't get it to work with init dir in too long path; but it does set @WorkingDir! ; FileRecycle - not applicable: too long paths can not be put to recycle bin anyway. ; FileRecycleEmpty - not applicable: too long paths can not be put to recycle bin anyway. ; FileSaveDialog - couldn't get it to work with init dir in too long path; but it does set @WorkingDir! ; FileSelectFolder - seems to work as is. ; How To use this UDF: ; - for new scripts: as usual, include this UDF in your script and use its functions. ; - for existing scripts: use the conversion script (downloadable from the AutoIt forum). The conversion will ; replace the native functions calls with their LFN equivalents, and add an #include statement for this UDF ; just after your last #include statement (or at the top of your script if you have no #include statements). ; There is no need to change anything in the parameters or return values. ; Remark on the _LFN_Ini* functions: ; - comments (any text following a semicolon) are preserved. Comment following a Key=Value line are considered ; as part of the value string. ; Dll ...........: kernel32.dll ; Author(s) .....: orbs ; Resources .....: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx ; http://www.geoffchappell.com/studies/windows/win32/kernel32/api/ ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;_LFN_DirCopy ;_LFN_DirCreate ;_LFN_DirGetSize ;_LFN_DirMove ;_LFN_DirRemove ;_LFN_FileClose ;_LFN_FileCopy ;_LFN_FileDelete ;_LFN_FileExists ;_LFN_FileFindFirstFile ;_LFN_FileFindNextFile ;_LFN_FileFlush ;_LFN_FileGetAttrib ;_LFN_FileGetEncoding ;_LFN_FileGetLongName ;_LFN_FileGetPos ;_LFN_FileGetShortName ;_LFN_FileGetSize ;_LFN_FileGetTime ;_LFN_FileGetVersion ;_LFN_FileMove ;_LFN_FileOpen ;_LFN_FileRead ;_LFN_FileReadLine ;_LFN_FileReadToArray ;_LFN_FileSetAttrib ;_LFN_FileSetEnd ;_LFN_FileSetPos ;_LFN_FileSetTime ;_LFN_FileWrite ;_LFN_FileWriteLine ;_LFN_IniDelete ;_LFN_IniRead ;_LFN_IniReadSection ;_LFN_IniReadSectionNames ;_LFN_IniRenameSection ;_LFN_IniWrite ;_LFN_IniWriteSection ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirCopy ; Description ...: Copies a directory and all sub-directories and files. ; Syntax.........: _LFN_DirCopy($sSrcPath, $sDstPath[, $iFlag = 0]) ; Parameters ....: $sSrcPath - Path of the source directory (with no trailing backslash). e.g. "C:\Path1" ; $sDstPath - Path of the destination directory (with no trailing backslash). e.g. "C:\Path_Copy" ; $iFlag - [optional] This flag determines whether to overwrite files if they already exist: ; $FC_NOOVERWRITE (0) = (default) do not overwrite existing files ; $FC_OVERWRITE (1) = overwrite existing files ; Constants are defined in FileConstants.au3 ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the destination directory structure doesn't exist, it will be created (if possible). This means that flag 8 ; is assumed, and needs not be specified. ; Overwrite is determined per file, and complies with flag combination. ; NOTE: DirCopy('D:\dir','C:\') will fail, but _LFN_DirCopy('D:\dir','C:\') will succeed. Make of it whatever ; suits you. ; Related .......: ; Dependencies ..: _LFN_DirCreate, _LFN_FileCopy ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_DirCopy($sSrcPath, $sDstPath, $iFlag = 0) ; preparation $sSrcPath = __LFN_Target_RemoveTrailingBackslash($sSrcPath) $sDstPath = __LFN_Target_RemoveTrailingBackslash($sDstPath) If Not __LFN_Target_IsExistingFolder($sSrcPath) Then Return SetError(1, 0, 0) _LFN_DirCreate($sDstPath) ; main action Local $aFiles = __LFN_FilesListToArray($sSrcPath & '\*') Local $i Local $bOneFail = False For $i = 1 To $aFiles[0] If StringRight($aFiles[$i], 1) = '\' Then _LFN_DirCreate($sDstPath & '\' & __LFN_Target_LastElement_Get(StringTrimRight($aFiles[$i], 1))) If Not _LFN_DirCopy($aFiles[$i], $sDstPath & '\' & __LFN_Target_LastElement_Get(StringTrimRight($aFiles[$i], 1)), $iFlag) Then $bOneFail = True Else If Not _LFN_FileCopy($aFiles[$i], $sDstPath & '\', BitOR($iFlag, 8)) Then $bOneFail = True EndIf Next If $bOneFail Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_DirCopy ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirCreate ; Description ...: Creates a directory. ; Syntax.........: _LFN_DirCreate($sPath) ; Parameters ....: $sPath - Full path of the directory to create. ; Return values .: Success - Returns 1 ; Failure - Returns 0, sets @error to 1, and sets @extended to the @error returned from DllCall ; Author ........: orbs ; Modified ......: ; Remarks .......: This function will also create all parent directories given in $sPath if they do not already exist. ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirCreate($sPath) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) Local $nFirstElement = 7 ; assuming local drive Local $nNthFound = 0 Local $i $sPath = __LFN_Target_SetUnicodePrefix($sPath) If @extended = 2 Then ; assumption incorrect, it's a UNC path $nFirstElement = 0 For $i = 1 To StringLen($sPath) If StringMid($sPath, $i, 1) = '\' Then $nNthFound += 1 If $nNthFound = 6 Then $nFirstElement = $i EndIf Next EndIf ; main action For $i = $nFirstElement To StringLen($sPath) If StringMid($sPath, $i, 1) = '\' Then DllCall($hDLL, 'bool', 'CreateDirectoryW', 'wstr', StringLeft($sPath, $i), 'struct*', 0) EndIf Next DllCall($hDLL, 'bool', 'CreateDirectoryW', 'wstr', $sPath, 'struct*', 0) If __LFN_Target_IsExistingFolder($sPath) Then Return 1 Return 0 EndFunc ;==>_LFN_DirCreate ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirGetSize ; Description ...: Use exactly like the native AutoIt function DirGetSize ; Syntax.........: _LFN_DirGetSize($sPath[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_DirGetSize($sPath, $iFlag = 0) $sPath = __LFN_Target_SetUnicodePrefix($sPath) Local $result = DirGetSize($sPath, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_DirGetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirMove ; Description ...: Moves a directory and all sub-directories and files. ; Syntax.........: _LFN_DirMove($sSrcPath, $sDstPath[, $iFlag = 0]) ; Parameters ....: $sSrcPath - Path of the source directory (with no trailing backslash). e.g. "C:\Path1" ; $sDstPath - Path of the destination directory (with no trailing backslash). e.g. "C:\Path_Copy" ; $iFlag - [optional] This flag determines whether to overwrite files if they already exist: ; $FC_NOOVERWRITE (0) = (default) do not overwrite existing files ; $FC_OVERWRITE (1) = overwrite existing files ; Constants are defined in FileConstants.au3 ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: - If the source and destination are on different volumes or UNC paths are used, then a copy+delete operation ; is performed rather than a move. If the 'copy' or 'delete' fails, then depending on the reason of failure, ; there may remain some files either in the source or destination, where not expected. ; - If the destination already exists and the overwrite flag IS specified, then the source directory will be ; moved inside the destination. If a subfolder of the destination folder already exists by the name of the ; source folder, then source files will overwrite destination files if exist. ; - If the destination already exists and the overwrite flag IS NOT specified, the operation fails. ; - Because AutoIt lacks a "_LFN_DirRename" function, use _LFN_DirMove to rename a folder! ; Related .......: ; Dependencies ..: _LFN_FileDelete, _LFN_DirCopy, _LFN_DirRemove ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirMove($sSrcPath, $sDstPath, $iFlag = 0) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation $sSrcPath = __LFN_Target_RemoveTrailingBackslash($sSrcPath) $sDstPath = __LFN_Target_RemoveTrailingBackslash($sDstPath) If Not __LFN_Target_IsExistingFolder($sSrcPath) Then Return SetError(1, 0, 0) If __LFN_FilesExist($sDstPath) Then Switch @extended Case 1 ; file If $iFlag Then ; overwrite => delete file _LFN_FileDelete($sSrcPath) Else Return SetError(1, 0, 0) ; fail EndIf Case 3 ; folder If $iFlag Then ; overwrite => move inside $sDstPath = $sDstPath & '\' & __LFN_Target_LastElement_Get($sSrcPath) Else Return SetError(1, 0, 0) ; fail EndIf EndSwitch EndIf ; main action Local $aRet = DllCall($hDLL, 'bool', 'MoveFileExW', 'wstr', __LFN_Target_SetUnicodePrefix($sSrcPath), 'wstr', __LFN_Target_SetUnicodePrefix($sDstPath), 'dword', 2 + $iFlag) If $aRet[0] = 0 Then If _LFN_DirCopy($sSrcPath, $sDstPath, $iFlag) Then _LFN_DirRemove($sSrcPath, 3) Else Return SetError(1, 0, 0) EndIf EndIf Return 1 EndFunc ;==>_LFN_DirMove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirRemove ; Description ...: Deletes a directory. ; Syntax.........: _LFN_DirRemove($sPath[, $iFlag = 0]) ; Parameters ....: $sPath - Full path of the directory to remove. ; $iFlag - [optional] This flag is a combination of the following values: ; 1 = recurse subfolders ; 2 = clear the Read-only and System attributes to force removal ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: _LFN_FileSetAttrib, _LFN_FileDelete ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirRemove($sPath, $iFlag = 0) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) $sPath = __LFN_Target_SetUnicodePrefix($sPath) If Not __LFN_Target_IsExistingFolder($sPath) Then Return SetError(1, 0, 0) ; main action If BitAND($iFlag, 1) Then Local $aFiles = __LFN_FilesListToArray($sPath, BitAND($iFlag, 1)) Local $i, $aRet For $i = $aFiles[0] To 1 Step -1 If StringRight($aFiles[$i], 1) = '\' Then If BitAND($iFlag, 2) Then _LFN_FileSetAttrib($aFiles[$i], '-RS') $aRet = DllCall($hDLL, 'bool', 'RemoveDirectoryW', 'wstr', StringTrimRight($aFiles[$i], 1)) If $aRet[0] = 0 Then Return SetError(1, @error, 0) Else If BitAND($iFlag, 2) Then _LFN_FileSetAttrib($aFiles[$i], '-RS') _LFN_FileDelete($aFiles[$i]) EndIf Next EndIf $aRet = DllCall($hDLL, 'bool', 'RemoveDirectoryW', 'wstr', $sPath) If @error Then Return SetError(1, @error, 0) If FileExists($sPath) Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_DirRemove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileClose ; Description ...: Use exactly like the native AutoIt function FileClose ; Syntax.........: _LFN_FileClose($hFile) ; =============================================================================================================================== Func _LFN_FileClose($hFile) Local $result = FileClose($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileClose ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileCopy ; Description ...: Use exactly like the native AutoIt function FileCopy ; Syntax ........: _LFN_FileCopy($sSrc, $sDst[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileCopy($sSrc, $sDst, $iFlag = 0) $sSrc = __LFN_Target_SetUnicodePrefix($sSrc) $sDst = __LFN_Target_SetUnicodePrefix($sDst) Local $result = FileCopy($sSrc, $sDst, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileCopy ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileDelete ; Description ...: Use exactly like the native AutoIt function FileDelete ; Syntax.........: _LFN_FileDelete($sMask) ; =============================================================================================================================== Func _LFN_FileDelete($sMask) $sMask = __LFN_Target_SetUnicodePrefix($sMask) Local $result = FileDelete($sMask) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileDelete ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileExists ; Description ...: Use exactly like the native AutoIt function FileExists ; Syntax.........: _LFN_FileExists($sFile) ; =============================================================================================================================== Func _LFN_FileExists($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileExists($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileExists ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFindFirstFile ; Description ...: Use exactly like the native AutoIt function FileFindFirstFile ; Syntax.........: _LFN_FileFindFirstFile($sFile) ; =============================================================================================================================== Func _LFN_FileFindFirstFile($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileFindFirstFile($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFindFirstFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFindNextFile ; Description ...: Use exactly like the native AutoIt function FileFindNextFile ; Syntax.........: _LFN_FileFindNextFile($hSearch) ; =============================================================================================================================== Func _LFN_FileFindNextFile($hSearch) Local $result = FileFindNextFile($hSearch) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFindNextFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFlush ; Description ...: Use exactly like the native AutoIt function FileFlush ; Syntax.........: _LFN_FileFlush($hFile) ; =============================================================================================================================== Func _LFN_FileFlush($hFile) Local $result = FileFlush($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFlush ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetAttrib ; Description ...: Use exactly like the native AutoIt function FileGetAttrib ; Syntax.........: _LFN_FileGetAttrib($sTarget) ; =============================================================================================================================== Func _LFN_FileGetAttrib($sTarget) $sTarget = __LFN_Target_SetUnicodePrefix($sTarget) Local $result = FileGetAttrib($sTarget) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetAttrib ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetEncoding ; Description ...: Use exactly like the native AutoIt function FileGetEncoding ; Syntax.........: _LFN_FileGetEncoding($xFile[, $nMode = 1]) ; =============================================================================================================================== Func _LFN_FileGetEncoding($xFile, $nMode = 1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileGetEncoding($xFile, $nMode) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetEncoding ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetLongName ; Description ...: Returns the long path+name of the path+name passed. ; Syntax.........: _LFN_FileGetLongName($sFile[, $iFlag = 0]) ; Parameters ....: $sFile - Full path and file name to convert ; $iFlag - [optional] if 1 file can have relative dir, e.g. "..\file.txt" ; Return values .: Success - Returns the long path+name of the path+name passed. ; Failure - Returns the parameter and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx ; http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_FileGetLongName($sFile, $iFlag = 0) Local $aRet Local $sFileFullPath If $iFlag Then $aRet = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', __LFN_Target_SetUnicodePrefix($sFile), 'dword', 4096, 'wstr', '', 'ptr', 0) If @error Or Not $aRet[0] Then $sFileFullPath = $sFile $sFileFullPath = $aRet[3] Else $sFileFullPath = $sFile EndIf $aRet = DllCall('kernel32.dll', 'dword', 'GetLongPathNameW', _ 'wstr', __LFN_Target_SetUnicodePrefix($sFileFullPath), _ 'wstr', '', _ 'dword', 65536) If $aRet[0] = 0 Then Return SetError(1, $sFile) Return __LFN_Target_UnSetUnicodePrefix($aRet[2]) EndFunc ;==>_LFN_FileGetLongName ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetPos ; Description ...: Use exactly like the native AutoIt function FileGetPos ; Syntax.........: _LFN_FileGetPos($hFile) ; =============================================================================================================================== Func _LFN_FileGetPos($hFile) Local $result = FileGetPos($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetPos ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetSize ; Description ...: Use exactly like the native AutoIt function FileGetSize ; Syntax.........: _LFN_FileGetSize($sFile) ; =============================================================================================================================== Func _LFN_FileGetSize($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetSize($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetShortName ; Description ...: Use exactly like the native AutoIt function FileGetShortName ; Syntax.........: _LFN_FileGetShortName($sFile[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileGetShortName($sFile, $iFlag = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetShortName($sFile, $iFlag) Local $nError = @error Local $nExtended = @extended $result = __LFN_Target_UnSetUnicodePrefix($result) ; the result is a short name, therefore must not have the unicode prefix. Return SetError($nError, $nExtended, $result) EndFunc ;==>_LFN_FileGetShortName ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetTime ; Description ...: Use exactly like the native AutoIt function FileGetTime ; Syntax.........: _LFN_FileGetTime($sFile[, $nOption = 0[, $nFormat = 0]]) ; =============================================================================================================================== Func _LFN_FileGetTime($sFile, $nOption = 0, $nFormat = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetTime($sFile, $nOption, $nFormat) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetTime ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetVersion ; Description ...: Use exactly like the native AutoIt function FileGetVersion ; Syntax.........: _LFN_FileGetVersion($sFile[, $sField = -1]) ; =============================================================================================================================== Func _LFN_FileGetVersion($sFile, $sField = -1) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $sResult If $sField = -1 Then $sResult = FileGetVersion($sFile) Return SetError(@error, @extended, $sResult) Else $sResult = FileGetVersion($sFile, $sField) Return SetError(@error, @extended, $sResult) EndIf EndFunc ;==>_LFN_FileGetVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileMove ; Description ...: Use exactly like the native AutoIt function FileMove ; Syntax ........: _LFN_FileMove($sSrc, $sDst[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileMove($sSrc, $sDst, $iFlag = 0) $sSrc = __LFN_Target_SetUnicodePrefix($sSrc) $sDst = __LFN_Target_SetUnicodePrefix($sDst) Local $result = FileMove($sSrc, $sDst, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileMove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileOpen ; Description ...: Use exactly like the native AutoIt function FileOpen ; Syntax.........: _LFN_FileOpen($sFile[, $nMode = 0]) ; =============================================================================================================================== Func _LFN_FileOpen($sFile, $nMode = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileOpen($sFile, $nMode) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileOpen ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileRead ; Description ...: Use exactly like the native AutoIt function FileRead ; Syntax.........: _LFN_FileRead($xFile[, $nCount = -1]) ; =============================================================================================================================== Func _LFN_FileRead($xFile, $nCount = -1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result If $nCount < 0 Then $result = FileRead($xFile) Else $result = FileRead($xFile, $nCount) EndIf Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileRead ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileReadLine ; Description ...: Use exactly like the native AutoIt function FileReadLine ; Syntax.........: _LFN_FileReadLine($xFile[, $nLine = 1]) ; =============================================================================================================================== Func _LFN_FileReadLine($xFile, $nLine = 1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result If $nLine = 1 Then $result = FileReadLine($xFile) Else $result = FileReadLine($xFile, $nLine) EndIf Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileReadLine ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileReadToArray ; Description ...: Use exactly like the native AutoIt function FileReadToArray ; Syntax.........: _LFN_FileReadToArray($xFile) ; =============================================================================================================================== Func _LFN_FileReadToArray($xFile) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileReadToArray($xFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileReadToArray ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetAttrib ; Description ...: Sets or clears attributes of one or more files/directories. ; Syntax.........: _LFN_FileSetAttrib($sTarget, $sAttrib[, $bRecurse = False]) ; Parameters ....: Target - Full path of file(s) to set attributes for (wildcards supported). ; $sAttrib - A string representation of the attributes to set or clear - see Remarks. ; $bRecurse - [optional] Set to True if to recurse subdirectories. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error: ; 1 - Error opening the kernel32 DLL. ; 2 - The attributes parameter includes an invalid attribute - see Remarks. ; 3 - deprecated (used to be "No files found", but this is not an error, but a legitimate result). ; 4 - At least one file could not have its attributes changed. ; Author ........: orbs ; Modified ......: ; Remarks .......: - The attributes that can be modified with the function are + or -: ; "R" = READONLY ; "A" = ARCHIVE ; "S" = SYSTEM ; "H" = HIDDEN ; "N" = NORMAL ; "O" = OFFLINE ; "T" = TEMPORARY ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/aa365535(v=vs.85).aspx ; http://msdn.microsoft.com/en-us/library/gg258117(v=vs.85).aspx ; http://stackoverflow.com/questions/12594403/fasm-if-file-exists-using-getfileattributes-invalid-file-attributes-value ; Example .......: No ; =============================================================================================================================== Func _LFN_FileSetAttrib($sTarget, $sAttrib, $bRecurse = False) ; reversion If Not __LFN_Target_IsMask($sTarget) And _ ; target is a single file or folder StringLen($sTarget) < 260 And _ ; target is short Not $bRecurse Then _ ; no recurse (recurse may breach MAX_PATH limit) Return FileSetAttrib($sTarget, $sAttrib, $bRecurse) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation Local Const $_LFN_FILE_ATTRIBUTE_ARCHIVE = 32 ;(0x20) Local Const $_LFN_FILE_ATTRIBUTE_COMPRESSED = 2048 ;(0x800) Local Const $_LFN_FILE_ATTRIBUTE_DEVICE = 64 ;(0x40) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_DIRECTORY = 16 ;(0x10) Local Const $_LFN_FILE_ATTRIBUTE_ENCRYPTED = 16384 ;(0x4000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_HIDDEN = 2 ;(0x2) Local Const $_LFN_FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 ;(0x8000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_NORMAL = 128 ;(0x80) Local Const $_LFN_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 ;(0x2000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 ;(0x20000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_OFFLINE = 4096 ;(0x1000) Local Const $_LFN_FILE_ATTRIBUTE_READONLY = 1 ;(0x1) Local Const $_LFN_FILE_ATTRIBUTE_REPARSE_POINT = 1024 ;(0x400) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_SPARSE_FILE = 512 ;(0x200) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_SYSTEM = 4 ;(0x4) Local Const $_LFN_FILE_ATTRIBUTE_TEMPORARY = 256 ;(0x100) Local Const $_LFN_FILE_ATTRIBUTE_VIRTUAL = 65536 ;(0x10000) ; not used here Local $aAttributes[18][2] = [[0, 0], _ [$_LFN_FILE_ATTRIBUTE_ARCHIVE, 'A'], _ [$_LFN_FILE_ATTRIBUTE_COMPRESSED, 'C'], _ [$_LFN_FILE_ATTRIBUTE_DEVICE, ''], _ [$_LFN_FILE_ATTRIBUTE_DIRECTORY, 'D'], _ [$_LFN_FILE_ATTRIBUTE_ENCRYPTED, ''], _ [$_LFN_FILE_ATTRIBUTE_HIDDEN, 'H'], _ [$_LFN_FILE_ATTRIBUTE_INTEGRITY_STREAM, ''], _ [$_LFN_FILE_ATTRIBUTE_NORMAL, 'N'], _ [$_LFN_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, ''], _ [$_LFN_FILE_ATTRIBUTE_NO_SCRUB_DATA, ''], _ [$_LFN_FILE_ATTRIBUTE_OFFLINE, 'O'], _ [$_LFN_FILE_ATTRIBUTE_READONLY, 'R'], _ [$_LFN_FILE_ATTRIBUTE_REPARSE_POINT, ''], _ [$_LFN_FILE_ATTRIBUTE_SPARSE_FILE, ''], _ [$_LFN_FILE_ATTRIBUTE_SYSTEM, 'S'], _ [$_LFN_FILE_ATTRIBUTE_TEMPORARY, 'T'], _ [$_LFN_FILE_ATTRIBUTE_VIRTUAL, '']] Local Const $_LFN_INVALID_FILE_ATTRIBUTES = 4294967295 ;(0xFFFFFFFF, also equals -1 for unsigned DWORD) Local $bAttribToSet = True Local $nAttribToSet = 0 Local $nAttribToClear = 0 Local $i, $j For $i = 1 To StringLen($sAttrib) Switch StringUpper(StringMid($sAttrib, $i, 1)) Case '+' $bAttribToSet = True Case '-' $bAttribToSet = False Case 'R', 'A', 'S', 'H', 'N', 'O', 'T' For $j = 1 To UBound($aAttributes) - 1 If $aAttributes[$j][1] = StringUpper(StringMid($sAttrib, $i, 1)) Then If $bAttribToSet Then $nAttribToSet = BitOR($nAttribToSet, $aAttributes[$j][0]) Else $nAttribToClear = BitOR($nAttribToClear, $aAttributes[$j][0]) EndIf EndIf Next Case Else Return SetError(2, 0, 0) EndSwitch Next ; main action Local $aFiles[2] = [1, $sTarget] If Not __LFN_Target_IsExistingFolder($sTarget) Or $bRecurse Then $aFiles = __LFN_FilesListToArray($sTarget, $bRecurse) If __LFN_Target_IsExistingFolder($sTarget) And $bRecurse Then __LFN_ReDim($aFiles, $sTarget & '\') Local $bOneFail = False Local $sOneName = '' Local $aRet, $nAttribToChange For $i = $aFiles[0] To 1 Step -1 $sOneName = $aFiles[$i] If StringRight($sOneName, 1) = '\' Then $sOneName = StringTrimRight($sOneName, 1) $aRet = DllCall($hDLL, 'dword', 'GetFileAttributesW', 'wstr', $sOneName) If @error Or $aRet[0] = $_LFN_INVALID_FILE_ATTRIBUTES Then $bOneFail = True ContinueLoop EndIf $nAttribToChange = $aRet[0] $nAttribToChange = BitOR($nAttribToChange, $nAttribToSet) $nAttribToChange = BitAND($nAttribToChange, BitNOT($nAttribToClear)) If $nAttribToChange = $aRet[0] Then ContinueLoop ; no need to change $aRet = DllCall($hDLL, 'int', 'SetFileAttributesW', 'wstr', $sOneName, 'dword', $nAttribToChange) If @error Or $aRet[0] = 0 Then $bOneFail = True ContinueLoop EndIf Next If $bOneFail Then Return SetError(4, 0, 0) Return 1 EndFunc ;==>_LFN_FileSetAttrib ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetPos ; Description ...: Use exactly like the native AutoIt function FileSetPos ; Syntax.........: _LFN_FileSetPos($hFile, $nOffset, $nOrigin) ; =============================================================================================================================== Func _LFN_FileSetPos($hFile, $nOffset, $nOrigin) Local $result = FileSetPos($hFile, $nOffset, $nOrigin) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileSetPos ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetEnd ; Description ...: Use exactly like the native AutoIt function FileSetEnd ; Syntax.........: _LFN_FileSetEnd($hFile) ; =============================================================================================================================== Func _LFN_FileSetEnd($hFile) Local $result = FileSetEnd($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileSetEnd ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetTime ; Description ...: Sets the timestamp of one of more files. ; Syntax.........: _LFN_FileSetTime($sTarget, $sTimestamp[, $nType = 0[, $bRecurse = False]]) ; Parameters ....: Target - Full path of file(s) to set timestamp for (wildcards supported). ; $sTimestamp - A string which denotes the new time to set. ; format: "YYYYMMDDhhmmss" (Year, Month, Day, hour (24hr clock), minute, second). ; If an empty string is passed, then the current time is used. ; $nType - [optional] Timestamp to change: ; $FT_MODIFIED (0) = Last modified (default) ; $FT_CREATED (1) = Created ; $FT_ACCESSED (2) = Last accessed ; Constants are defined in FileConstants.au3 ; $bRecurse - [optional] Set to True if to recurse subdirectories. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: Using a date earlier than 1980-01-01 will have no effect. ; Trying to change a timestamp on read-only files will result in an error. ; This function fails in the following conditions: ; - Invalid timestamp: string is not all integer or not exactly 14 characters in length ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_FileSetTime($sTarget, $sTimestamp, $nType = 0, $bRecurse = False) ; reversion If Not __LFN_Target_IsMask($sTarget) And _ ; target is a single file or folder StringLen($sTarget) < 260 And _ ; target is short Not $bRecurse Then _ ; no recurse (recurse may breach MAX_PATH limit) Return FileSetTime($sTarget, $sTimestamp, $nType, $bRecurse) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation If Not __LFN_FilesExist($sTarget) Then Return SetError(1, 0, 0) If Not StringIsInt($sTimestamp) Or StringLen($sTimestamp) <> 14 Then Return SetError(1, 0, 0) ; - parse parameter Local $sYYYY = StringLeft($sTimestamp, 4) Local $sMM = StringMid($sTimestamp, 5, 2) Local $sDD = StringMid($sTimestamp, 7, 2) Local $sHH = StringMid($sTimestamp, 9, 2) Local $sMN = StringMid($sTimestamp, 11, 2) Local $sSS = StringMid($sTimestamp, 13, 2) ; - enclode time to "System" time format ; = _Date_Time_EncodeSystemTime Local Const $_LFN_tagSYSTEMTIME = 'struct;word Year;word Month;word Dow;word Day;word Hour;word Minute;word Second;word MSeconds;endstruct' Local $tSystemTime_File = DllStructCreate($_LFN_tagSYSTEMTIME) DllStructSetData($tSystemTime_File, 'Month', Number($sMM)) DllStructSetData($tSystemTime_File, 'Day', Number($sDD)) DllStructSetData($tSystemTime_File, 'Year', Number($sYYYY)) DllStructSetData($tSystemTime_File, 'Hour', Number($sHH)) DllStructSetData($tSystemTime_File, 'Minute', Number($sMN)) DllStructSetData($tSystemTime_File, 'Second', Number($sSS)) DllStructSetData($tSystemTime_File, 'MSeconds', 0) ; - convert "System" time format to "UTC System" time format ; = _Date_Time_TzSpecificLocalTimeToSystemTime Local $aRet Local $tUTC = DllStructCreate($_LFN_tagSYSTEMTIME) $aRet = DllCall("kernel32.dll", "ptr", "TzSpecificLocalTimeToSystemTime", "ptr", 0, "ptr", DllStructGetPtr($tSystemTime_File), "struct*", $tUTC) If @error Then Return SetError(1, 0, 0) ; - convert "System" time format to "File" time format ; = _Date_Time_SystemTimeToFileTime Local Const $_LFN_tagFILETIME = 'struct;dword Lo;dword Hi;endstruct' Local $tFileTime_File = DllStructCreate($_LFN_tagFILETIME) $aRet = DllCall($hDLL, 'bool', 'SystemTimeToFileTime', 'struct*', $tUTC, 'struct*', $tFileTime_File) If @error Then Return SetError(1, 0, 0) ; - decide which timestamp to change Local $pCreated = 0 Local $pAccessed = 0 Local $pModified = 0 Switch $nType Case 1 ; "Created" $pCreated = DllStructGetPtr($tFileTime_File) Case 2 ; "Accessed" $pAccessed = DllStructGetPtr($tFileTime_File) Case Else ; "Modified" $pModified = DllStructGetPtr($tFileTime_File) EndSwitch ; main action Local $aFiles = __LFN_FilesListToArray($sTarget, $bRecurse) If @extended = 0 Then Return SetError(1, 0, 0) ; no files found Local $hFile Local $bOneFail = False For $i = $aFiles[0] To 1 Step -1 If StringRight($aFiles[$i], 1) = '\' Then ContinueLoop ; it's a subfolder ; _WinAPI_CreateFile (does not equal FileOpen!) $aRet = DllCall($hDLL, 'handle', 'CreateFileW', 'wstr', $aFiles[$i], 'dword', 0x40000000, 'dword', 0, 'ptr', 0, 'dword', 3, 'dword', 0, 'ptr', 0) $hFile = $aRet[0] ; finally... $aRet = DllCall($hDLL, 'bool', 'SetFileTime', 'handle', $hFile, 'ptr', $pCreated, 'ptr', $pAccessed, 'ptr', $pModified) If $aRet[0] = 0 Then $bOneFail = True EndIf ;_WinAPI_CloseHandle (does not equal FileClose!) $aRet = DllCall($hDLL, 'bool', 'CloseHandle', 'handle', $hFile) Next If $bOneFail Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_FileSetTime ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileWrite ; Description ...: Use exactly like the native AutoIt function FileWrite ; Syntax.........: _LFN_FileWrite($xFile, $xData) ; =============================================================================================================================== Func _LFN_FileWrite($xFile, $xData) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileWrite($xFile, $xData) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileWrite ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileWriteLine ; Description ...: Use exactly like the native AutoIt function FileWriteLine ; Syntax.........: _LFN_FileWriteLine($xFile, $xData) ; =============================================================================================================================== Func _LFN_FileWriteLine($xFile, $xData) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileWriteLine($xFile, $xData) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileWriteLine ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniDelete ; Description ...: Deletes a value from a standard format .ini file. ; Syntax.........: _LFN_IniDelete($sFile, $sSection[, $sKey = '']) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - [optional] The key name in the .ini file to delete. If the key name is not given the entire ; section is deleted. The Default keyword may also be used which will cause the section to be deleted. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniDelete($sFile, $sSection, $sKey = '') If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True If $sKey = '' Then $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 EndIf Else If $bSectionFound Then ; entering next section If $sKey = '' Then $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf Else If $bSectionFound And $sKey <> '' Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then $iFirstLineToDelete = $i $iLastLineToDelete = $i EndIf EndIf EndIf Next Local $hFile Local $bError If $iFirstLineToDelete > -1 And $iLastLineToDelete >= $iFirstLineToDelete Then $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) Else Return SetError(1, 0, 0) EndIf Return 1 EndFunc ;==>_LFN_IniDelete ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniRead ; Description ...: Reads a value from a standard format .ini file. ; Syntax.........: _LFN_IniRead($sFile, $sSection, $sKey, $xDefaultValue) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - The key name in the .ini file. ; $xDefaultValue - The default value to return if the requested key is not found. ; Return values .: Success - Returns the requested key value as a string. ; Failure - Returns the default string if the requested key is not found or any error occured. ; Author ........: orbs ; Modified ......: ; Remarks .......: All values returned are converted as a string. ; A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniRead($sFile, $sSection, $sKey, $xDefaultValue) If Not _LFN_FileExists($sFile) Then Return $xDefaultValue Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return $xDefaultValue Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section, key not found Return $xDefaultValue ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then Return StringTrimLeft($aFileLines[$i], $iPos) EndIf EndIf Next Return $xDefaultValue EndFunc ;==>_LFN_IniRead ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniReadSection ; Description ...: Reads all key/value pairs from a section in a standard format .ini file. ; Syntax.........: _LFN_IniReadSection($sFile, $sSection) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; Return values .: Success - Returns a 2-D array where element[n][0] is the key and element[n][1] is the value. ; Failure - Returns 0 and sets the @error flag to non-zero if unable to read the section (The INI file may not ; exist or the section may not exist or is empty). ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; The number of elements returned will be in element[0][0]. If an @error occurs, no array is created. ; This function is not impacted by the 32kB limitation. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniReadSection($sFile, $sSection) If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $aResult[1][2] $aResult[0][0] = 0 Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop __LFN_ReDim2D($aResult) $aResult[$aResult[0][0]][0] = StringLeft($aFileLines[$i], $iPos - 1) $aResult[$aResult[0][0]][1] = StringTrimLeft($aFileLines[$i], $iPos) EndIf EndIf Next ReDim $aResult[$aResult[0][0] + 1][2] Return $aResult EndFunc ;==>_LFN_IniReadSection ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniReadSectionNames ; Description ...: Reads all sections in a standard format .ini file. ; Syntax.........: _LFN_IniReadSectionNames($sFile) ; Parameters ....: $sFile - The filename of the .ini file. ; Return values .: Success - Returns a 1-D array of all section names in the .ini file. ; Failure - Returns 0 and sets the @error flag to non-zero. ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; The number of elements returned will be in element[0]. If an @error occurs, no array is created. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniReadSectionNames($sFile) If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $aResult[1] = [0] For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then __LFN_ReDim($aResult, StringTrimRight(StringTrimLeft($aFileLines[$i], 1), 1)) Next If $aResult[0] = 0 Then Return SetError(1, 0, 0) ReDim $aResult[$aResult[0] + 1] Return $aResult EndFunc ;==>_LFN_IniReadSectionNames ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniRenameSection ; Description ...: Renames a section in a standard format .ini file. ; Syntax.........: _LFN_IniRenameSection($sFile, $sSection, $sNewSection[, $bOverwrite = False]) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section to be renamed. ; $sNewSection - The new name for the section. ; $bOverwrite - [optional] if a section already exists by the new name, set to True to overwrite it. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to non-zero. ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniRenameSection($sFile, $sSection, $sNewSection, $bOverwrite = False) If $sSection = $sNewSection Then Return 1 If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $bSectionFound = False Local $bNewSectionFound = False Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True If StringLeft($aFileLines[$i], StringLen($sNewSection) + 2) = '[' & $sNewSection & ']' Then $bNewSectionFound = True $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 Else If $bNewSectionFound Then ; entering next section $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf EndIf Next If Not $bSectionFound Then Return SetError(1, 0, 0) If $bNewSectionFound And Not $bOverwrite Then Return SetError(1, 0, 0) Local $hFile Local $bError $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $aFileLines[$i] = StringReplace($aFileLines[$i], $sSection, $sNewSection) _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniRenameSection ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniWrite ; Description ...: Writes a value to a standard format .ini file. ; Syntax.........: _LFN_IniWrite($sFile, $sSection, $sKey, $xValue) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - The key name in the .ini file. ; $xValue - The value to write/change. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error ro 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; - If the file does not already exist, it is created so long as the directory exists. Keys and/or sections are ; added to the end and are not sorted in any way. ; - If you would like to wrap quotes around an ini value, then you need to double up the quotation marks as the ; first set of quotation marks are stripped. For example: ""This is a test"" will produce "This is a test" ; when using IniRead() or such-like. ; - Leading and trailing whitespace is stripped. In order to preserve the whitespace, the string must be quoted. ; For example, " this is a test" will preserve the whitespace but per above, the quotation marks are stripped. ; - Multi-line values are not possible. ; - If you want to use an ini file with Unicode encoding, first create an .ini file by using the FileOpen() ; function with the mode parameter set to a Unicode parameter. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileWriteLine, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniWrite($sFile, $sSection, $sKey, $xValue) Local $sValue = String($xValue) $sValue = StringStripWS($sValue, 3) If StringLeft($sValue, 1) = '"' And StringRight($sValue, 1) = '"' Then $sValue = StringTrimLeft(StringTrimRight($sValue, 1), 1) If Not _LFN_FileExists($sFile) Then _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then Return SetError(1, 0, 0) _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then Return SetError(1, 0, 0) Return 1 EndIf Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $bToDo = -1 ; 0 = replace existing line, 1 = insert line in existing section, 2 = add new section, 3 = add new line at last section Local $bSectionFound = False Local $iLineToInsert = -1 Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section, key not found $iLineToInsert = $i $bToDo = 1 ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then $aFileLines[$i] = $sKey & '=' & $sValue $bToDo = 0 ExitLoop Else If $i = UBound($aFileLines) - 1 Then $bToDo = 3 EndIf EndIf EndIf Next If Not $bSectionFound Then $bToDo = 2 Local $bError = False Local $hFile Switch $bToDo Case 0 $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) Case 1 While $aFileLines[$iLineToInsert - 1] = '' $iLineToInsert -= 1 WEnd $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i = $iLineToInsert Then _LFN_FileWriteLine($hFile, $sKey & '=' & $sValue) If @error Then $bError = True ExitLoop EndIf EndIf _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) Case 2 _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then $bError = True _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then $bError = True Case 3 _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then $bError = True Case Else $bError = True EndSwitch If $bError Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniWrite ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniWriteSection ; Description ...: Writes a section to a standard format .ini file. ; Syntax.........: _LFN_IniWriteSection($sFile, $sSection, $xData[, $iFirstEntry = 1]) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $xData - The data to write. The data can either be a string or an array. If the data is a string, then ; each key=value pair must be delimited by @LF. If the data is an array, the array must be 2-D ; and the second dimension must be 2 elements. ; $iFirstEntry - [optional] If an array is passed as data, this specifies the index to start writing from. ; By default, this is 1 so that the return value of IniReadSection() can be used immediately. ; For manually created arrays, this value may need to be different depending on how the array was ; created. This parameter is ignored if a string is passed as data. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error ro 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; - _LFN_IniWrite Remarks about doubling quotation marks or quoting whitespace are irrelevant here. Data is ; written to the .ini file as is. ; - If the file does not already exist, it is created so long as the directory exists. Keys and/or sections are ; added to the end and are not sorted in any way. ; - If the section being written already exists, its contents will be overwritten. ; - If you want to use an ini file with Unicode encoding, first create an .ini file by using the FileOpen() ; function with the mode parameter set to a Unicode parameter. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniWriteSection($sFile, $sSection, $xData, $iFirstEntry = 1) Local $sData If IsArray($xData) Then For $i = $iFirstEntry To UBound($xData) - 1 $sData = $sData & $xData[$i][0] & '=' & $xData[$i][1] & @CRLF Next Else $sData = StringReplace($xData, @LF, @CRLF) EndIf If _LFN_FileExists($sFile) Then Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 Local $bSectionFound = False For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 Else If $bSectionFound Then ; entering next section $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf EndIf Next Local $hFile Local $bError If $iFirstLineToDelete > -1 And $iLastLineToDelete >= $iFirstLineToDelete Then $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) EndIf EndIf _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then Return SetError(1, 0, 0) _LFN_FileWriteLine($sFile, $sData) If @error Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniWriteSection ; #INTERNAL_USE_ONLY# =========================================================================================================== ;__LFN_DllOpen ;__LFN_FileReadable ;__LFN_FilesExist ;__LFN_FilesListToArray ;__LFN_FilesSimilar ;__LFN_FileWritable ;__LFN_ReDim ;__LFN_ReDim2D ;__LFN_Target_IsExistingFile ;__LFN_Target_IsExistingFolder ;__LFN_Target_IsMask ;__LFN_Target_LastElement_Get ;__LFN_Target_LastElement_Trim ;__LFN_Target_RemoveTrailingBackslash ;__LFN_Target_SetUnicodePrefix ;__LFN_Target_UnSetUnicodePrefix ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_DllOpen ; Description ...: Opens "kernel32.dll" unless already opened. ; Syntax.........: __LFN_DllOpen() ; Parameters ....: none ; Return values .: Success - Returns a handle to "kernel32.dll" ; Failure - Returns -1 and sets @error to 1 ; Author ........: orbs ; Modified.......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_DllOpen() Local Static $hDLL If $hDLL < 1 Then $hDLL = DllOpen('kernel32.dll') If $hDLL < 1 Then Return SetError(1, 0, -1) Return $hDLL EndFunc ;==>__LFN_DllOpen ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FileReadable ; Description ...: Checks if a file can be read. ; Syntax.........: __LFN_FileReadable($sFile) ; Parameters ....: $sFile - Full path of a single file to check. ; Return values .: Success - Returns True if the file can be read. ; Failure - Returns False if the file cannot be read. ; Author ........: orbs ; Modified ......: ; Remarks .......: The check is done by opening the file for reading in binary mode and reading the first byte. ; Example: this funtion will return False when checking a PST file currently in use by Microsoft Outlook. ; @error is not used. ; Related .......: ; Dependencies ..: _LFN_FileGetSize, _LFN_FileOpen, _LFN_FileRead, _LFN_FileClose ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FileReadable($sFile) If _LFN_FileGetSize($sFile) = 0 Then Return True Local $hFile = _LFN_FileOpen($sFile, 16) _LFN_FileRead($hFile, 1) Local $nError = @error _LFN_FileClose($hFile) Return ($nError = 0) EndFunc ;==>__LFN_FileReadable ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesExist ; Description ...: Checks if the target exists, and if so, also checks its type (single file, multiple files, or folder). ; Syntax.........: __LFN_FilesExist($sTarget) ; Parameters ....: $sTarget - Full path to check (wildcards supported). ; Return values .: Success - Returns 1 if the target exists, and sets @extended: ; 0 - Target does not exist (therefore can not determine if it is a file or a folder) ; 1 - Target is a single file ; 2 - Target is multiple files ; 3 - Target is a folder ; Failure - Returns 0 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the target is a mask (i.e. contains wildcards): ; - For a success return, it is sufficient that at least one of the files matching the mask exists. ; - It is always considered as "multiple files" (@extended=2), even if only a single match exists. ; @error is not used. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesExist($sTarget) Local $nResult = 0 Local $nExtended = 0 If __LFN_Target_IsMask($sTarget) Then $nExtended = 2 ; multiple files $sTarget = __LFN_Target_SetUnicodePrefix($sTarget) Local $hSearch = FileFindFirstFile($sTarget) If $hSearch = -1 And Not FileExists($sTarget) Then ; not exist $nResult = 0 Else ; exists $nResult = 1 If $nExtended = 0 Then ; not yet determined if file or folder, but definitely not multiple files If StringInStr(FileGetAttrib($sTarget), 'D') Then ; folder $nExtended = 3 Else ; single file $nExtended = 1 EndIf EndIf EndIf FileClose($hSearch) Return SetExtended($nExtended, $nResult) EndFunc ;==>__LFN_FilesExist ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesListToArray ; Description ...: Creates a list of files. ; Syntax.........: __LFN_FilesListToArray($sMask[, $bRecurse = False]) ; Parameters ....: $sMask - Full path and mask of files to list (wildcards supported). ; $bRecurse - [optional] Set to True if to recurse subdirectories ; Return values .: Success - Returns a 1-D 1-based array of filesystem entries (files & subfolders) with unicode prefix: ; [0] = number of entries ; [1] = 1st entry ; [2] = 2nd entry ; [N] = Nth entry ; The count of files only is returned in @extended. ; Failure - Returns a 1-D array of one element [0] = 0, and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the parameter is a folder, the files therein will be listed just as if you had used the * mask. ; Directories are listed with suffix backslash ("\"). ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesListToArray($sMask, $bRecurse = False) Local $aResult[1] = [0] Local $aTemp[1] = [0] Local $nExtended = 0 $sMask = __LFN_Target_SetUnicodePrefix($sMask) Local $sPath = '' Local $sMaskOnly = __LFN_Target_LastElement_Get($sMask) If Not StringInStr($sMaskOnly, '*') And Not StringInStr($sMaskOnly, '?') And StringInStr(FileGetAttrib($sMask), 'D') Then $sPath = $sMask $sMaskOnly = '*' $sMask = $sMask & '\' & $sMaskOnly Else $sPath = __LFN_Target_LastElement_Trim($sMask) EndIf If Not __LFN_FilesExist($sPath) Then Return SetExtended($nExtended, $aResult) Local $hSearch, $sFile, $i ; files $hSearch = FileFindFirstFile($sMask) While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sPath & '\' & $sFile), 'D') Then __LFN_ReDim($aResult, $sPath & '\' & $sFile & '\') Else __LFN_ReDim($aResult, $sPath & '\' & $sFile) $nExtended += 1 EndIf WEnd FileClose($hSearch) ; folders If $bRecurse Then $hSearch = FileFindFirstFile($sPath & '\*') While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sPath & '\' & $sFile), 'D') Then $aTemp = __LFN_FilesListToArray($sPath & '\' & $sFile & '\' & $sMaskOnly, $bRecurse) $nExtended += @extended If $aTemp[0] > 0 Then ReDim $aResult[$aResult[0] + 1 + $aTemp[0]] For $i = 1 To $aTemp[0] $aResult[$aResult[0] + $i] = $aTemp[$i] Next $aResult[0] += $aTemp[0] EndIf EndIf WEnd FileClose($hSearch) EndIf Return SetExtended($nExtended, $aResult) EndFunc ;==>__LFN_FilesListToArray ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesSimilar ; Description ...: Checks if two files have the same size and small-enough "Modified" timestamp difference. ; Syntax.........: __LFN_FilesSimilar($sFile1, $sFile2) ; Parameters ....: $sFile1 - first file to check similarity of. ; $sFile2 - second file to check similarity of. ; Return values .: Success - Returns 1 if the files are similar, or 0 otherwise and sets @extended: ; 1 - Difference of the "Modify" timestamp. ; 2 - Difference of size. ; Failure - Returns 0 and sets @error: ; 1 - At least one of the files was not found, or could not get timestamp of At least one of the files. ; 2 - At least one of the files was not found, or could not get size of At least one of the files. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: _LFN_FileGetTime, _LFN_FileGetSize ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesSimilar($sFile1, $sFile2) Local $sTime1 = _LFN_FileGetTime($sFile1, 0, 1) If @error Then Return SetError(1, 0, 0) Local $sTime2 = _LFN_FileGetTime($sFile2, 0, 1) If @error Then Return SetError(1, 0, 0) If Abs(Number($sTime1) - Number($sTime2)) > 2 Then Return SetExtended(1, 0) Local $nSize1 = _LFN_FileGetSize($sFile1) If @error Then Return SetError(2, 0, 0) Local $nSize2 = _LFN_FileGetSize($sFile2) If @error Then Return SetError(2, 0, 0) If $nSize1 <> $nSize2 Then Return SetExtended(2, 0) Return 1 EndFunc ;==>__LFN_FilesSimilar ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FileWritable ; Description ...: Checks if a file can be written to. ; Syntax.........: __LFN_FileWritable($sFile) ; Parameters ....: $sFile - Full path of a single file to check. ; Return values .: Success - Returns True if the file can be written to. ; Failure - Returns False if the file cannot be written to. ; Author ........: KaFu ; Modified ......: orbs ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: http://www.autoitscript.com/forum/topic/133076-looking-for-a-non-invasive-way-to-check-if-a-file-or-directory-is-writable-deletable-solved/ ; Example .......: No ; =============================================================================================================================== Func __LFN_FileWritable($sFile) Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', _ 'wstr', __LFN_Target_SetUnicodePrefix($sFile), _ 'dword', 2, _ 'dword', 7, _ 'struct*', 0, _ 'dword', 3, _ 'dword', 0x02000000, _ 'handle', 0) If @error Or $aRet[0] = Ptr(-1) Or $aRet[0] = 0 Then Return False DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $aRet[0]) Return True EndFunc ;==>__LFN_FileWritable ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_ReDim ; Description ...: Applies ReDim on a 1-D array in an efficient way. ; Syntax.........: __LFN_ReDim(ByRef $aArray[, $xData='']) ; Parameters ....: $aArray - The array to ReDim ; $xData - [optional] Data to add to the array ; Return values .: Returns the array after ReDim ; Author ........: guinness ; Modified.......: orbs ; Remarks .......: The returned array probably has empty cells at the end. the value at element [0] is the count of used cells, ; not the count of total cells. To work with the returned array, use element [0] to determine the last used cell ; instead of UBound. ; To truncate the array to used size: ReDim $aArray[$aArray[0]+1] ; Related .......: ; Dependencies ..: ; Link ..........: http://www.autoitscript.com/forum/topic/129689-redim-the-most-efficient-way-so-far-when-you-have-to-resize-an-existing-array/?hl=array+2d ; Example .......: No ; =============================================================================================================================== Func __LFN_ReDim(ByRef $aArray, $xData = '') Local $iNewRealSize = UBound($aArray) If $aArray[0] >= UBound($aArray) - 1 Then ; if used size = real size then must redim, otherwise do nothing $iNewRealSize = Ceiling((UBound($aArray) + 1) * 1.5) ReDim $aArray[$iNewRealSize] EndIf $aArray[0] += 1 ; anyway used size increased If $xData <> '' Then $aArray[$aArray[0]] = $xData EndFunc ;==>__LFN_ReDim ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_ReDim2D ; Description ...: Applies ReDim on a 2-D array in an efficient way. ; Syntax.........: __LFN_ReDim2D(ByRef $aArray[, $xData=''[, $sDelimiter='|']]) ; Parameters ....: $aArray - The array to ReDim ; $xData - [optional] Data to add to the array ; $sDelimiter - [optional] Delimiter to be used to separate data elements to columns ; Return values .: Returns the array after ReDim ; Author ........: orbs ; Modified.......: ; Remarks .......: The returned array probably has empty rows at the end. the value at element [0][0] is the count of used rows, ; not the count of total rows. To work with the returned array, use element [0][0] to determine the last used ; cell instead of UBound. ; To truncate the array to used size: ReDim $aArray[$aArray[0][0]+1][UBound($aArray,2)] ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_ReDim2D(ByRef $aArray, $xData = '', $sDelimiter = '|') Local $iNewRealSize = UBound($aArray) If $aArray[0][0] >= UBound($aArray) - 1 Then ; if used size = real size then must redim, otherwise do nothing $iNewRealSize = Ceiling((UBound($aArray) + 1) * 1.5) ReDim $aArray[$iNewRealSize][UBound($aArray, 2)] EndIf $aArray[0][0] += 1 ; anyway used size increased Local $aElements If $xData <> '' Then $aElements = StringSplit($xData, $sDelimiter) If $aElements[0] > UBound($aArray, 2) Then ReDim $aArray[$iNewRealSize][$aElements[0]] ; need to add columns For $i = 1 To $aElements[0] $aArray[$aArray[0][0]][$i - 1] = $aElements[$i] Next EndIf EndFunc ;==>__LFN_ReDim2D ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsExistingFile ; Description ...: Checks if the target is a single file that exists and is not a folder. ; Syntax.........: __LFN_Target_IsExistingFile($sTarget) ; Parameters ....: $sTarget - Full path to check. ; Return values .: True if the target is an existing file. ; False if the target is a mask, a folder, or does not exist. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsExistingFile($sTarget) If __LFN_FilesExist($sTarget) And @extended = 1 Then Return True Return False EndFunc ;==>__LFN_Target_IsExistingFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsExistingFolder ; Description ...: Checks if the target is a folder that exists. ; Syntax.........: __LFN_Target_IsExistingFolder($sTarget) ; Parameters ....: $sTarget - Full path to check. ; Return values .: True if the target is an existing folder. ; False if the target is a mask, a file, or does not exist. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsExistingFolder($sTarget) If __LFN_FilesExist($sTarget) And @extended = 3 Then Return True Return False EndFunc ;==>__LFN_Target_IsExistingFolder ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsMask ; Description ...: Checks if the target is multiple files (includes wildcards). ; Syntax.........: __LFN_Target_IsMask($sTarget) ; Parameters ....: $sTarget - Full path to check (wildcards supported). ; Return values .: True if the target is multiple files. ; False if the target is a single file. ; Author ........: orbs ; Modified ......: ; Remarks .......: If the target is a folder then it is not multiple files, therefore False is returned. ; The target does not have to exist. ; Related .......: ; Dependencies ..: __LFN_Target_LastElement_Get ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsMask($sTarget) Local $sLastElement = __LFN_Target_LastElement_Get($sTarget) If (StringInStr($sLastElement, '*') Or StringInStr($sLastElement, '?')) Then Return True Return False EndFunc ;==>__LFN_Target_IsMask ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_LastElement_Get ; Description ...: Isolates the last filesystem element of a target - what's after the last backslash ("\") character. ; Syntax.........: __LFN_Target_LastElement_Get($sTarget[, $sDelimiter = '\']) ; Parameters ....: $sTarget - Filesystem element to check (wildcards supported). ; $sDelimiter - Delimiter to determine the last element ; Return values .: A string of the last filesystem element. ; Author ........: orbs ; Modified ......: ; Remarks .......: $sDelimiter MUST be a single character! ; The target does not have to exist. ; The return string does not begin with the leading delimiter. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_LastElement_Get($sTarget, $sDelimiter = '\') Local $sTargetUnset = __LFN_Target_UnSetUnicodePrefix($sTarget) Local $iPos = StringInStr($sTargetUnset, $sDelimiter, 0, -1) Return StringTrimLeft($sTargetUnset, $iPos) EndFunc ;==>__LFN_Target_LastElement_Get ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_LastElement_Trim ; Description ...: Trims the last filesystem element of a target and returns what's before the last backslash ("\") character. ; Syntax.........: __LFN_Target_LastElement_Trim($sTarget[, $sDelimiter = '\']) ; Parameters ....: $sTarget - Filesystem element to check (wildcards supported). ; $sDelimiter - Delimiter to determine the last element ; Return values .: A string of the target with the last filesystem element stripped from it. ; Author ........: orbs ; Modified ......: ; Remarks .......: $sDelimiter MUST be a single character! ; The target does not have to exist. ; The return string does not end with the trailing delimiter. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_LastElement_Trim($sTarget, $sDelimiter = '\') Local $sTargetUnset = __LFN_Target_UnSetUnicodePrefix($sTarget) Local $iPos = StringInStr($sTargetUnset, $sDelimiter, 0, -1) Return __LFN_Target_SetUnicodePrefix(StringLeft($sTargetUnset, $iPos - 1)) EndFunc ;==>__LFN_Target_LastElement_Trim ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_RemoveTrailingBackslash ; Description ...: Strips all trailing backslash characters ("\") from the end of the given target path. ; Syntax.........: __LFN_Target_RemoveTrailingBackslash($sTarget) ; Parameters ....: $sTarget - Target path to remove trailing backslash characters from (wildcards supported). ; Return values .: A string of the target path without trailing backslash. ; @extended holds the number of backslash characters removed. ; Author ........: orbs ; Modified ......: ; Remarks .......: The target does not have to exist. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_RemoveTrailingBackslash($sTarget) Local $nBackslashedRemoved = 0 While StringRight($sTarget, 1) = '\' $sTarget = StringTrimRight($sTarget, 1) $nBackslashedRemoved += 1 WEnd Return SetExtended($nBackslashedRemoved, $sTarget) EndFunc ;==>__LFN_Target_RemoveTrailingBackslash ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_SetUnicodePrefix ; Description ...: Adds the unicode prefix to a given target, unless already present or some conditios are mey - see Remarks. ; Syntax.........: __LFN_Target_SetUnicodePrefix($sTarget) ; Parameters ....: $sTarget - Path to prefix with the unicode prefix ("\\?\" or "\\?\UNC\"). ; Return values .: Returns the parameter with the unicode prefix and sets @extended: ; 1 - $sTarget is on a locally mounted volume (local drive, mapped network drive, etc.) ; 2 - $sTarget is on a network share (UNC path) ; Author ........: orbs ; Modified.......: ; Remarks .......: The unicode prefix is added only if needed. it is not added under these conditions: ; $sTarget already has the unicode prefix ; $sTarget is a drive root ; $sTarget is a relative path ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_SetUnicodePrefix($sTarget) If (StringLeft($sTarget, 4) = '\\?\') Then $sTarget = __LFN_Target_UnSetUnicodePrefix($sTarget) ; remove unicode prefix in case it's a drive root If (StringLen($sTarget) = 2 And StringRight($sTarget, 1) = ':') Or (StringLen($sTarget) = 3 And StringRight($sTarget, 2) = ':\') Then Return $sTarget ; $sTarget is a drive root If StringLeft($sTarget, 2) <> '\\' And StringMid($sTarget, 2, 1) <> ':' Then Return $sTarget ; $sTarget is a relative path ; before adding prefix, embody relative elements "\.." Local $iPos, $iPosPrevBackslash, $sSubstringToReplace While True $iPos = StringInStr($sTarget, '\..') If $iPos = 0 Then ExitLoop $iPosPrevBackslash = $iPos Do $iPosPrevBackslash -= 1 Until StringMid($sTarget, $iPosPrevBackslash, 1) = '\' Or $iPos = 0 $sSubstringToReplace = StringMid($sTarget, $iPosPrevBackslash, $iPos - $iPosPrevBackslash + 3) $sTarget = StringReplace($sTarget, $sSubstringToReplace, '', 1) WEnd ; now add the unicode prefix and return If StringLeft($sTarget, 2) = '\\' Then Return SetExtended(2, '\\?\UNC\' & StringTrimLeft($sTarget, 2)) Else Return SetExtended(1, '\\?\' & $sTarget) EndIf EndFunc ;==>__LFN_Target_SetUnicodePrefix ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_UnSetUnicodePrefix ; Description ...: Removes the unicode prefix from a given target. ; Syntax.........: __LFN_Target_UnSetUnicodePrefix($sTarget) ; Parameters ....: $sTarget - Filesystem element to remove the unicode prefix ("\\?\" or "\\?\UNC\") from. ; Return values .: Returns the parameter without the unicode prefix and sets @extended: ; 0 - The unicode prefix was not found. ; 1 - $sTarget is on a locally mounted volume (local drive, mapped network drive, etc.) ; 2 - $sTarget is on a network share (UNC path) ; Author ........: orbs ; Modified.......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_UnSetUnicodePrefix($sTarget) If (StringLeft($sTarget, 8) = '\\?\UNC\') Then Return SetExtended(2, '\\' & StringTrimLeft($sTarget, 8)) If (StringLeft($sTarget, 4) = '\\?\') Then Return SetExtended(1, StringTrimLeft($sTarget, 4)) Return $sTarget EndFunc ;==>__LFN_Target_UnSetUnicodePrefix demo script: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 AutoItSetOption('TrayIconDebug',1) #include <Array.au3> ; included only for a call to _ArrayDisplay #include 'LFN.au3' ; INIT ; - declare root of test folder Global $sLFN_Root='C:\TEMP\LFN' ; - declare element of path - create an element (subfolder) of 200 characters in length. two of those, and you're off limit. Global $sLFN_Element='' For $i=1 To 20 $sLFN_Element=$sLFN_Element&'_-_-_-_'&StringFormat('%03d',$i*10) Next ; - declare 3 levels of path lengths: Global $sLFN_L0=$sLFN_Root ; level 0 is the root of the test folder Global $sLFN_L1=$sLFN_L0&'\'&$sLFN_Element ; level 1 is one element deep (total 212 characters) - still OK Global $sLFN_L2=$sLFN_L1&'\'&$sLFN_Element ; level 2 is two elements deep (total 413 characters) - off limit! Global $sLFN_L3=$sLFN_L2&'\'&$sLFN_Element ; level 3 is three elements deep (total 614 characters) - way off limit! ; MAIN ; - prepare folder structure _LFN_DirRemove($sLFN_L0,1) ; delete the 1st test folder to begin blank _LFN_DirRemove($sLFN_L0&'2',1) ; delete the 2nd test folder to begin blank _LFN_DirRemove($sLFN_L0&'3',1) ; delete the 3rd test folder to begin blank MsgBox(0,'Checkpoint','check clear folder now.') _LFN_DirCreate($sLFN_L3) ; create the deepest level L3 ; - file manipulation _LFN_FileWriteLine($sLFN_L3&'\file1.txt','this is a line of text') ; create a file by writing a line to a new file Global $hFile=_LFN_FileOpen($sLFN_L3&'\file1.txt',1) ; do some file manipulation _LFN_FileWriteLine($hFile,'this is a line of text') ; add a line to the file _LFN_FileSetPos($hFile,-14,2) ; beginning of the word "line" _LFN_FileWrite($hFile,'LINE') ; capitalize the word "line" _LFN_FileFlush($hFile) ; apply the change _LFN_FileSetPos($hFile,-4,1) ; back MsgBox(0,'_LFN_FileGetPos',_LFN_FileGetPos($hFile)) MsgBox(0,'_LFN_FileRead (4 chars)',_LFN_FileRead($hFile,4)) ; read the change _LFN_FileSetEnd($hFile) ; truncate the rest of the line _LFN_FileClose($hFile) ; done for now _LFN_FileSetTime($sLFN_L3&'\file1.txt','20011231010203') ; - test file info Global $aFileLines=_LFN_FileReadToArray($sLFN_L3&'\file1.txt') _ArrayDisplay($aFileLines,'_LFN_FileReadToArray') Global $hSearch=_LFN_FileFindFirstFile($sLFN_L3&'\file1.txt') Global $sShortName=_LFN_FileGetShortName($sLFN_L3&'\file1.txt') Global $sLongName=_LFN_FileGetLongName($sShortName) MsgBox(0,'test file information', _ '_LFN_FileExists = '&_LFN_FileExists($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileFindNextFile = '&_LFN_FileFindNextFile($hSearch)&@CR&@CR& _ '_LFN_FileRead (entire file) = '&@CR&_LFN_FileRead($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileReadLine (last line) = '&_LFN_FileReadLine($sLFN_L3&'\file1.txt',-1)&@CR&@CR& _ '_LFN_FileGetSize = '&_LFN_FileGetSize($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileGetTime = '&_LFN_FileGetTime($sLFN_L3&'\file1.txt',0,1)&@CR&@CR& _ '_LFN_FileGetShortName = '&$sShortName&@CR&@CR& _ '_LFN_FileGetLongName (from short name) = '&$sLongName) _LFN_FileClose($hSearch) ; - exe file info _LFN_FileCopy(@AutoItExe,$sLFN_L3) MsgBox(0,'EXE file information', _ '_LFN_FileGetVersion (not specified) = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe')&@CR& _ '_LFN_FileGetVersion (empty string) = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe','')&@CR& _ '_LFN_FileGetVersion ("FileVersion") = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe','FileVersion')&@CR&@CR& _ '_LFN_FileGetEncoding = '&_LFN_FileGetEncoding($sLFN_L3&'\AutoIt3.exe')) ; - file copy, rename, move _LFN_FileCopy($sLFN_L3&'\file1.txt',$sLFN_L2) MsgBox(0,'Checkpoint','file copy L3 -> L2') _LFN_FileMove($sLFN_L2&'\file1.txt',$sLFN_L2&'\renamed1.txt') MsgBox(0,'Checkpoint','file rename L2\file1.txt -> L2\renamed1.txt') _LFN_FileMove($sLFN_L2&'\renamed1.txt',$sLFN_L3) MsgBox(0,'Checkpoint','file move L2\renamed1.txt -> L3') _LFN_FileCopy($sLFN_L3,$sLFN_L2) MsgBox(0,'Checkpoint','file copy L3 -> L2') _LFN_FileDelete($sLFN_L2) MsgBox(0,'Checkpoint','file delete L2') ; - folder copy, rename, move, hide/unhide _LFN_DirCopy($sLFN_L0,$sLFN_L0&'2') MsgBox(0,'Checkpoint','dir copy <L0> -> <L02>') _LFN_DirMove($sLFN_L0,$sLFN_L0&'2',1) MsgBox(0,'Checkpoint','dir move <L0> -> <L02> (inside)') _LFN_DirCopy($sLFN_L0&'2\LFN',$sLFN_L0) MsgBox(0,'Checkpoint','dir copy <L02>\LFN -> <L0>') _LFN_FileSetAttrib($sLFN_L0,'+H') MsgBox(0,'Checkpoint','dir hidden <L0>'&@CR&@CR&'dir attrib: '&_LFN_FileGetAttrib($sLFN_L0)) _LFN_FileSetAttrib($sLFN_L0,'-H') MsgBox(0,'Checkpoint','dir unhidden <L0>'&@CR&@CR&'dir attrib: '&_LFN_FileGetAttrib($sLFN_L0)) ; - folder size Global $aDirSize=_LFN_DirGetSize($sLFN_L0,1) MsgBox(0,'Checkpoint','dir size <L0>: '&@CR&@CR& _ 'Size [bytes] = '&$aDirSize[0]&@CR& _ 'Files count = '&$aDirSize[1]&@CR& _ 'Folders count = '&$aDirSize[2]) ; - ini functions Global $sIniFile1=$sLFN_L3&'\test1.ini' Global $sIniFile2=$sLFN_L3&'\test2.ini' MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K1) = '&_LFN_IniWrite($sIniFile1,'S1','S1K1','""S1V1 inside double-souble-quotes to be stripped""')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection (S2) = '&_LFN_IniWriteSection($sIniFile1,'S2','S2K1= S2V1 with whitespaces NOT to be stripped '&@LF&'S2K2="S2V2 inside double-quotes NOT to be stripped"'&@LF&'S2K3=V3')) MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K2) = '&_LFN_IniWrite($sIniFile1,'S1','S1K2','" S1V2 with quoted whitespaces "')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection (S3) = '&_LFN_IniWriteSection($sIniFile1,'S3','S3K1=V1'&@LF&'S3K2=V2'&@LF&'S3K3=V3')) MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K3) = '&_LFN_IniWrite($sIniFile1,'S1','S1K3','V3')) MsgBox(0,'Checkpoint','_LFN_IniRead (S1K2) = '&_LFN_IniRead($sIniFile1,'S1','S1K2','S1K2: could not read value')) Global $a $a=_LFN_IniReadSection($sIniFile1,'S3') $a[1][1]='"V1 with quotes"' $a[2][1]=' V2 with whitespace ' MsgBox(0,'Checkpoint','_LFN_IniDelete 1:(S3) = '&_LFN_IniDelete($sIniFile1,'S3')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection 2:(S3) = '&_LFN_IniWriteSection($sIniFile2,'S3',$a)) $a=_LFN_IniReadSection($sIniFile1,'S2') MsgBox(0,'Checkpoint','_LFN_IniDelete 1:(S2K2) = '&_LFN_IniDelete($sIniFile1,'S2','S2K2')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection 2:(S2) = '&_LFN_IniWriteSection($sIniFile2,'S2',$a)) MsgBox(0,'Checkpoint','_LFN_IniRenameSection 2:(S2) = '&_LFN_IniRenameSection($sIniFile2,'S2','S2renamed')) Global $aSectionNames=_LFN_IniReadSectionNames($sIniFile2) _ArrayDisplay($aSectionNames,'section names') For $i=1 To $aSectionNames[0] $a=_LFN_IniReadSection($sIniFile2,$aSectionNames[$i]) _ArrayDisplay($a,$aSectionNames[$i]) Next script converter: #NoTrayIcon #Region refs ; http://www.autoitscript.com/forum/topic/135536-how-to-make-the-gui-resizable/ ; https://www.autoitscript.com/wiki/Adding_UDFs_to_AutoIt_and_SciTE ; https://www.autoitscript.com/autoit3/docs/appendix/WinMsgCodes.htm #EndRegion refs #Region AutoIt3Wrapper directives section #AutoIt3Wrapper_Icon=LFN_Script_Converter_NG.ico #AutoIt3Wrapper_UseUpx=N #AutoIt3Wrapper_Res_Fileversion=1.4.0.3 #EndRegion AutoIt3Wrapper directives section #Region include #include <StaticConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <ComboConstants.au3> #include <GuiButton.au3> #EndRegion include #Region declare ; declare Global $aFuncs[1] = [0] Global $sScript_File = '' Global $aScriptOrg[1] = [0] Global $aScriptNew[1] = [0] Global $aLineChanged[1][3] Global $iLineChanged = 0 Global $bNeedToInclude = True ; assume the LFN UDF is not alredy included Global $iLineOfLastInclude = 0 ; after this line number, the line to include the LFN UDF will be added Global $tPoint_MainGlobal = DllStructCreate($tagPoint) ; ListView tooltips ; declare and populate possible UDF paths Global $sUDF_Path_MainInclude = RegRead('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude = '' Then $sUDF_Path_MainInclude = RegRead('HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude = '' Then $sUDF_Path_MainInclude = RegRead('HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude <> '' Then $sUDF_Path_MainInclude = StringLeft($sUDF_Path_MainInclude, StringInStr($sUDF_Path_MainInclude, '\', 0, -1) - 1) If $sUDF_Path_MainInclude <> '' Then $sUDF_Path_MainInclude &= '\Include' Global $sUDF_Path_UserInclude = RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include') ; declare UDF properties Global $sUDF_Name = 'LFN.au3' Global $sUDF = '' Global $sUDF_Version = '' Global $sUDF_AutoItVersion = '' Global $sUDF_FunctionsList = '' ; declare and init preferences Global $bMonospace = False Global $bCreateBackup = True Global $bIncludeUDF = True Global $bConvertFileFindNextFile = False #EndRegion declare #Region build GUI $hGUI = GUICreate('LFN Script Converter', 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_SYSMENU)) GUISetBkColor(0xFEDCBA) $iLine_Y = 25 GUICtrlCreateGroup('UDF', 10, $iLine_Y - 18, 355, 40) RemoveTheme(GUICtrlGetHandle(-1)) GUICtrlSetColor(-1, 0x876543) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlCreateLabel('Location:', 20, $iLine_Y, 50, 16) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gUDF_Path = GUICtrlCreateCombo('Script folder', 75, $iLine_Y - 4, 160, 100, $CBS_DROPDOWNLIST) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) If $sUDF_Path_MainInclude <> '' Then GUICtrlSetData(-1, 'AutoIt main include folder') If $sUDF_Path_UserInclude <> '' Then GUICtrlSetData(-1, 'AutoIt user include folder') GUICtrlCreateLabel('Name:', 250, $iLine_Y, 35, 16) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gUDF_Name = GUICtrlCreateInput($sUDF_Name, 285, $iLine_Y - 2, 70, 18) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gPref = GUICtrlCreateLabel(Chr(64), 459, $iLine_Y - 4, 20, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetFont(-1, 18, Default, 0, 'Webdings') GUICtrlSetCursor(-1, 0) GUICtrlSetColor(-1, 0x876543) GUICtrlSetTip(-1, 'Preferences') $gPref_Menu_Dummy = GUICtrlCreateDummy() $gPref_Menu = GUICtrlCreateContextMenu($gPref_Menu_Dummy) $gPref_Menu_Monospace = GUICtrlCreateMenuItem('Monospace Font', $gPref_Menu) $gPref_Menu_CreateBackup = GUICtrlCreateMenuItem('Create Backup', $gPref_Menu) If $bCreateBackup Then GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_CHECKED) $gPref_Menu_IncludeUDF = GUICtrlCreateMenuItem('Include UDF', $gPref_Menu) If $bIncludeUDF Then GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_CHECKED) $gPref_Menu_ConvertFileFindNextFile = GUICtrlCreateMenuItem('Convert FileFindNextFile', $gPref_Menu) If $bConvertFileFindNextFile Then GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_CHECKED) $iLine_Y = 73 GUICtrlCreateGroup('Script', 10, $iLine_Y - 18, 480, 40) RemoveTheme(GUICtrlGetHandle(-1)) GUICtrlSetColor(-1, 0x876543) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT)) $gScript_File = GUICtrlCreateInput('', 20, $iLine_Y - 2, 265, 18) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT)) $gScript_Select = GUICtrlCreateButton('Browse', 290, $iLine_Y - 3, 60, 20) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) $gScript_Convert = GUICtrlCreateButton('Convert', 355, $iLine_Y - 3, 125, 20, $BS_SPLITBUTTON) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) $gScript_Convert_Menu_Dummy = GUICtrlCreateDummy() $gScript_Convert_Menu = GUICtrlCreateContextMenu($gScript_Convert_Menu_Dummy) $gScript_Convert_Menu_QueryUDF = GUICtrlCreateMenuItem('Query UDF', $gScript_Convert_Menu) $gScript_Convert_Menu_Analyze = GUICtrlCreateMenuItem('Analyze', $gScript_Convert_Menu) $gScript_Convert_Menu_Convert = GUICtrlCreateMenuItem('Convert', $gScript_Convert_Menu) $gLV = GUICtrlCreateListView('Line#|Original|Converted', 10, 100, 480, 370) GUICtrlSetFont(-1, Default, Default, Default, 'Tahoma') $hLV = GUICtrlGetHandle($gLV) _GUICtrlListView_SetColumnWidth($gLV, 0, 50) _GUICtrlListView_SetColumnWidth($gLV, 1, 200) _GUICtrlListView_SetColumnWidth($gLV, 2, 200) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUISetState() ControlFocus('', '', $gScript_File) GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") GUIRegisterMsg($WM_SIZE, "_WM_SIZE") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; for context menu of split button #EndRegion build GUI ; work with GUI While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_RESTORE, $GUI_EVENT_MAXIMIZE _WM_SIZE($hGUI, -1, -1, -1) Case $GUI_EVENT_MOUSEMOVE SetMousePos() TimerFunc($hLV) Case $gScript_Convert_Menu_QueryUDF If UDF_Query() Then MsgBox(0, 'UDF Info:', _ 'UDF Full Path:' & @TAB & $sUDF & @CR & _ 'UDF Version:' & @TAB & $sUDF_Version & @CR & _ 'AutoIt Version:' & @TAB & $sUDF_AutoItVersion & @CR & _ 'Functions List:' & @TAB & '(' & $aFuncs[0] & ' functions)' & @CR & _ $sUDF_FunctionsList) Case $gScript_Select $sScript_File = FileOpenDialog('Select an AutoIt v3 Script to convert:', @ScriptDir, 'AutoIt v3 Scripts (*.au3)') If Not @error Then GUICtrlSetData($gScript_File, $sScript_File) Call_Analyze() EndIf Case $gScript_Convert_Menu_Analyze Call_Analyze() Case $gScript_Convert, $gScript_Convert_Menu_Convert If Call_Analyze() Then Convert() Case $gPref _ContextMenu_ShowMenu($hGUI, $gPref, $gPref_Menu, -180) Case $gPref_Menu_Monospace $bMonospace = Not $bMonospace If $bMonospace Then GUICtrlSetState($gPref_Menu_Monospace, $GUI_CHECKED) GUICtrlSetFont($gLV, Default, Default, Default, 'Courier New') Else GUICtrlSetState($gPref_Menu_Monospace, $GUI_UNCHECKED) GUICtrlSetFont($gLV, Default, Default, Default, 'Tahoma') EndIf Case $gPref_Menu_CreateBackup $bCreateBackup = Not $bCreateBackup If $bCreateBackup Then GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_UNCHECKED) EndIf Case $gPref_Menu_IncludeUDF $bIncludeUDF = Not $bIncludeUDF If $bIncludeUDF Then GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_UNCHECKED) EndIf Case $gPref_Menu_ConvertFileFindNextFile $bConvertFileFindNextFile = Not $bConvertFileFindNextFile If $bConvertFileFindNextFile Then GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_UNCHECKED) EndIf EndSwitch WEnd Func Call_Analyze() If GUICtrlRead($gScript_File) = '' Then MsgBox(16, 'Error!', 'Please select a script file to convert. ', 0, $hGUI) Return False EndIf _GUICtrlListView_DeleteAllItems($gLV) If Not UDF_Query() Then Return False If Analyze() Then For $i = 1 To $iLineChanged GUICtrlCreateListViewItem($aLineChanged[$i][0] & '|' & StringStripWS($aLineChanged[$i][1], 3) & '|' & StringStripWS($aLineChanged[$i][2], 3), $gLV) Next Else MsgBox(64, 'Abort', 'Conversion aborted.' & @CR & @CR & 'No changes need to be made. Script is either already converted or does not use any functions to be converted. ', 0, $hGUI) GUICtrlSetData($gScript_File, '') Return False EndIf Return True EndFunc ;==>Call_Analyze Func UDF_Query() Local $sScript_Path = '' $sUDF_Name = GUICtrlRead($gUDF_Name) If $sUDF_Name = '' Then MsgBox(16, 'Error!', 'Please type the UDF file name. ', 0, $hGUI) Return False EndIf Switch GUICtrlRead($gUDF_Path) Case 'Script folder' $sScript_Path = GUICtrlRead($gScript_File) If $sScript_Path = '' Then $sScript_Path = @ScriptDir Else $sScript_Path = StringLeft($sScript_Path, StringInStr($sScript_Path, '\', 0, -1) - 1) EndIf $sUDF = $sScript_Path & '\' & $sUDF_Name Case 'AutoIt main include folder' $sUDF = $sUDF_Path_MainInclude & '\' & $sUDF_Name Case 'AutoIt user include folder' $sUDF = $sUDF_Path_UserInclude & '\' & $sUDF_Name Case Else MsgBox(16, 'Error!', 'Unknown item in locations list. ', 0, $hGUI) Return False EndSwitch If Not FileExists($sUDF) Then MsgBox(16, 'Error!', 'UDF file not found: ' & @CR & @CR & $sUDF, 0, $hGUI) Return False EndIf $sUDF_Version = 'n/a' $sUDF_AutoItVersion = 'n/a' $sUDF_FunctionsList = '' ReDim $aFuncs[1] $aFuncs[0] = 0 $aUDF = __FileReadToArray($sUDF) Local $bListFuncs = False For $i = 1 To UBound($aUDF) - 1 If StringLeft($aUDF[$i], 19) = '; UDF Version ...: ' Then $sUDF_Version = StringTrimLeft($aUDF[$i], 19) If StringLeft($aUDF[$i], 19) = '; AutoIt Version : ' Then $sUDF_AutoItVersion = StringTrimLeft($aUDF[$i], 19) If $bListFuncs Then If $aUDF[$i] = '; ===============================================================================================================================' Then ExitLoop $aFuncs[0] += 1 ReDim $aFuncs[$aFuncs[0] + 1] $aFuncs[$aFuncs[0]] = StringTrimLeft($aUDF[$i], 6) ; remove the string ";_LFN_" and leave only the native name of the function $sUDF_FunctionsList = $sUDF_FunctionsList & @TAB & $aFuncs[$aFuncs[0]] & @CR EndIf If $aUDF[$i] = '; #CURRENT# =====================================================================================================================' Then $bListFuncs = True Next If $aFuncs[0] = 0 Then MsgBox(16, 'Error!', 'No functions found in the LFN UDF file: ' & @CR & @CR & $sUDF, 0, $hGUI) Return False EndIf Return True EndFunc ;==>UDF_Query Func Analyze() ; init ReDim $aLineChanged[1][3] $aLineChanged[0][0] = 0 $aLineChanged[0][1] = 0 $aLineChanged[0][2] = 0 $iLineChanged = 0 $bNeedToInclude = True $iLineOfLastInclude = 0 ; read existing script to memory $aScriptOrg = __FileReadToArray($sScript_File) ; match size of new array ReDim $aScriptNew[UBound($aScriptOrg)] $aScriptNew[0] = UBound($aScriptNew) - 1 ; in memory, replace functions line-by-line, while searching for the last #include and checking if LFN UDF is not already included For $i = 1 To UBound($aScriptOrg) - 1 If StringInStr($aScriptOrg[$i], '#include ') Then $iLineOfLastInclude = $i If StringInStr($aScriptOrg[$i], $sUDF_Name) Then $bNeedToInclude = False EndIf $aScriptNew[$i] = ReplaceAllFuncs($aScriptOrg[$i]) If @extended Then $iLineChanged += 1 ReDim $aLineChanged[$iLineChanged + 1][3] $aLineChanged[$iLineChanged][0] = $i $aLineChanged[$iLineChanged][1] = $aScriptOrg[$i] $aLineChanged[$iLineChanged][2] = $aScriptNew[$i] EndIf Next ; control #1 - if no changes are required then exit If $iLineChanged = 0 Then Return False ; done analyze Return True EndFunc ;==>Analyze Func Convert() ToolTip('') ; summary report Local $sUDF_IncludeString = '' Local $sText = '' If $bCreateBackup Then $sText = $sText & '- Original file will be backed-up.' & @CR $sText = $sText & '- ' & $iLineChanged & ' lines will be modified.' & @CR If $bNeedToInclude And $bIncludeUDF Then $sText &= '- The statement #include ' If GUICtrlRead($gUDF_Path) = 'Script folder' Then $sUDF_IncludeString = '"' & $sUDF_Name & '"' Else $sUDF_IncludeString = '<' & $sUDF_Name & '>' EndIf $sText &= $sUDF_IncludeString $sText &= ' will be added ' If $iLineOfLastInclude = 0 Then $sText &= 'at the top of the script. ' Else $sText &= 'after line #' & $iLineOfLastInclude & ': ' & @CR & ' ' & $aScriptOrg[$iLineOfLastInclude] EndIf Else $sText &= '- #include statement will not be added.' EndIf If MsgBox(32 + 4, 'Conversion Summary:', $sText & @CR & @CR & 'Continue with the conversion?', 0, $hGUI) <> 6 Then MsgBox(64, 'Abort', 'Conversion aborted. No changes were made. ', 0, $hGUI) Return EndIf ; backup existing script If $bCreateBackup And Not FileCopy($sScript_File, $sScript_File & '.PreLFN_' & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & '.au3') Then MsgBox(16, 'Error!', 'Could not create a backup of the script before conversion. ', 0, $hGUI) Return EndIf ; rewrite the script Local $hScriptFile = FileOpen($sScript_File, 2) For $i = 1 To UBound($aScriptNew) - 1 If $bNeedToInclude And $bIncludeUDF And $i = $iLineOfLastInclude + 1 Then FileWriteLine($hScriptFile, '#include ' & $sUDF_IncludeString) If Not FileWriteLine($hScriptFile, $aScriptNew[$i]) Then MsgBox(16, 'Error!', 'Could not write line #' & $i & ' to the script file. ' & @CR & @CR & 'IMPORTANT: to avoid issues, you are advised to revert to the backup copy of your script. ', 0, $hGUI) FileClose($hScriptFile) Return EndIf Next FileClose($hScriptFile) MsgBox(64, 'Done', 'Conversion completed successfully. ', 0, $hGUI) EndFunc ;==>Convert Func ReplaceAllFuncs($sLine) ; isolate LFN UDF internal functions Local $sLineNew = StringReplace($sLine, '__LFN_', '__L!N_') ; revert any LFN UDF current functinos back to their native form $sLineNew = StringReplace($sLineNew, '_LFN_', '') ; convert functions to LFN For $i = 1 To $aFuncs[0] $sLineNew = StringRegExpReplace($sLineNew, "(?<!\w)(" & $aFuncs[$i] & '\(' & ")", '_LFN_' & $aFuncs[$i] & '(') Next ; revert isolation of LFN UDF internal functions $sLineNew = StringReplace($sLineNew, '__L!N_', '__LFN_') ; revert conversion of FileFindNextFile if needed If Not $bConvertFileFindNextFile Then $sLineNew = StringReplace($sLineNew, '_LFN_FileFindNextFile', 'FileFindNextFile') ; return the converted line with indication if it was changed or not If $sLineNew = $sLine Then Return SetExtended(0, $sLineNew) Else Return SetExtended(1, $sLineNew) EndIf EndFunc ;==>ReplaceAllFuncs Func __FileReadToArray($xFile) Return StringSplit(StringStripCR(FileRead($xFile, FileGetSize($xFile))), @LF) EndFunc ;==>__FileReadToArray Func RemoveTheme($hItem) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $hItem, "wstr", 0, "wstr", 0) EndFunc ;==>RemoveTheme #Region resizing funcs Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $hGUI Then $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($tagMaxinfo, 7, 500) ; min X DllStructSetData($tagMaxinfo, 8, 300) ; min Y Return 0 EndIf EndFunc ;==>_WM_GETMINMAXINFO Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $hGUI Then $aLVPos = ControlGetPos($hGUI, "", $gLV) If @error Then Return Local $nLV_ColWidth = ($aLVPos[2] - 80) / 2 _GUICtrlListView_SetColumnWidth($gLV, 0, 50) _GUICtrlListView_SetColumnWidth($gLV, 1, $nLV_ColWidth) _GUICtrlListView_SetColumnWidth($gLV, 2, $nLV_ColWidth) EndIf EndFunc ;==>_WM_SIZE #EndRegion resizing funcs #Region ListView tooltip funcs Func TimerFunc($hLV) Local Const $nLinesAround = 10 Local Static $iIndex_old = -1 Local $iIndex = _GUICtrlListView_HitTest($hLV) If HoveringOnHeader($hLV) Or $iIndex[0] < 0 Then $iIndex_old = -1 Return ToolTip('') EndIf If $iIndex[0] = $iIndex_old Then Return Local $iLine = $aLineChanged[$iIndex[0] + 1][0] Local $iLineStart = 1 If $iLine - $nLinesAround > 1 Then $iLineStart = $iLine - $nLinesAround Local $iLineEnd = $iLine + $nLinesAround If UBound($aScriptNew) - 1 < $iLine + $nLinesAround Then $iLineEnd = UBound($aScriptNew) - 1 Local $sTooltip = '' For $i = $iLineStart To $iLineEnd $sTooltip = $sTooltip & $i & '.' & @TAB & $aScriptNew[$i] & @CR Next ; create tooltip ToolTip($sTooltip, Default, Default, 'Line #' & $iLine & ':', Default, 4) $iIndex_old = $iIndex[0] EndFunc ;==>TimerFunc Func SetMousePos() DllStructSetData($tPoint_MainGlobal, 1, MouseGetPos(0)) DllStructSetData($tPoint_MainGlobal, 2, MouseGetPos(1)) EndFunc ;==>SetMousePos Func HoveringOnHeader($hLV) Local $tRect = DllStructCreate($tagRect) Local $aPos = WinGetPos(_GUICtrlListView_GetHeader($hLV)) $aPos[2] = $aPos[0] + $aPos[2] $aPos[3] = $aPos[1] + $aPos[3] If @error Then Return SetError(1, 0, 0) For $i = 1 To 4 DllStructSetData($tRect, $i, $aPos[$i - 1]) Next Return _WinAPI_PtInRect($tRect, $tPoint_MainGlobal) EndFunc ;==>HoveringOnHeader #EndRegion ListView tooltip funcs #Region context menu for split button Func _ContextMenu_ShowMenu($hWnd, $CtrlID, $nContextID, $n_dx = 0) ; Show a menu in a given GUI window which belongs to a given GUI ctrl Local $arPos, $x, $y Local $hMenu = GUICtrlGetHandle($nContextID) $arPos = ControlGetPos($hWnd, "", $CtrlID) $x = $arPos[0] + $n_dx $y = $arPos[1] + $arPos[3] _ContextMenu_ClientToScreen($hWnd, $x, $y) _ContextMenu_TrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ;==>_ContextMenu_ShowMenu Func _ContextMenu_ClientToScreen($hWnd, ByRef $x, ByRef $y) ; Convert the client (GUI) coordinates to screen (desktop) coordinates Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFunc ;==>_ContextMenu_ClientToScreen Func _ContextMenu_TrackPopupMenu($hWnd, $hMenu, $x, $y) ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ;==>_ContextMenu_TrackPopupMenu Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $wParam Local $tNMBHOTITEM = DllStructCreate("hwnd hWndFrom;int IDFrom;int Code;dword dwFlags", $lParam) Local $nNotifyCode = DllStructGetData($tNMBHOTITEM, "Code") Local $hCtrl = DllStructGetData($tNMBHOTITEM, "hWndFrom") Switch $nNotifyCode Case $BCN_DROPDOWN _ContextMenu_ShowMenu($hGUI, $gScript_Convert, $gScript_Convert_Menu) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY #EndRegion context menu for split button1 point
-
As a starter and far from perfect and real messy code a simple spy for Java Accessibility Bridge Based on the information in general help and support '?do=embed' frameborder='0' data-embedContent>> Many functions still to make and enhance but I would call at a 0.1 version for automating Java from within AutoIT and Java accessibility Spy detects based on mouse position make sure you have JABSWITCH /ENABLE Childs start counting from 0 Hover mouse over your Java Element and press Ctrl+W and you will get some basic information Prerequisites 1. Only Java Runtime needed (no need for samples / JDK to install) from JRE 1.7 and higher (for 1.6 you need to install accessibility bridge 2.0.2 yourself) 2. JABSWITCH /ENABLE should have been run from commandline 3. Then script can be run (will run JavaCPL with shellexecute("C:Program FilesJavajre1.8.0_25binjavacpl.exe")) so needs change if other JRE version Optional (mainly for definitions in header files but main info copied in au3 script in comments) 4. Java Accessibility Bridge 2.0.2. for CPP source and headers and javamonkey (java spy tool) 5. JDK installed for other JAVA sample applications 6. NVDA screen reader source JABHANDLER.PY as a reference Please enhance / help in extending by posting small helper functions / translating the definitions (at the moment I have little time but the start is promising) Unfortunately there is not much documented on Java Accessibility Bridge Output example Mouse position is retrieved 1490-415 JAVA window found <> Java Window Title= Handle=0x00000000000E098C res: 1 Result getAccessibleContextFromHWND is <> ubound: 4 We have a VMid 133566 ac 1530827472 Call version info: PASSED VMID found : 133566 VMVersion: <1.8.0_25> bridgeJavaClassVersion: <1.8.0_25> bridgeJavaDLLVersion: <1.8.0_25> bridgeWinDLLVersion: <1.8.0_25> *** getAccessibleContextAT result is <1530827448> *** getAccessibleContextAT result is <1530827448> Network Settings... <html>Modify Internet connection settings</html> push button push button enabled,focusable,visible,showing,opaque enabled,focusable,visible,showing,opaque 0 0 1424 406 127 0 End of getAcceccibleContextAt info Source JABSimpleSpy #AutoIt3Wrapper_UseX64=Y ;~ It depends on amount of information you need if you require admin, run scite also as adminuser otherwise you will not see output in scitewindow ;~ #RequireAdmin #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <constants.au3> #include <WinAPI.au3> #include <WinAPIEx.au3> #include <debug.au3> #include <memory.au3> #include <Misc.au3> #include <javaui.au3> HotKeySet("{ESC}", "Close") ; Set ESC as a hotkey to exit the script. HotKeySet("^w", "GetElementInfo") ; Set Hotkey Ctrl+W to get some basic information in the GUI Global $hAccessBridgeDll ;~ reference to the accessbridge dll #Const $tagAccessBridgeVersionInfo = "WCHAR VMversion[256];WCHAR bridgeJavaClassVersion[256];WCHAR bridgeJavaDLLVersion[256];WCHAR bridgeWinDLLVersion[256]" ;~ const $c_JOBJECT64="UINT64" ;~ JOBJECT64 ;~ const $cP_JOBJECT64="UINT64*" ;~ POINTER(JOBJECT64) #Const $c_JOBJECT64 = (@AutoItX64) ? ("UINT64") : ("UINT") ;~ JOBJECT64 #Const $cP_JOBJECT64 = (@AutoItX64) ? ("UINT64*") : ("UINT*") ;~ POINTER(JOBJECT64) Const $c_AccessibleContext=$c_JOBJECT64 Const $cP_AccessibleContext=$cP_JOBJECT64 Local $tAccessBridgeVersionInfo = DllStructCreate($tagAccessBridgeVersionInfo) #Const $tagAccessibleContextInfo = "WCHAR name[1024];WCHAR description[1024];WCHAR role[256];WCHAR role_en_US[256];WCHAR states[256];WCHAR states_en_US[256];INT indexInParent;INT childrenCount;INT x;INT y;INT width;INT height;BOOL accessibleComponent;BOOL accessibleAction;BOOL accessibleSelection;BOOL accessibleText;BOOL accessibleInterfaces" Local $tAccessibleContextInfo = DllStructCreate($tagAccessibleContextInfo) ;~ struct AccessibleTextInfo { ;~ jint charCount; // # of characters in this text object ;~ jint caretIndex; // index of caret ;~ jint indexAtPoint; // index at the passsed in point ;~ }; #Const $tagAccessibleTextInfo = "INT charCount;INT caretIndex;INT indexAtPoint" Const $AutoSpy = 0 ;2000 ; SPY about every 2000 milliseconds automatically, 0 is turn of use only ctrl+w ;~ global $oldUIElement ; To keep track of latest referenced element Global $frmSimpleSpy, $edtCtrlInfo, $lblCapture, $lblEscape, $lblRecord, $edtCtrlRecord, $msg Global $i ; Just a simple counter to measure time expired in main loop If @AutoItX64 <> 1 Then Local $sJavaReg = "HKLM\SOFTWARE\JavaSoft\Java Runtime Environment" $sJavaVersion = RegRead($sJavaReg, "CurrentVersion") $sJavaHome = RegRead($sJavaReg & "\" & $sJavaVersion, "JavaHome") ElseIf @AutoItX64 = 1 Then Local $sJavaReg64 = "HKLM64\SOFTWARE\JavaSoft\Java Runtime Environment" Local $sJavaReg32 = "HKLM64\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment" local $regKey $regKey=(@AutoItX64) ? $sJavaReg64 : $sJavaReg32 consolewrite("Reading from regkey: "& $regkey & @CRLF) $sJavaVersion = RegRead($regkey, "CurrentVersion") if (@error=1) Then $regKey=$sJavaReg32 EndIf $sJavaVersion = RegRead($regkey, "CurrentVersion") $sJavaHome = RegRead($regkey & "\" & $sJavaVersion, "JavaHome") $sJavaHome = StringReplace($sJavaHome," (x86)","") $sJavaHome = "C:\Program Files\Java\jdk1.8.0_172\jre" ;~ consolewrite($sJavaHome & @ProgramFilesDir) ;~ exit EndIf if $sJavaHome="" Then Local $sJavaHome=envget("JAVA_HOME") if stringright($sJavaHome,1)="\" Then $sJavaHome=stringleft($sJavaHome,stringlen($sJavaHome)-1) EndIf endif ;~ Global $sWow64 = (@AutoItX64) ? ("\Wow6432Node") : ("") ;~ Global $sJavaVersion = RegRead("HKLM\SOFTWARE" & $sWow64 & "\JavaSoft\Java Runtime Environment", "CurrentVersion") ;~ Global $sJavaHome = RegRead("HKLM\SOFTWARE" & $sWow64 & "\JavaSoft\Java Runtime Environment\" & $sJavaVersion, "JavaHome") ConsoleWrite("JAVAHOME=" & $sJavaHome & @CRLF) consolewrite("The current working directory: " & @CRLF & @WorkingDir) ShellExecute($sJavaHome & "\bin\javacpl.exe") Sleep(3000) _JABInit() ;~ _Example1_IterateJavaWindows() #Region ### START Koda GUI section ### Form= $frmSimpleSpy = GUICreate("Simple UIA Spy", 801, 601, 181, 4) $edtCtrlInfo = GUICtrlCreateEdit("", 18, 18, 512, 580) GUICtrlSetData(-1, "") $lblCapture = GUICtrlCreateLabel("Ctrl+W to capture information", 544, 10, 528, 17) $lblEscape = GUICtrlCreateLabel("Escape to exit", 544, 53, 528, 17) $edtCtrlRecord = GUICtrlCreateEdit("", 544, 72, 233, 520) GUICtrlSetData(-1, "//TO DO edtCtrlRecord") ;~ $lblRecord = GUICtrlCreateLabel("Ctrl + R to record code", 544, 32, 527, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### ;~ _UIA_Init() ;~ loadCodeTemplates() ; //TODO: To use templates per class/controltype ; Run the GUI until the dialog is closed While True $msg = GUIGetMsg() Sleep(100) ;~ if _ispressed(01) Then ;~ getelementinfo() ;~ endif ;Just to show anyway the information about every n ms so ctrl+w is not interfering / removing window as unwanted side effects $i = $i + 100 If ($AutoSpy <> 0) And ($i >= $AutoSpy) Then $i = 0 GetElementInfo() EndIf If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd _JABShutDown() Func GetElementInfo() Local $acParent = 0 Local $vmID = 0 Local $tStruct = DllStructCreate($tagPOINT) Local $description $description = "" $xMouse = MouseGetPos(0) $yMouse = MouseGetPos(1) DllStructSetData($tStruct, "x", $xMouse) DllStructSetData($tStruct, "y", $yMouse) $tGetMousePos = _WinAPI_GetMousePos() $hwnd = _WinAPI_WindowFromPoint($tGetMousePos) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "isJavaWindow", "hwnd", $hwnd) If @error = 0 Then If $result[0] = 1 Then consolewrite("mouse position retrieved" & @CRLF) $description = "Mouse position is retrieved " & $xMouse & "-" & $yMouse & @CRLF ;~ GUICtrlSetData($edtCtrlInfo, "Mouse position is retrieved " & $xMouse & "-" & $yMouse & @CRLF) $description = $description & (" JAVA window found <" & "> Java Window Title=" & " Handle=" & $hwnd & @TAB & " res: " & $result[0] & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextFromHWND", "hwnd", $hwnd, "long*", $vmID, $cP_AccessibleContext, $acParent) If @error = 0 Then $description = $description & ("Result getAccessibleContextFromHWND is <" & $result & "> ubound: " & UBound($result) & @CRLF) $vmID = $result[2] $acParent = $result[3] $description = $description & (" We have a VMid " & $vmID & " ac " & $acParent & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getVersionInfo", "long", $vmID, "struct*", DllStructGetPtr($tAccessBridgeVersionInfo)) If @error = 0 Then $s1 = DllStructGetData($tAccessBridgeVersionInfo, "VMVersion") $s2 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeJavaClassVersion") $s3 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeJavaDLLVersion") $s4 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeWinDLLVersion") $description = $description & ("Call version info: PASSED VMID found : " & $vmID & @CRLF) $description = $description & (" VMVersion: <" & $s1 & ">" & @CRLF) $description = $description & (" bridgeJavaClassVersion: <" & $s2 & ">" & @CRLF) $description = $description & (" bridgeJavaDLLVersion: <" & $s3 & ">" & @CRLF) $description = $description & (" bridgeWinDLLVersion: <" & $s4 & ">" & @CRLF) Else $description = $description & ("getVersionInfo error:" & @error & @CRLF) EndIf Local $childAT_AC __getAccessibleContextAt($vmID, $acParent, $xmouse, $yMouse, $childAT_AC) $description = $description & (" *** getAccessibleContextAT result is <" & $childAT_AC & "> " & @CRLF) If @error = 0 Then $description = $description & (" *** getAccessibleContextAT result is <" & $childAT_AC & "> " & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $childAT_AC, "struct*", $tAccessibleContextInfo) $AccessibleContextInfo = $result[3] $description = $description & (getDescription($AccessibleContextInfo)) $description = $description & ("End of getAcceccibleContextAt info" & @CRLF) $acX = DllStructGetData($AccessibleContextInfo, "x") $acY = DllStructGetData($AccessibleContextInfo, "y") $acW = DllStructGetData($AccessibleContextInfo, "width") $acH = DllStructGetData($AccessibleContextInfo, "height") ConsoleWrite("rect:" & $acX & $acX+$acW & $acy & $acY+$acH) _UIA_DrawRect($acX,$acX+$acW, $acy, $acY+$acH) EndIf EndIf EndIf EndIf GUICtrlSetData($edtCtrlInfo, $description & @CRLF) EndFunc ;==>GetElementInfo Func Close() _JABShutDown() Exit EndFunc ;==>Close Func _JABInit() ;~ Make sure Java Access Bridge is turned on RunWait($sJavaHome & "\bin\jabswitch /enable", "", @SW_MAXIMIZE) ;~ TODO: Check if it works with both dll's ConsoleWrite("We are using " & @OSArch & " at cpu " & @CPUArch & " Autoit 64 bit version @AutoItX64=" & @AutoItX64 & @CRLF) If Not IsAdmin() Then ConsoleWrite("Warning: The script is advicable to be run with #requireadmin" & @CRLF) EndIf $sAccessBridgeDLL = (@AutoItX64) ? "WindowsAccessBridge-64.dll" : "WindowsAccessBridge-32.dll" ;~ $sAccessBridgeDLLFull = (@AutoItX64) ? $sJavaHome & "\bin\" & $sAccessBridgeDLL : "C:\Windows\SysWOW64\" & $sAccessBridgeDLL $sAccessBridgeDLLFull = $sJavaHome & "\bin\" & $sAccessBridgeDLL ;~ Open the Dll for accessibility ConsoleWrite("Opening " & $sAccessBridgeDLLFull & @CRLF) $hAccessBridgeDll = DllOpen($sAccessBridgeDLLFull) If $hAccessBridgeDll = True Then ConsoleWrite(" PASS : Windows accessbridge " & $sAccessBridgeDLLFull & " opened returns: " & $hAccessBridgeDll & @CRLF) Else ConsoleWrite(" ERROR: Windows accessbridge " & $sAccessBridgeDLLFull & " opened returns: " & $hAccessBridgeDll & @CRLF) EndIf ;~ TODO: Handle messages received from initialize $result = __Windows_run() ConsoleWrite($result & " " & @error & " initializeAccessBridge is finished") Sleep(250) ConsoleWrite("Windows_run passed :" & $result & @CRLF) EndFunc ;==>_JABInit ;~ _fixBridgeFunc(None,'Windows_run') ;~ Func __Windows_run() ;~ $result = DllCall($hAccessBridgeDll, "NONE", "Windows_run") ;~ If @error Then Return SetError(1, 0, 0) ;~ Return $result[0] ;~ EndFunc ;==>__Windows_run ;~ _fixBridgeFunc(None,'setFocusGainedFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'releaseJavaObject',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getVersionInfo',POINTER(AccessBridgeVersionInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'isJavaWindow',HWND) ;~ _fixBridgeFunc(BOOL,'isSameObject',c_long,JOBJECT64,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextFromHWND',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(HWND,'getHWNDFromAccessibleContext',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextAt',c_long,JOBJECT64,jint,jint,POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextWithFocus',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleParentFromContext',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getAccessibleRelationSet',c_long,JOBJECT64,POINTER(AccessibleRelationSetInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextInfo',c_long,JOBJECT64,POINTER(AccessibleTextInfo),jint,jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextItems',c_long,JOBJECT64,POINTER(AccessibleTextItemsInfo),jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextSelectionInfo',c_long,JOBJECT64,POINTER(AccessibleTextSelectionInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextAttributes',c_long,JOBJECT64,jint,POINTER(AccessibleTextAttributesInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextLineBounds',c_long,JOBJECT64,jint,POINTER(jint),POINTER(jint),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextRange',c_long,JOBJECT64,jint,jint,POINTER(c_wchar),c_short,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getCurrentAccessibleValueFromContext',c_long,JOBJECT64,POINTER(c_wchar),c_short,errcheck=True) ;~ _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(c_int,'getObjectDepth',c_long,JOBJECT64) ;~ _fixBridgeFunc(JOBJECT64,'getActiveDescendent',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'requestFocus',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActions),errcheck=True) ;~ _fixBridgeFunc(BOOL,'doAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActionsToDo),POINTER(jint),errcheck=True) ;~ By inspecting the WindowsAccessBridge-32.dll it reveals some information about the hidden dialogs ;~ So it seems the hidden dialog is shown after you call windows_run() no clue if interaction is needed ;~ ;~ Somehow it sends a message unclear if this is to the JVM to respond to ;~ push SSZ6E73E320_AccessBridge_FromJava_Hello ;~ push SSZ6E73E300_AccessBridge_FromWindows_Hello ;~ db 'AccessBridge-FromWindows-Hello',0 ;~ db 'AccessBridge-FromJava-Hello',0 ;~ JABHANDLER.PY is a usefull source to study on internet ;~ ******* ;~ Every AccessibleContext IntPtr must be replaced by long, including but not limited to getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromContext, getAccessibleTextInf ;~ JOBJECT64 is defined as jlong on 64-bit systems and jobject on legacy versions of Java Access Bridge. For definitions, see the section ACCESSBRIDGE_ARCH_LEGACY in the AccessBridgePackages.h header file. ;~ #ifdef ACCESSBRIDGE_ARCH_LEGACY ;~ typedef jobject JOBJECT64; ;~ typedef HWND ABHWND64; ;~ #define ABHandleToLong ;~ #define ABLongToHandle ;~ #else ;~ typedef jlong JOBJECT64; ;~ typedef long ABHWND64; ;~ #define ABHandleToLong HandleToLong ;~ #define ABLongToHandle LongToHandle ;~ #endif ;~ a jobject is a 32 bit pointer for 32 bit builds ;~ 'bool' is a built-in C++ type while 'BOOL' is a Microsoft specific type that is defined as an 'int'. You can find it in 'windef.h' ;~ ;~ ** jni_md.h ** ;~ typedef long jint; ;~ typedef __int64 jlong; ;~ typedef signed char jbyte; ;~ ******* ;~ accessbridgecalls.h ;~ typedef JOBJECT64 AccessibleContext; ;~ typedef JOBJECT64 AccessibleText; ;~ typedef JOBJECT64 AccessibleValue; ;~ typedef JOBJECT64 AccessibleSelection; ;~ typedef JOBJECT64 Java_Object; ;~ typedef JOBJECT64 PropertyChangeEvent; ;~ typedef JOBJECT64 FocusEvent; ;~ typedef JOBJECT64 CaretEvent; ;~ typedef JOBJECT64 MouseEvent; ;~ typedef JOBJECT64 MenuEvent; ;~ typedef JOBJECT64 AccessibleTable; ;~ typedef JOBJECT64 AccessibleHyperlink; ;~ typedef JOBJECT64 AccessibleHypertext; ;~ #Appropriately set the return and argument types of all the access bridge dll functions ;~ if bridgeDll: ;~ _fixBridgeFunc(None,'Windows_run') ;~ _fixBridgeFunc(None,'setFocusGainedFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'releaseJavaObject',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getVersionInfo',POINTER(AccessBridgeVersionInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'isJavaWindow',HWND) ;~ _fixBridgeFunc(BOOL,'isSameObject',c_long,JOBJECT64,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextFromHWND',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(HWND,'getHWNDFromAccessibleContext',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextAt',c_long,JOBJECT64,jint,jint,POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextWithFocus',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleParentFromContext',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'getAccessibleRelationSet',c_long,JOBJECT64,POINTER(AccessibleRelationSetInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextInfo',c_long,JOBJECT64,POINTER(AccessibleTextInfo),jint,jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextItems',c_long,JOBJECT64,POINTER(AccessibleTextItemsInfo),jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextSelectionInfo',c_long,JOBJECT64,POINTER(AccessibleTextSelectionInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextAttributes',c_long,JOBJECT64,jint,POINTER(AccessibleTextAttributesInfo),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextLineBounds',c_long,JOBJECT64,jint,POINTER(jint),POINTER(jint),errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleTextRange',c_long,JOBJECT64,jint,jint,POINTER(c_wchar),c_short,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getCurrentAccessibleValueFromContext',c_long,JOBJECT64,POINTER(c_wchar),c_short,errcheck=True) ;~ _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True) ;~ _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(c_int,'getObjectDepth',c_long,JOBJECT64) ;~ _fixBridgeFunc(JOBJECT64,'getActiveDescendent',c_long,JOBJECT64) ;~ _fixBridgeFunc(BOOL,'requestFocus',c_long,JOBJECT64,errcheck=True) ;~ _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True) ;~ _fixBridgeFunc(BOOL,'getAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActions),errcheck=True) ;~ _fixBridgeFunc(BOOL,'doAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActionsToDo),POINTER(jint),errcheck=True) ;~ Primitive Types and Native Equivalents ;~ Java Type Native Type Description ;~ boolean jboolean unsigned 8 bits ;~ byte jbyte signed 8 bits ;~ char jchar unsigned 16 bits ;~ short jshort signed 16 bits ;~ int jint signed 32 bits ;~ long jlong signed 64 bits ;~ float jfloat 32 bits ;~ double jdouble 64 bits ;~ void void not applicable ;~ Copied from this NVDA reference and translated to AutoIT ;~ http://www.webbie.org.uk/nvda/api/JABHandler-pysrc.html ;~ ;~ def initialize(): ;~ global isRunning ;~ if not bridgeDll: ;~ raise NotImplementedError("dll not available") ;~ bridgeDll.Windows_run() ;~ #Accept wm_copydata and any wm_user messages from other processes even if running with higher privilages ;~*** ChangeWindowMessageFilter=getattr(windll.user32,'ChangeWindowMessageFilter',None) ;~*** if ChangeWindowMessageFilter: ;~*** if not ChangeWindowMessageFilter(winUser.WM_COPYDATA,1): ;~*** raise WinError() ;~*** for msg in xrange(winUser.WM_USER+1,65535): ;~*** if not ChangeWindowMessageFilter(msg,1): ;~*** raise WinError() ;~ #Register java events ;~ bridgeDll.setFocusGainedFP(internal_event_focusGained) ;~ bridgeDll.setPropertyActiveDescendentChangeFP(internal_event_activeDescendantChange) ;~ bridgeDll.setPropertyNameChangeFP(event_nameChange) ;~ bridgeDll.setPropertyDescriptionChangeFP(event_descriptionChange) ;~ bridgeDll.setPropertyValueChangeFP(event_valueChange) ;~ bridgeDll.setPropertyStateChangeFP(internal_event_stateChange) ;~ bridgeDll.setPropertyCaretChangeFP(internal_event_caretChange) ;~ isRunning=True ;create the structs ;~ ;~ http://docs.oracle.com/javase/accessbridge/2.0.2/api.htm ;~ ;~ #define MAX_STRING_SIZE 1024 ;~ #define SHORT_STRING_SIZE 256 ;~ struct AccessBridgeVersionInfo { ;~ wchar_t VMversion[SHORT_STRING_SIZE]; // version of the Java VM ;~ wchar_t bridgeJavaClassVersion[SHORT_STRING_SIZE]; // version of the AccessBridge.class ;~ wchar_t bridgeJavaDLLVersion[SHORT_STRING_SIZE]; // version of JavaAccessBridge.dll ;~ wchar_t bridgeWinDLLVersion[SHORT_STRING_SIZE]; // version of WindowsAccessBridge.dll ;~ }; ;~ struct AccessibleContextInfo { ;~ wchar_ name[MAX_STRING_SIZE]; // the AccessibleName of the object ;~ wchar_ description[MAX_STRING_SIZE]; // the AccessibleDescription of the object ;~ wchar_ role[SHORT_STRING_SIZE]; // localized AccesibleRole string ;~ wchar_ states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string ;~ // (comma separated) ;~ jint indexInParent // index of object in parent ;~ jint childrenCount // # of children, if any ;~ jint x; // screen x-axis co-ordinate in pixels ;~ jint y; // screen y-axis co-ordinate in pixels ;~ jint width; // pixel width of object ;~ jint height; // pixel height of object ;~ BOOL accessibleComponent; // flags for various additional ;~ BOOL accessibleAction; // Java Accessibility interfaces ;~ BOOL accessibleSelection; // FALSE if this object doesn't ;~ BOOL accessibleText; // implement the additional interface ;~ BOOL accessibleInterfaces; // new bitfield containing additional ;~ // interface flags ;~ }; ;~ typedef struct AccessibleContextInfoTag { ;~ wchar_t name[MAX_STRING_SIZE]; // the AccessibleName of the object ;~ wchar_t description[MAX_STRING_SIZE]; // the AccessibleDescription of the object ;~ wchar_t role[SHORT_STRING_SIZE]; // localized AccesibleRole string ;~ wchar_t role_en_US[SHORT_STRING_SIZE]; // AccesibleRole string in the en_US locale ;~ wchar_t states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string (comma separated) ;~ wchar_t states_en_US[SHORT_STRING_SIZE]; // AccesibleStateSet string in the en_US locale (comma separated) ;~ jint indexInParent; // index of object in parent ;~ jint childrenCount; // # of children, if any ;~ jint x; // screen coords in pixels ;~ jint y; // " ;~ jint width; // pixel width of object ;~ jint height; // pixel height of object ;~ BOOL accessibleComponent; // flags for various additional ;~ BOOL accessibleAction; // Java Accessibility interfaces ;~ BOOL accessibleSelection; // FALSE if this object doesn't ;~ BOOL accessibleText; // implement the additional interface ;~ // in question ;~ // BOOL accessibleValue; // old BOOL indicating whether AccessibleValue is supported ;~ BOOL accessibleInterfaces; // new bitfield containing additional interface flags ;~ } AccessibleContextInfo; Local $hwnd Local $i Local $result Local $vmID Local $ac ;~ //TODO: Check if needed ;~ Make messages elevated ;~ _ChangeWindowMessageFilter($WM_COPYDATA,1) ;~ for $i=$WM_USER to $WM_USER+65536 ;~ _ChangeWindowMessageFilter($i, 1) ;~ Next ;~ Func _ChangeWindowMessageFilter($iMsg, $iAction) ;~ Local $aCall = DllCall("user32.dll", "bool", "ChangeWindowMessageFilter", "dword", $iMsg, "dword", $iAction) ;~ If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ;~ Return 1 ;~ EndFunc ;~ typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); ;~ _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True) ;~ Func __getTopLevelObject($vmID, $ac) ;~ Seems not to be allowed to call with null so passing $acParent ;~ $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getTopLevelObject", "long", $vmID, $c_JOBJECT64, $ac) ;~ If @error Then Return SetError(1, 0, 0) ;~ Return $result[0] ;~ EndFunc ;==>__getTopLevelObject ;~ typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i); ;~ typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac); ;~ typedef AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True) ;~ Returns an AccessibleContext object that represents the nth child of the object ac, where n is specified by the value index. #cs Func __getAccessibleChildFromContext($vmID, $ac, $index) ;~ Seems not to be allowed to call with null so passing $acParent $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleChildFromContext", "long", $vmID, $c_JOBJECT64, $ac, "int", $index) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;==>__getAccessibleChildFromContext ;~ _fixBridgeFunc(JOBJECT64,'getActiveDescendent',c_long,JOBJECT64) Func __getActiveDescendent($vmID, $ac) ;~ Seems not to be allowed to call with null so passing $acParent $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getActiveDescendent", "long", $vmID, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;==>__getActiveDescendent ;~ _fixBridgeFunc(BOOL,'getAccessibleContextAt',c_long,JOBJECT64,jint,jint,POINTER(JOBJECT64),errcheck=True) ;~ BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, jint x, jint y, AccessibleContext *ac) Func __getAccessibleContextAt($vmID, $acParent, $x, $y, ByRef $ac) ;~ Seems not to be allowed to call with null so passing $acParent consolewrite("BREAKING: AcceccibleContextAt 1 " & $c_JOBJECT64 & @CRLF) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextAt", "long", $vmID, $c_JOBJECT64, $acParent, "int", $x, "int", $y, $cP_JOBJECT64, $ac) consolewrite("PASSED : AcceccibleContextAt 2 " & @CRLF) ConsoleWrite(@error) If @error Then Return SetError(1, 0, 0) consolewrite("AcceccibleContextAt 3 ") ConsoleWrite("hello") $ac = $result[5] Return $result[0] EndFunc ;==>__getAccessibleContextAt #ce Func _Example1_IterateJavaWindows() ;~ Just check all windows if its a java window Local $var = WinList() ConsoleWrite("Before checking all Windows: " & $var[0][0] & @CRLF) For $i = 1 To $var[0][0] ; Only display visble windows that have a title If IsVisible($var[$i][1]) Then Local $handle = WinGetHandle($var[$i][0]) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "isJavaWindow", "hwnd", $handle) If @error = 0 Then If $result[0] = 1 Then ConsoleWrite(" JAVA window found <" & $i & "> Java Window Title=" & $var[$i][0] & " Handle=" & $var[$i][1] & @TAB & " res: " & $result[0] & @CRLF) Local $acParent = 0 Local $vmID = 0 ;~AccessibilityContext (acParent above), which I had incorrectly mapped as an IntPtr, is actually an Int32 when using the "legacy" WindowsAccessBridge.dll library (used under x86), ;~and an Int64 when using the WOW64 WindowsAccessBridge-32.dll library. ;~WindowsAccessBridge-32.dll bool getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out Int64 acParent); ;~WindowsAccessBridge.dll bool _getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out Int32 acParent); ;~ _fixBridgeFunc(BOOL,'getAccessibleContextFromHWND',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextFromHWND", "hwnd", $handle, "long*", $vmID, "UINT64*", $acParent) ;~ $result =dllcall($hAccessBridgeDll,"BOOL:cdecl", "getAccessibleContextFromHWND", "hwnd", $handle, "long*", $vmID, "ptr*", $acParent) ;~ $result =dllcall($hAccessBridgeDll,"BOOL:cdecl", "getAccessibleContextFromHWND", "hwnd", $handle, "long*", $vmID, "INT64*", $acParent) If @error = 0 Then ConsoleWrite("Result getAccessibleContextFromHWND is <" & $result & "> ubound: " & UBound($result) & @CRLF) $vmID = $result[2] $acParent = $result[3] ConsoleWrite(" We have a VMid " & $vmID & " ac " & $acParent & @CRLF) ;~ $result =dllcall($hAccessBridgeDll, "BOOL:cdecl", "getVersionInfo", "long", $vmId, "struct", $AccessBridgeVersionInfo) ;~ typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info); $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getVersionInfo", "long", $vmID, "struct*", DllStructGetPtr($tAccessBridgeVersionInfo)) If @error = 0 Then $s1 = DllStructGetData($tAccessBridgeVersionInfo, "VMVersion") $s2 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeJavaClassVersion") $s3 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeJavaDLLVersion") $s4 = DllStructGetData($tAccessBridgeVersionInfo, "bridgeWinDLLVersion") ConsoleWrite("Call version info: PASSED VMID found : " & $vmID & @CRLF) ConsoleWrite(" VMVersion: <" & $s1 & ">" & @CRLF) ConsoleWrite(" bridgeJavaClassVersion: <" & $s2 & ">" & @CRLF) ConsoleWrite(" bridgeJavaDLLVersion: <" & $s3 & ">" & @CRLF) ConsoleWrite(" bridgeWinDLLVersion: <" & $s4 & ">" & @CRLF) Else ConsoleWrite("getVersionInfo error:" & @error & @CRLF) EndIf ;~ /** ;~ * Returns the Accessible Context for the top level object in ;~ * a Java Window. This is same Accessible Context that is obtained ;~ * from GetAccessibleContextFromHWND for that window. Returns ;~ * (AccessibleContext)0 on error. ;~ */ ;~ AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); ;~ typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); ;~ _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True) Local $topAC = __getTopLevelObject($vmID, $acParent) If @error = 0 Then ConsoleWrite(" *** getTopLevelObject Result is <" & $topAC & "> " & @CRLF) ;~ $vmID=$result[1] ;~ local $tPtr = DllStructCreate( "ptr", $result[0] ) ;~ local $ptr = DllStructGetData( $tPtr,1 ) ;~ local $topAC = $result ;~ DllStructCreate( $tagAccessibleContextInfo, $ptr ) ;~ Local $topAC=DllStructCreate($tagAccessibleContextInfo,DllStructGetPtr($result[0])) ;~ Local $topAC=DllStructCreate($tagAccessibleContextInfo,$result[0]) ;~ dllstructsetdata($topAC,-1,$result[0] ConsoleWrite("We have a VMid " & $vmID & " toplevel object ac " & $topAC & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $topAC, "struct*", $tAccessibleContextInfo) $AccessibleContextInfo = $result[3] ConsoleWrite(getDescription($AccessibleContextInfo)) ConsoleWrite("End of top level object info" & @CRLF) $childAC = __getAccessibleChildFromContext($vmID, $topAC, 0) ConsoleWrite(" *** getAccessibleChildFromContext Result is <" & $childAC & "> " & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $childAC, "struct*", $tAccessibleContextInfo) $AccessibleContextInfo = $result[3] ConsoleWrite(getDescription($AccessibleContextInfo)) ConsoleWrite("End of getAccessibleChild object info" & @CRLF) $descentAC = __getActiveDescendent($vmID, $topAC) ConsoleWrite(" *** getActiveDescendent Result is <" & $descentAC & "> " & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $descentAC, "struct*", $tAccessibleContextInfo) $AccessibleContextInfo = $result[3] ConsoleWrite(getDescription($AccessibleContextInfo)) ConsoleWrite("End of getActiveDescendent object info" & @CRLF) Else ConsoleWrite("getTopLevelObjecterror:" & @error & @CRLF) _WinAPI_DisplayStruct($topAC, $tagAccessibleContextInfo) EndIf ConsoleWrite(" We still have a VMid " & $vmID & " acParent " & $acParent & @CRLF) ;~ Retrieves an AccessibleContextInfo object of the AccessibleContext object ac. ;~ $result =dllcall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo","long", $vmId, "ptr", $ac, "ptr", DllStructGetPtr($AccessibleContextInfo)) ;~ typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info); ;~ _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True) ;~ $result =dllcall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo","INT64", $vmId, "int", $ac, "ptr*", DllStructGetPtr($AccessibleContextInfo)) ;~ $result =dllcall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo","long", $vmId, "long", $ac, "ptr", DllStructGetPtr($AccessibleContextInfo),DllStructGetSize($AccessibleContextInfo)) ;~ $result =dllcall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo","long", $vmId, "INT64", $acParent, "struct*", DllStructGetPtr($AccessibleContextInfo)) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $acParent, "struct*", $tAccessibleContextInfo) If @error <> 0 Then ConsoleWrite("We have an error " & @error & @CRLF) EndIf ;~ We should pass it by reference ;~ Exception code c0000005 is an access violation, also known as general protection fault. The program is reading from, or writing to, an address which is not part of the virtual address space. ;~ A very common cause is that you are de-referencing a stale pointer. In other words, the pointer was once valid, but you have subsequently freed it. Then later when you attempt to access it, ;~ an exception is raised. ;~ The problem is don't use out parameter. Use the IntPtr. ;~ So it should be getAccessibleContextInfo(Int32 vmID, IntPtr accessibleContext, IntPtr acInfo) ConsoleWrite("Result is <" & $result & "> ubound: " & UBound($result) & @CRLF) $AccessibleContextInfo = $result[3] _WinAPI_DisplayStruct($tAccessibleContextInfo, $tagAccessibleContextInfo) ConsoleWrite(getDescription($AccessibleContextInfo)) $s9 = DllStructGetData($AccessibleContextInfo, "x") $s10 = DllStructGetData($AccessibleContextInfo, "y") $s11 = DllStructGetData($AccessibleContextInfo, "width") $s12 = DllStructGetData($AccessibleContextInfo, "height") ConsoleWrite(" We still have before getAccessible Child FromContext a VMid " & $vmID & " acParent " & $acParent & @CRLF) ConsoleWrite("rect:" & $s9 & $s9 + $s11 & $s10 & $s10 + $s12) _UIA_DrawRect($s9, $s9 + $s11, $s10, $s10 + $s12) Sleep(3000) ;~ AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); ;~ _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True) ;~ Returns an AccessibleContext object that represents the nth child of the object ac, where n is specified by the value index. $childAC = __getAccessibleChildFromContext($vmID, $topAC, 0) ConsoleWrite(" *** getAccessibleChildFromContext Result is <" & $childAC & "> " & @CRLF) $result = DllCall($hAccessBridgeDll, "BOOL:cdecl", "getAccessibleContextInfo", "long", $vmID, "long", $childAC, "struct*", $tAccessibleContextInfo) $AccessibleContextInfo = $result[3] ConsoleWrite(getDescription($AccessibleContextInfo)) ConsoleWrite("End of getAccessibleChild object info" & @CRLF) _WinAPI_DisplayStruct($tAccessibleContextInfo, $tagAccessibleContextInfo) ;~ memcpy(tData->ResponceHTML, m_pResponse, INT_BUFFERSIZE); ConsoleWrite(getDescription($AccessibleContextInfo)) Else ConsoleWrite(@error & " No context found" & @CRLF) EndIf EndIf Else EndIf EndIf Next EndFunc ;==>_Example1_IterateJavaWindows ;~ http://www.autohotkey.com/board/topic/95343-how-to-send-to-unseen-controls-in-a-java-app/ Func _JABShutDown() Local $result $result = DllCall($hAccessBridgeDll, "BOOL", "shutdownAccessBridge") EndFunc ;==>_JABShutDown Func IsVisible($handle) If BitAND(WinGetState($handle), 2) Then Return 1 Else Return 0 EndIf EndFunc ;==>IsVisible ; Draw rectangle on screen. Func _UIA_DrawRect($tLeft, $tRight, $tTop, $tBottom, $color = 0xFF, $PenWidth = 4) Local $hDC, $hPen, $obj_orig, $x1, $x2, $y1, $y2 $x1 = $tLeft $x2 = $tRight $y1 = $tTop $y2 = $tBottom $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop) $hPen = _WinAPI_CreatePen($PS_SOLID, $PenWidth, $color) $obj_orig = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_DrawLine($hDC, $x1, $y1, $x2, $y1) ; horizontal to right _WinAPI_DrawLine($hDC, $x2, $y1, $x2, $y2) ; vertical down on right _WinAPI_DrawLine($hDC, $x2, $y2, $x1, $y2) ; horizontal to left right _WinAPI_DrawLine($hDC, $x1, $y2, $x1, $y1) ; vertical up on left ; clear resources _WinAPI_SelectObject($hDC, $obj_orig) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc ;==>_UIA_DrawRect Func getDescription($ac) $s1 = DllStructGetData($ac, "name") $s2 = DllStructGetData($ac, "description") $s3 = DllStructGetData($ac, "role") $s4 = DllStructGetData($ac, "role_en_US") $s5 = DllStructGetData($ac, "states") $s6 = DllStructGetData($ac, "states_en_US") $s7 = DllStructGetData($ac, "indexInParent") $s8 = DllStructGetData($ac, "childrenCount") $s9 = DllStructGetData($ac, "x") $s10 = DllStructGetData($ac, "y") $s11 = DllStructGetData($ac, "width") $s12 = DllStructGetData($ac, "height") $s13 = DllStructGetData($ac, "accessibleComponent") $s14 = DllStructGetData($ac, "accessibleAction") ConsoleWrite(" name: <" & $s1 & ">" & @CRLF) ConsoleWrite(" description: <" & $s2 & ">" & @CRLF) ConsoleWrite(" role: <" & $s3 & ">" & @CRLF) ConsoleWrite(" role_en_US: <" & $s4 & ">" & @CRLF) ConsoleWrite(" states: <" & $s5 & ">" & @CRLF) ConsoleWrite(" states_en_US: <" & $s6 & ">" & @CRLF) ConsoleWrite(" indexInParent: <" & $s7 & ">" & @CRLF) ConsoleWrite(" childrenCount: <" & $s8 & ">" & @CRLF) ConsoleWrite(" x: <" & $s9 & ">" & @CRLF) ConsoleWrite(" y: <" & $s10 & ">" & @CRLF) ConsoleWrite(" width: <" & $s11 & ">" & @CRLF) ConsoleWrite(" height: <" & $s12 & ">" & @CRLF) ConsoleWrite(" accessibleComponent: <" & $s13 & ">" & @CRLF) ConsoleWrite(" accessibleAction: <" & $s14 & ">" & @CRLF) Return $s1 & @CRLF & $s2 & @CRLF & $s3 & @CRLF & $s4 & @CRLF & $s5 & @CRLF & $s6 & @CRLF & $s7 & @CRLF & $s8 & @CRLF & $s9 & @CRLF & $s10 & @CRLF & $s11 & @CRLF & $s12 & @CRLF & $s13 & @CRLF & $s14 & @CRLF EndFunc ;==>getDescription Source JAVAUI.au3 ;~ ******* ;~ Every AccessibleContext IntPtr must be replaced by long, including but not limited to getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromContext, getAccessibleTextInf ;~ JOBJECT64 is defined as jlong on 64-bit systems and jobject on legacy versions of Java Access Bridge. For definitions, see the section ACCESSBRIDGE_ARCH_LEGACY in the AccessBridgePackages.h header file. ;~ #ifdef ACCESSBRIDGE_ARCH_LEGACY ;~ typedef jobject JOBJECT64; ;~ typedef HWND ABHWND64; ;~ #else ;~ typedef jlong JOBJECT64; ;~ typedef long ABHWND64; ;~ #endif ;~ a jobject is a 32 bit pointer for 32 bit builds ;~ 'bool' is a built-in C++ type while 'BOOL' is a Microsoft specific type that is defined as an 'int'. You can find it in 'windef.h' ;~ ;~ ** jni_md.h ** ;~ typedef long jint; ;~ typedef __int64 jlong; ;~ typedef signed char jbyte; ;~ ******* ;~ accessbridgecalls.h ;~ typedef JOBJECT64 AccessibleContext; ;~ typedef JOBJECT64 AccessibleText; ;~ typedef JOBJECT64 AccessibleValue; ;~ typedef JOBJECT64 AccessibleSelection; ;~ typedef JOBJECT64 Java_Object; ;~ typedef JOBJECT64 PropertyChangeEvent; ;~ typedef JOBJECT64 FocusEvent; ;~ typedef JOBJECT64 CaretEvent; ;~ typedef JOBJECT64 MouseEvent; ;~ typedef JOBJECT64 MenuEvent; ;~ typedef JOBJECT64 AccessibleTable; ;~ typedef JOBJECT64 AccessibleHyperlink; ;~ typedef JOBJECT64 AccessibleHypertext; ;~ Primitive Types and Native Equivalents ;~ Java Type Native Type Description ;~ boolean jboolean unsigned 8 bits ;~ byte jbyte signed 8 bits ;~ char jchar unsigned 16 bits ;~ short jshort signed 16 bits ;~ int jint signed 32 bits ;~ long jlong signed 64 bits ;~ float jfloat 32 bits ;~ double jdouble 64 bits ;~ void void not applicable ;#AutoIt3Wrapper_UseX64 = y #include <array.au3> Global Const $c_JOBJECT64 = "UINT64" ;~ JOBJECT64 Global Const $cP_JOBJECT64 = "UINT64*" ;~ POINTER(JOBJECT64) ;=====================================Accessibility information================================ Global Const $MAX_BUFFER_SIZE = 10240 Global Const $MAX_STRING_SIZE = 1024 Global Const $SHORT_STRING_SIZE = 256 Global Const $tagAccessBridgeVersionInfo = _ "WCHAR VMversion[256];" & _ ; output of "java -version" "WCHAR bridgeJavaClassVersion[256];" & _ ; version of the AccessBridge.class "WCHAR bridgeJavaDLLVersion[256];" & _ ; version of JavaAccessBridge.dll "WCHAR bridgeWinDLLVersion[256]" ; version of WindowsAccessBridge.dll Global Const $tagAccessibleContextInfo = _ "WCHAR name[1024];" & _ ; the AccessibleName of the object "WCHAR description[1024];" & _ ; the AccessibleDescription of the object "WCHAR role[256];" & _ ; localized AccesibleRole string "WCHAR role_en_US[256];" & _ ; AccesibleRole string in the en_US locale "WCHAR states[256];" & _ ; localized AccesibleStateSet string (comma separated) "WCHAR states_en_US[256];" & _ ; AccesibleStateSet string in the en_US locale (comma separated) "INT indexInParent;" & _ ; index of object in parent "INT childrenCount;" & _ ; # of children, if any "INT x;" & _ ; screen x-axis co-ordinate in pixels "INT y;" & _ ; screen y-axis co-ordinate in pixels "INT width;" & _ ; pixel width of object "INT height;" & _ ; pixel height of object "BOOL accessibleComponent;" & _ ; flags for various additional Java Accessibility interfaces "BOOL accessibleAction;" & _ "BOOL accessibleSelection;" & _ ; FALSE if this object does not implement the additional interface in question "BOOL accessibleText;" & _ "BOOL accessibleInterfaces" ; new bitfield containing additional interface flags Global Const $tagAccessibleTextInfo = _ "INT charCount;" & _ ; # of characters in this text object "INT caretIndex;" & _ ; index of caret "INT indexAtPoint" ; index at the passsed in point Global Const $tagAccessibleTextItemsInfo = _ "WCHAR letter;" & _ "WCHAR word[256];" & _ "WCHAR sentence[1024]" Global Const $tagAccessibleTextSelectionInfo = _ "INT selectionStartIndex;" & _ "INT selectionEndIndex;" & _ "WCHAR selectedText[1024]" Global Const $tagAccessibleTextRectInfo = _ "INT x;" & _ ; bounding recttangle of char at index, x-axis co-ordinate "INT y;" & _ ; y-axis co-ordinate "INT width;" & _ ; bounding rectangle width "INT height" ; bounding rectangle height Global Const $tagAccessibleTextAttributesInfo = _ "BOOL bold;" & _ "BOOL italic;" & _ "BOOL underline;" & _ "BOOL strikethrough;" & _ "BOOL superscript;" & _ "BOOL subscript;" & _ "WCHAR backgroundColor[256];" & _ "WCHAR foregroundColor[256];" & _ "WCHAR fontFamily[256];" & _ "INT fontSize;" & _ "INT alignment;" & _ "INT bidiLevel;" & _ "FLOAT firstLineIndent;" & _ "FLOAT LeftIndent;" & _ "FLOAT rightIndent;" & _ "FLOAT lineSpacing;" & _ "FLOAT spaceAbove;" & _ "FLOAT spaceBelow;" & _ "WCHAR fullAttributesString[1024]" ;=====================================AccessibleTable================================ Global Const $MAX_TABLE_SELECTIONS = 64 Global Const $tagAccessibleTableInfo = _ "UINT64 caption;" & _ ; AccessibleContext "UINT64 summary;" & _ ; AccessibleContext "INT rowCount;" & _ "INT columnCount;" & _ "UINT64 accessibleContext;" & _ "UINT64 accessibleTable" Global Const $tagAccessibleTableCellInfo = _ "UINT64 accessibleContext;" & _ "INT index;" & _ "INT row;" & _ "INT column;" & _ "INT rowExtent;" & _ "INT columnExtent;" & _ "BOOL isSelected" ;=====================================AccessibleRelationSet================================ Global Const $MAX_RELATION_TARGETS = 25 Global Const $MAX_RELATIONS = 5 Global Const $tagAccessibleRelationInfo = _ "WCHAR key[256];" & _ "INT targetCount;" & _ "UINT64 targets[25]" ; AccessibleContexts Local $tag_Relations = "" For $i = 1 To 5 If $tag_Relations = "" Then $tag_Relations = $tagAccessibleRelationInfo Else $tag_Relations = $tag_Relations & ";" & $tagAccessibleRelationInfo EndIf Next Global Const $tagAccessibleRelationSetInfo = _ "INT relationCount;" & _ $tag_Relations ; $tAccessibleRelationInfo relations[5] ;=====================================AccessibleHypertext================================ Global Const $MAX_HYPERLINKS = 64 ;~ maximum number of hyperlinks returned Global Const $tagAccessibleHyperlinkInfo = _ "WCHAR text[256];" & _ ; the hyperlink text "INT startIndex;" & _ ; index in the hypertext document where the link begins "INT endIndex;" & _ ; index in the hypertext document where the link ends "UINT64 accessibleHyperlink" ; AccessibleHyperlink object Local $tag_Links = "" For $i = 1 To 64 If $tag_Links = "" Then $tag_Links = $tagAccessibleHyperlinkInfo Else $tag_Links = $tag_Links & ";" & $tagAccessibleHyperlinkInfo EndIf Next Global Const $tagAccessibleHypertextInfo = _ "INT linkCount;" & _ ; number of hyperlinks $tag_Links & ";" & _ ; the hyperlinks ,$tAccessibleHyperlinkInfo links[64] "UINT64 accessibleHypertext" ; AccessibleHypertext object ;=====================================Accessible Key Bindings================================ Global Const $MAX_KEY_BINDINGS = 8 Global Const $tagAccessibleKeyBindingInfo = _ "WCHAR character;" & _ ; the key character "INT modifiers" ; the key modifiers Local $tag_KeyBindingInfo = "" For $i = 1 To 8 If $tag_KeyBindingInfo = "" Then $tag_KeyBindingInfo = $tagAccessibleKeyBindingInfo Else $tag_KeyBindingInfo = $tag_KeyBindingInfo & ";" & $tagAccessibleKeyBindingInfo EndIf Next Global Const $tagAccessibleKeyBindings = _ "INT keyBindingsCount;" & _ ; number of key bindings $tag_KeyBindingInfo ; $tAccessibleKeyBindingInfo keyBindingInfo[8] ;=====================================AccessibleIcon================================ Global Const $MAX_ICON_INFO = 8 Global Const $tagAccessibleIconInfo = _ "WCHAR description[256];" & _ ; icon description "INT height;" & _ ; icon height "INT width" ; icon width Local $tag_IconInfo = "" For $i = 1 To 8 If $tag_IconInfo = "" Then $tag_IconInfo = $tagAccessibleIconInfo Else $tag_IconInfo = $tag_IconInfo & ";" & $tagAccessibleIconInfo EndIf Next Global Const $tagAccessibleIcon = _ "INT iconsCount;" & _ ; number of icons $tag_IconInfo ; the icons ,$tAccessibleIconInfo iconInfo[8] ;=====================================AccessibleAction================================ Global Const $MAX_ACTION_INFO = 256 Global Const $MAX_ACTIONS_TO_DO = 32 Global Const $tagAccessibleActionInfo = _ "WCHAR name[256]" Local $tag_ActionInfo = "" For $i = 1 To 256 If $tag_ActionInfo = "" Then $tag_ActionInfo = $tagAccessibleActionInfo Else $tag_ActionInfo = $tag_ActionInfo & ";" & $tagAccessibleActionInfo EndIf Next Global Const $tagAccessibleActions = _ "INT actionsCount;" & _ $tag_ActionInfo ; $tAccessibleActionInfo actionInfo[256] Local $tag_Actions = "" For $i = 1 To 32 If $tag_Actions = "" Then $tag_Actions = $tagAccessibleActionInfo Else $tag_Actions = $tag_Actions & ";" & $tagAccessibleActionInfo EndIf Next Global Const $tagAccessibleActionsToDo = _ "INT actionsCount;" & _ $tag_Actions ; $tAccessibleActions actions[32] ;=====================================VisibleChilden================================ Global Const $MAX_VISIBLE_CHILDREN = 256 Global Const $tagVisibleChildenInfo = _ "INT returnedChildrenCount;" & _ ; number of children returned "UINT64 children[256]" ; the visible children Global $hAccessBridgeDll ;~ reference to the accessbridge dll _JAB_init() Func _JAB_init() ;~ Determine java location Local $sJavaVersion Local $sJavaHome Local $sAccessBridgeDLL If @AutoItX64 <> 1 Then Local $sJavaReg = "HKLM\SOFTWARE\JavaSoft\Java Runtime Environment" $sJavaVersion = RegRead($sJavaReg, "CurrentVersion") $sJavaHome = RegRead($sJavaReg & "\" & $sJavaVersion, "JavaHome") ElseIf @AutoItX64 = 1 Then Local $sJavaReg64 = "HKLM64\SOFTWARE\JavaSoft\Java Runtime Environment" Local $sJavaReg32 = "HKLM64\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment" $sJavaVersion = RegRead(((@AutoItX64) ? $sJavaReg64 : $sJavaReg32 ), "CurrentVersion") $sJavaHome = RegRead(((@AutoItX64) ? $sJavaReg64 : $sJavaReg32 ) & "\" & $sJavaVersion, "JavaHome") EndIf If $sJavaHome = "" Then consolewrite(" Unable to find Java Registry using hardcoded value" & @CRLF) $sJavaHome = "C:\Program Files\Java\jdk1.8.0_172\jre" EndIf consolewrite(" Java Home: " & $sJavaHome & @CRLF) ;~ TODO: Check which dll that Autoit can work with, still can't find eazy way to work with both dlls consolewrite(" We are using OS " & @OSArch & " at cpu " & @CPUArch & "; Autoit 64 bit version @AutoItX64="& @AutoItX64 & @CRLF) ;~ Only Autoit 64 bit version can open WindowsAccessBridge-64.dll, so use @AutoItX64 to decide which WindowsAccessBridge can be opened $sAccessBridgeDLL = (@AutoItX64) ? "WindowsAccessBridge-64.dll" : "WindowsAccessBridge-32.dll" ;~ Open the Dll for accessibility consolewrite($sJavaHome & "\bin\" & $sAccessBridgeDLL) $hAccessBridgeDll = DllOpen($sJavaHome & "\bin\" & $sAccessBridgeDLL) If $hAccessBridgeDll <> -1 Then ConsoleWrite(" PASS: Windows accessbridge " & $sAccessBridgeDLL & " opened returns: " & $hAccessBridgeDll & @CRLF) Else ConsoleWrite(" ERROR: Windows accessbridge " & $sAccessBridgeDLL & " open failed returns: " & $hAccessBridgeDll & @CRLF) Return EndIf ;~ Make sure Java Access Bridge is turned on Runwait($sJavaHome & "\bin\jabswitch /enable","",@SW_MAXIMIZE) ;~ TODO: Handle messages received from initialize $result = __Windows_run() consolewrite(@error & " Windows_run returns: " & $result & @CRLF) ;$result = __initializeAccessBridge() ;consolewrite($result & " " & @error & " initializeAccessBridge is finished" & @CRLF) EndFunc Func _JAB_shutDown() __shutdownAccessBridge() EndFunc Func _JAB_getName($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Return DllStructGetData($acInfo, "name") EndFunc Func _JAB_getRole($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Return DllStructGetData($acInfo, "role") EndFunc Func _JAB_getIndexInParent($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Return DllStructGetData($acInfo, "indexInParent") EndFunc Func _JAB_getChildrenCount($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Return DllStructGetData($acInfo, "childrenCount") EndFunc ;~ Must use the AccessibleContext got from the win handle which include the target element Func _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole) Local $find_ac = 0 Local $iCount =_JAB_getChildrenCount($vmId, $ac) If $iCount = 0 Then Return EndIf For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i) Local $s1 = _JAB_getName($vmId, $child_ac) Local $s3 = _JAB_getRole($vmId, $child_ac) ;~ consolewrite($child_ac & "|" & $s1 & "," & $s3 & @CRLF) If $s1 = $sName And $s3 = $sRole Then ;~ consolewrite("FOUND:" & $child_ac & "|" & $s1 & "," & $s3 & @CRLF) $find_ac = $child_ac ExitLoop Else If $find_ac = 0 Then $find_ac = _JAB_getAccessibleContextByFindAll($vmId, $child_ac, $sName, $sRole) EndIf EndIf Next Return $find_ac EndFunc ;~ $next can be negative Func _JAB_getNextSibling($vmId, $ac, $next = 1) If Not IsInt($next) Then consolewrite("_JAB_findNextSibling: $next must be int" & @CRLF) Return EndIf Local $s7 = _JAB_getIndexInParent($vmId, $ac) Local $parent_ac = __getAccessibleParentFromContext($vmId, $ac) Local $parent_s8 = _JAB_getChildrenCount($vmId, $parent_ac) If $s7 + $next >= 0 and $s7 + $next <= $parent_s8 - 1 Then Local $sibling_ac = __getAccessibleChildFromContext($vmId, $parent_ac, $s7 + $next) Return $sibling_ac EndIf EndFunc Func _JAB_getFirstChildByRole($vmId, $ac, $sRole) Local $iCount = _JAB_getChildrenCount($vmId, $ac) consolewrite("Investigating" & $iCount) If $iCount = 0 Then Return EndIf Local $re1 = -1 For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i) Local $child_ac_s3 = _JAB_getRole($vmId, $child_ac) If $child_ac_s3 = $sRole Then $re1 = $child_ac Return $child_ac ExitLoop EndIf Next If $re1 = -1 Then consolewrite("_JAB_getFirstChildByRole: " & $sRole & " is not found" & @CRLF) Return EndIf EndFunc ;~ list element's actions Func _JAB_getAllActions($vmId, $ac) Local $actions = DllStructCreate($tagAccessibleActions) __getAccessibleActions($vmId, $ac, $actions) Local $s1 = DllStructGetData($actions, "actionsCount") If $s1 = 0 Then consolewrite("_JAB_findAllActions: this element has no action" & @CRLF) Return EndIf Local $re = "" For $i = 2 To $s1 + 1 Local $s = $i&"|"&DllStructGetData($actions, $i)&@CRLF If $re = "" Then $re = $s Else $re = $re & $s EndIf Next Return $re EndFunc ;~ Only applicable for single action element like button or check box, menu, menu item Func _JAB_singleAction($vmId, $ac) Local $actions = DllStructCreate($tagAccessibleActions) Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo) __getAccessibleActions($vmId, $ac, $actions) Local $s1 = DllStructGetData($actions, "actionsCount") Local $s2 = DllStructGetData($actions, 2) If $s1 <> 1 Then consolewrite("_JAB_singleAction: Only applicable for single action element like button or check box, menu, menu item" & @CRLF) Return EndIf Local $failure DllStructSetData($actionsToDo, "actionsCount", 1) DllStructSetData($actionsToDo, 2, $s2) __doAccessibleActions($vmId, $ac, $actionsToDo, $failure) EndFunc Func _JAB_setValue($vmId, $ac, $sValue) Local $actions = DllStructCreate($tagAccessibleActions) __getAccessibleActions($vmId, $ac, $actions) Local $s1 = DllStructGetData($actions, "actionsCount") If $s1 = 0 Then consolewrite("_JAB_setValue: this element has no action" & @CRLF) Return EndIf Local $re1 = 0 Local $re2 = 0 For $i = 2 To $s1 + 1 Local $s = DllStructGetData($actions, $i) If $s = "select-all" Then $re1 = 1 ExitLoop EndIf Next If $re1 = 0 Then consolewrite("_JAB_setValue: this element doesn't support select-all action" & @CRLF) Return EndIf For $i = 2 To $s1 + 1 Local $s = DllStructGetData($actions, $i) If $s = "paste-from-clipboard" Then $re2 = 1 ExitLoop EndIf Next If $re2 = 0 Then consolewrite("_JAB_setValue: this element doesn't support paste-from-clipboard action" & @CRLF) Return EndIf Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo) Local $failure ClipPut($sValue) DllStructSetData($actionsToDo, "actionsCount", 2) DllStructSetData($actionsToDo, 2, "select-all") DllStructSetData($actionsToDo, 3, "paste-from-clipboard") __doAccessibleActions($vmId, $ac, $actionsToDo, $failure) EndFunc Func _JAB_getValue($vmId, $ac) Local $actions = DllStructCreate($tagAccessibleActions) __getAccessibleActions($vmId, $ac, $actions) Local $s1 = DllStructGetData($actions, "actionsCount") If $s1 = 0 Then consolewrite("_JAB_getValue: this element has no action" & @CRLF) Return EndIf Local $re1 = 0 For $i = 2 To $s1 + 1 Local $s = DllStructGetData($actions, $i) If $s = "copy-to-clipboard" Then $re1 = 1 ExitLoop EndIf Next If $re1 = 0 Then consolewrite("_JAB_getValue: this element doesn't support copy-to-clipboard action" & @CRLF) Return EndIf ;~ empty the clipboard ClipPut("") Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo) Local $failure DllStructSetData($actionsToDo, "actionsCount", 1) DllStructSetData($actionsToDo, 2, "copy-to-clipboard") __doAccessibleActions($vmId, $ac, $actionsToDo, $failure) Return ClipGet() EndFunc Func _JAB_selectCheckBox($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Local $s3 = DllStructGetData($acInfo, "role") If $s3 <> "check box" Then consolewrite("_JAB_selectCheckBox: this element isn't check box" & @CRLF) Return EndIf Local $s6 = DllStructGetData($acInfo, "states_en_US") If StringInStr($s6, "checked") Then Return Else _JAB_singleAction($vmId, $ac) EndIf EndFunc Func _JAB_unselectCheckBox($vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmId, $ac, $acInfo) Local $s3 = DllStructGetData($acInfo, "role") If $s3 <> "check box" Then consolewrite("_JAB_unselectCheckBox: this element isn't check box" & @CRLF) Return EndIf Local $s6 = DllStructGetData($acInfo, "states_en_US") If StringInStr($s6, "checked") Then _JAB_singleAction($vmId, $ac) EndIf EndFunc ;~ scroll pane-->viewport-->table ;~ |-->scroll bar ;~ |-->scroll bar ;~ |-->viewport-->panel-->panel:column1 ;~ |-->panel:column2 ;~ Must use unique name to find column ac Func _JAB_getTableFromColumn($vmId, $ac) Local $p1_ac = __getAccessibleParentFromContext($vmId, $ac) Local $p2_ac = __getAccessibleParentFromContext($vmId, $p1_ac) Local $s3 = _JAB_getRole($vmId, $p2_ac) If $s3 <> "viewport" Then consolewrite("_JAB_getTableFromColumn: find wrong column viewport" & @CRLF) Return EndIf Local $p3_ac = __getAccessibleParentFromContext($vmId, $p2_ac) Local $iCount = _JAB_getChildrenCount($vmId, $p3_ac) For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $p3_ac, $i) Local $child_s3 = _JAB_getRole($vmId, $child_ac) If $child_s3 = "viewport" Then ;~ first child is table, begin from 0 Local $grandson_ac = __getAccessibleChildFromContext($vmId, $child_ac, 0) Local $grandson_s3 = _JAB_getRole($vmId, $grandson_ac) If $grandson_s3 = "table" Then Return $grandson_ac ExitLoop EndIf EndIf Next EndFunc ;~ row and column begin from 0 Func _JAB_getTableCellText($vmId, $ac, $iRow = 0, $iColumn = 0) If Not IsInt($iRow) Or Not IsInt($iColumn) Then consolewrite("_JAB_getTableCellText: $iRow and $iColumn must be int" & @CRLF) Return EndIf Local $s3 = _JAB_getRole($vmId, $ac) If $s3 <> "table" Then consolewrite("_JAB_getTableCellText: this element isn't table" & @CRLF) Return EndIf Local $tableInfo = DllStructCreate($tagAccessibleTableInfo) __getAccessibleTableInfo($vmId, $ac, $tableInfo) Local $table_s3 = DllStructGetData($tableInfo, "rowCount") Local $table_s4 = DllStructGetData($tableInfo, "columnCount") Local $table_s6 = DllStructGetData($tableInfo, "accessibleTable") If $iRow < 0 Or $iRow > $table_s3 - 1 Then consolewrite("_JAB_getTableCellText: $iRow out of range" & @CRLF) Return EndIf If $iColumn < 0 Or $iColumn > $table_s4 - 1 Then consolewrite("_JAB_getTableCellText: $iColumn out of range" & @CRLF) Return EndIf Local $tableCellInfo = DllStructCreate($tagAccessibleTableCellInfo) __getAccessibleTableCellInfo($vmId, $table_s6, $iRow, $iColumn, $tableCellInfo) Local $cell_s1 = DllStructGetData($tableCellInfo, "accessibleContext") Return _JAB_getName($vmId, $cell_s1) EndFunc Func _JAB_selectAFromTableWhereB($vmId, $ac, $iColumnA, $iColumnB, $sB) If Not IsInt($iColumnA) Or Not IsInt($iColumnB) Then consolewrite("_JAB_selectAFromTableWhereB: $iColumnA and $iColumnB must be int" & @CRLF) Return EndIf Local $s3 = _JAB_getRole($vmId, $ac) If $s3 <> "table" Then consolewrite("_JAB_selectAFromTableWhereB: this element isn't table" & @CRLF) Return EndIf Local $tableInfo = DllStructCreate($tagAccessibleTableInfo) __getAccessibleTableInfo($vmId, $ac, $tableInfo) Local $table_s3 = DllStructGetData($tableInfo, "rowCount") Local $table_s4 = DllStructGetData($tableInfo, "columnCount") Local $table_s6 = DllStructGetData($tableInfo, "accessibleTable") If $iColumnA < 0 Or $iColumnA > $table_s4 - 1 Then consolewrite("_JAB_selectAFromTableWhereB: $iColumnA out of range" & @CRLF) Return EndIf If $iColumnB < 0 Or $iColumnB > $table_s4 - 1 Then consolewrite("_JAB_selectAFromTableWhereB: $iColumnB out of range" & @CRLF) Return EndIf Local $re = -1 For $i = 0 To $table_s3 - 1 Local $tableCellInfo = DllStructCreate($tagAccessibleTableCellInfo) __getAccessibleTableCellInfo($vmId, $table_s6, $i, $iColumnB, $tableCellInfo) Local $cell_s1 = DllStructGetData($tableCellInfo, "accessibleContext") Local $s1 = _JAB_getName($vmId, $cell_s1) If StringInStr($s1, $sB) Then $re = 1 __getAccessibleTableCellInfo($vmId, $table_s6, $i, $iColumnA, $tableCellInfo) Local $cell_s2 = DllStructGetData($tableCellInfo, "accessibleContext") Return _JAB_getName($vmId, $cell_s2) ExitLoop EndIf Next If $re = -1 Then consolewrite("_JAB_selectAFromTableWhereB: " & $sB & " is not found" & @CRLF) Return EndIf EndFunc Func _JAB_menuSelectItem($vmId, $ac, $item1 = "", $item2 = "", $item3 = "", $item4 = "", $item5 = "", $item6 = "") Local $s3 = _JAB_getRole($vmId, $ac) If $s3 <> "menu" Then consolewrite("_JAB_menuSelectItem: this element isn't menu" & @CRLF) Return EndIf _JAB_singleAction($vmId, $ac) Sleep(250) If $item1 <> "" Then Local $re1 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $ac) For $i = 0 To $iCount - 1 Local $ac1 = __getAccessibleChildFromContext($vmId, $ac, $i) Local $ac1_s1 = _JAB_getName($vmId, $ac1) If StringInStr($ac1_s1, $item1) Then _JAB_singleAction($vmId, $ac1) Sleep(250) $re1 = $ac1 ExitLoop EndIf Next If $re1 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item1 & " is not found" & @CRLF) Return EndIf If $item2 <> "" Then Local $re2 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $re1) For $i = 0 To $iCount - 1 Local $ac2 = __getAccessibleChildFromContext($vmId, $re1, $i) Local $ac2_s1 = _JAB_getName($vmId, $ac2) If StringInStr($ac2_s1, $item2) Then _JAB_singleAction($vmId, $ac2) Sleep(250) $re2 = $ac2 ExitLoop EndIf Next If $re2 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item2 & " is not found" & @CRLF) Return EndIf If $item3 <> "" Then Local $re3 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $re2) For $i = 0 To $iCount - 1 Local $ac3 = __getAccessibleChildFromContext($vmId, $re2, $i) Local $ac3_s1 = _JAB_getName($vmId, $ac3) If StringInStr($ac3_s1, $item3) Then _JAB_singleAction($vmId, $ac3) Sleep(250) $re3 = $ac3 ExitLoop EndIf Next If $re3 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item3 & " is not found" & @CRLF) Return EndIf If $item4 <> "" Then Local $re4 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $re3) For $i = 0 To $iCount - 1 Local $ac4 = __getAccessibleChildFromContext($vmId, $re3, $i) Local $ac4_s1 = _JAB_getName($vmId, $ac4) If StringInStr($ac4_s1, $item4) Then _JAB_singleAction($vmId, $ac4) Sleep(250) $re4 = $ac4 ExitLoop EndIf Next If $re4 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item4 & " is not found" & @CRLF) Return EndIf If $item5 <> "" Then Local $re5 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $re4) For $i = 0 To $iCount - 1 Local $ac5 = __getAccessibleChildFromContext($vmId, $re4, $i) Local $ac5_s1 = _JAB_getName($vmId, $ac5) If StringInStr($ac5_s1, $item5) Then _JAB_singleAction($vmId, $ac5) Sleep(250) $re5 = $ac5 ExitLoop EndIf Next If $re5 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item5 & " is not found" & @CRLF) Return EndIf If $item6 <> "" Then Local $re6 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $re5) For $i = 0 To $iCount - 1 Local $ac6 = __getAccessibleChildFromContext($vmId, $re5, $i) Local $ac6_s1 = _JAB_getName($vmId, $ac6) If StringInStr($ac6_s1, $item6) Then _JAB_singleAction($vmId, $ac6) Sleep(250) $re6 = $ac6 ExitLoop EndIf Next If $re6 = -1 Then consolewrite("_JAB_menuSelectItem: " & $item6 & " is not found" & @CRLF) Return EndIf EndIf EndIf EndIf EndIf EndIf EndIf EndFunc ;~ combo box-->popup menu-->scroll pane-->viewport-->list- ;~ | |-->label 0 ;~ | |-->label 1 ;~ | |-->label 2 ;~ | |-->label 3 ;~ -->scroll bar Func _JAB_comboBoxSelectItem($vmId, $ac, $listItem) Local $s3 = _JAB_getRole($vmId, $ac) If $s3 <> "combo box" Then consolewrite("_JAB_comboBoxSelectItem: this element isn't combo box" & @CRLF) Return EndIf Local $popup_ac = _JAB_getFirstChildByRole($vmId, $ac, "popup menu") If $popup_ac = "" Then consolewrite("_JAB_comboBoxSelectItem: popup menu is not found" & @CRLF) Return EndIf Local $scroll_ac = _JAB_getFirstChildByRole($vmId, $popup_ac, "scroll pane") If $scroll_ac = "" Then consolewrite("_JAB_comboBoxSelectItem: scroll pane is not found" & @CRLF) Return EndIf Local $viewport_ac = _JAB_getFirstChildByRole($vmId, $scroll_ac, "viewport") If $viewport_ac = "" Then consolewrite("_JAB_comboBoxSelectItem: viewport is not found" & @CRLF) Return EndIf Local $list_ac = _JAB_getFirstChildByRole($vmId, $viewport_ac, "list") If $list_ac = "" Then consolewrite("_JAB_comboBoxSelectItem: list is not found" & @CRLF) Return EndIf Local $re2 = -1 Local $iCount = _JAB_getChildrenCount($vmId, $list_ac) For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $list_ac, $i) Local $child_ac_s1 = _JAB_getName($vmId, $child_ac) If StringInStr($child_ac_s1 ,$listItem) Then $re2 = $i ExitLoop EndIf Next If $re2 = -1 Then consolewrite("_JAB_comboBoxSelectItem: " & $listItem & " is not found" & @CRLF) Return EndIf __addAccessibleSelectionFromContext($vmId, $ac, $re2) EndFunc ;~ _fixBridgeFunc(None,'Windows_run') Func __Windows_run() $result = DllCall($hAccessBridgeDll, "NONE", "Windows_run") If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ _fixBridgeFunc(None,'setFocusGainedFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyNameChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyDescriptionChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyValueChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p) ;~ _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p) ;========================================Initialization/Shutdown Functions========================================== ; Starts Java Access Bridge. You can't use any part of the Java Access Bridge API until you call this function. Func __initializeAccessBridge() $result = DllCall($hAccessBridgeDll, "NONE", "initializeAccessBridge") If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; Shuts down Java Access Bridge. Func __shutdownAccessBridge() $result = DllCall($hAccessBridgeDll, "NONE", "shutdownAccessBridge") If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;========================================Gateway Functions========================================================= ;~ BOOL IsJavaWindow(HWND window) ; Checks to see if the given window implements the Java Accessibility API. Func __isJavaWindow($hwnd) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isJavaWindow", "hwnd", $hwnd) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac) ; Returns the virtual machine ID and AccessibleContext for a top-level window. Func __getAccessibleContextFromHWND($hwnd, byref $vmID, byref $ac) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextFromHWND", "hwnd", $hwnd, "long*", $vmId, $cP_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) $vmID = $result[2] $ac = $result[3] Return $result[0] EndFunc ;========================================General Functions========================================================= ;~ void ReleaseJavaObject(long vmID, Java_Object object) ; Release the memory used by the Java object object, where object is an object returned to you by Java Access Bridge. Func __releaseJavaObject($vmId, $object) $result = DllCall($hAccessBridgeDll, "NONE", "releaseJavaObject", "long", $vmId, $c_JOBJECT64, $object) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info) ; Gets the version information of the instance of Java Access Bridge instance your application is using. ; $tAccessBridgeVersionInfo $info Func __getVersionInfo($vmId, byref $info) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getVersionInfo", "long", $vmId, "struct*", $info) If @error Then Return SetError(1, 0, 0) $info = $result[2] Return $result[0] EndFunc ;========================================Accessible Context Functions========================================================= ;~ BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, jint x, jint y, AccessibleContext *ac) ; Retrieves an AccessibleContext object of the window or object that is under the mouse pointer. Func __getAccessibleContextAt($vmId, $acParent, $x, $y, byref $ac) ;~ Seems not to be allowed to call with null so passing $acParent $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextAt", "long", $vmId, $c_JOBJECT64, $acParent, "int", $x, "int", $y, $cP_JOBJECT64, $ac) consolewrite(@error) If @error Then Return SetError(1, 0, 0) $ac = $result[5] Return $result[0] EndFunc ;~ BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac) ; Retrieves an AccessibleContext object of the window or object that has the focus. Func __getAccessibleContextWithFocus($hwnd, byref $vmID, byref $ac) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextWithFocus", "hwnd", $hwnd, "long*", $vmId, $cP_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) $vmID = $result[2] $ac = $result[3] Return $result[0] EndFunc ;~ BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info) ; Retrieves an AccessibleContextInfo object of the AccessibleContext object ac. ; $tAccessibleContextInfo $info Func __getAccessibleContextInfo($vmId, $ac, byref $info) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextInfo", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $info) If @error Then Return SetError(1, 0, 0) $info = $result[3] Return $result[0] EndFunc ;~ AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index)) ; Returns an AccessibleContext object that represents the nth child of the object ac, where n is specified by the value index. Func __getAccessibleChildFromContext($vmId, $ac, $index) ;~ Seems not to be allowed to call with null so passing $acParent $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleChildFromContext", "long", $vmId, $c_JOBJECT64, $ac, "int", $index) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac) ; Returns an AccessibleContext object that represents the parent of object ac. Func __getAccessibleParentFromContext($vmId, $ac) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleParentFromContext", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac) ; Returns the HWND from the AccessibleContextof a top-level window. Func __getHWNDFromAccessibleContext($vmId, $ac) $result = DllCall($hAccessBridgeDll, "hwnd", "getHWNDFromAccessibleContext", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;========================================Accessible Text Functions========================================================= ;~ BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y) ; $tAccessibleTextInfo $textInfo Func __getAccessibleTextInfo($vmId, $at, byref $textInfo, $x, $y) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextInfo", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textInfo, "int", $x, "int", $y) If @error Then Return SetError(1, 0, 0) $textInfo = $result[3] Return $result[0] EndFunc ;~ BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index) ; $tAccessibleTextItemsInfo $textItems Func __getAccessibleTextItems($vmId, $at, byref $textItems, $index) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextItems", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textItems, "int", $index) If @error Then Return SetError(1, 0, 0) $textItems = $result[3] Return $result[0] EndFunc ;~ BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection) ; $tAccessibleTextSelectionInfo $textSelection Func __getAccessibleTextSelectionInfo($vmId, $at, byref $textSelection) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextSelectionInfo", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textSelection) If @error Then Return SetError(1, 0, 0) $textSelection = $result[3] Return $result[0] EndFunc ;~ BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes) ; $tAccessibleTextAttributesInfo $attributes Func __getAccessibleTextAttributes($vmId, $at, $index, byref $attributes) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextAttributes", "long", $vmId, $c_JOBJECT64, $at, "int", $index, "struct*", $attributes) If @error Then Return SetError(1, 0, 0) $attributes = $result[4] Return $result[0] EndFunc ; BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); ; $tAccessibleTextRectInfo $rectInfo Func __getAccessibleTextRect($vmId, $at, byref $rectInfo, $index) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextRect", "long", $vmId, $c_JOBJECT64, $at, "struct*", $rectInfo, "int", $index) If @error Then Return SetError(1, 0, 0) $attributes = $result[3] Return $result[0] EndFunc ;~ BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len) Func __getAccessibleTextRange($vmId, $at, $start, $end, $text, $len) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextRange", "long", $vmId, $c_JOBJECT64, $at, "int", $start, "int", $end, "wstr", $text, "short", $len) If @error Then Return SetError(1, 0, 0) $text = $result[5] Return $result[0] EndFunc ;~ BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex) Func __getAccessibleTextLineBounds($vmId, $at, $index, byref $startIndex, byref $endIndex) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextLineBounds", "long", $vmId, $c_JOBJECT64, $at, "int", $index, "int*", $startIndex, "int*", $endIndex) If @error Then Return SetError(1, 0, 0) $startIndex = $result[4] $endIndex = $result[5] Return $result[0] EndFunc ;========================================Additional Text Functions========================================================= ;~ _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True) ; Selects text between two indices. Selection includes the text at the start index and the text at the end index. ; AccessibleContext $ac Func __selectTextRange($vmId, $ac, $startIndex, $endIndex) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "selectTextRange", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "int", $endIndex) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True) ; Get text attributes between two indices. The attribute list includes the text at the start index and the text at the end index. ; AccessibleContext $ac ; $tAccessibleTextAttributesInfo $attributes Func __getTextAttributesInRange($vmId, $ac, $startIndex, $endIndex, byref $attributes, byref $len) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getTextAttributesInRange", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "int", $endIndex, "struct*", $attributes, "short*", $len) If @error Then Return SetError(1, 0, 0) $attributes = $result[5] $len = $result[6] Return $result[0] EndFunc ;~ _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True) ; Set the caret to a text position. ; AccessibleContext $ac Func __setCaretPosition($vmId, $ac, $position) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "setCaretPosition", "long", $vmId, $c_JOBJECT64, $ac, "int", $position) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True) ; Gets the text caret location. ; AccessibleContext $ac ; $tAccessibleTextRectInfo $rectInfo Func __getCaretLocation($vmId, $ac, byref $rectInfo, $position) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getCaretLocation", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $position, "int", $position) If @error Then Return SetError(1, 0, 0) $rectInfo = $result[3] Return $result[0] EndFunc ; BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text) ; Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. Returns whether successful. ; AccessibleContext $ac Func __setTextContents($vmId, $ac, $text) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "setTextContents", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $text) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;========================================Accessible Table Functions========================================================= ;~ BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) ; Returns information about the table, for example, caption, summary, row and column count, and the AccessibleTable. ; $tAccessibleTableInfo $tableInfo Func __getAccessibleTableInfo($vmId, $acParent, byref $tableInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableInfo", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo) If @error Then Return SetError(1, 0, 0) $tableInfo = $result[3] Return $result[0] EndFunc ;~ BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, AccessibleTableCellInfo *tableCellInfo) ; Returns information about the specified table cell. The row and column specifiers are zero-based. ; $tAccessibleTableCellInfo $tableCellInfo Func __getAccessibleTableCellInfo($vmId, $table, $row, $column, byref $tableCellInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableCellInfo", "long", $vmId, $c_JOBJECT64, $table, "int", $row, "int", $column, "struct*", $tableCellInfo) If @error Then Return SetError(1, 0, 0) $tableCellInfo = $result[5] Return $result[0] EndFunc ;~ BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) ; Returns the table row headers of the specified table as a table. ; $tAccessibleTableInfo $tableInfo Func __getAccessibleTableRowHeader($vmId, $acParent, byref $tableInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableRowHeader", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo) If @error Then Return SetError(1, 0, 0) $tableInfo = $result[3] Return $result[0] EndFunc ;~ BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) ; Returns the table column headers of the specified table as a table. ; $tAccessibleTableInfo $tableInfo Func __getAccessibleTableColumnHeader($vmId, $acParent, byref $tableInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableColumnHeader", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo) If @error Then Return SetError(1, 0, 0) $tableInfo = $result[3] Return $result[0] EndFunc ;~ AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row) ; Returns the description of the specified row in the specified table. The row specifier is zero-based. Func __getAccessibleTableRowDescription($vmId, $acParent, $row) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleTableRowDescription", "long", $vmId, $c_JOBJECT64, $acParent, "int", $row) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column) ; Returns the description of the specified column in the specified table. The column specifier is zero-based. Func __getAccessibleTableColumnDescription($vmId, $acParent, $column) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleTableColumnDescription", "long", $vmId, $c_JOBJECT64, $acParent, "int", $column) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table) ; Returns how many rows in the table are selected. Func __getAccessibleTableRowSelectionCount($vmId, $table) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableRowSelectionCount", "long", $vmId, $c_JOBJECT64, $table) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row) ; Returns true if the specified zero based row is selected. Func __isAccessibleTableRowSelected($vmId, $table, $row) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleTableRowSelected", "long", $vmId, $c_JOBJECT64, $table, "int", $row) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections) ; Returns an array of zero based indices of the selected rows. Func __getAccessibleTableRowSelections($vmId, $table, $count, byref $selections) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableRowSelections", "long", $vmId, $c_JOBJECT64, $table, "int", $count, "int*", $selections) If @error Then Return SetError(1, 0, 0) $selections = $result[4] Return $result[0] EndFunc ; jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table) ; Returns how many columns in the table are selected. Func __getAccessibleTableColumnSelectionCount($vmId, $table) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableColumnSelectionCount", "long", $vmId, $c_JOBJECT64, $table) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column) ; Returns true if the specified zero based column is selected. Func __isAccessibleTableColumnSelected($vmId, $table, $column) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleTableColumnSelected", "long", $vmId, $c_JOBJECT64, $table, "int", $column) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections) ; Returns an array of zero based indices of the selected columns. Func __getAccessibleTableColumnSelections($vmId, $table, $count, byref $selections) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableColumnSelections", "long", $vmId, $c_JOBJECT64, $table, "int", $count, "int*", $selections) If @error Then Return SetError(1, 0, 0) $selections = $result[4] Return $result[0] EndFunc ;~ jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index) ; Returns the row number of the cell at the specified cell index. The values are zero based. Func __getAccessibleTableRow($vmId, $table, $index) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableRow", "long", $vmId, $c_JOBJECT64, $table, "int", $index) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index) ; Returns the column number of the cell at the specified cell index. The values are zero based. Func __getAccessibleTableColumn($vmId, $table, $index) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableColumn", "long", $vmId, $c_JOBJECT64, $table, "int", $index) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column) ; Returns the index in the table of the specified row and column offset. The values are zero based. Func __getAccessibleTableIndex($vmId, $table, $row, $column) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableIndex", "long", $vmId, $c_JOBJECT64, $table, "int", $row, "int", $column) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;========================================Accessible Relation Set Function========================================================= ;~ BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, AccessibleRelationSetInfo *relationSetInfo) ; Returns information about an object's related objects. ; $tAccessibleRelationInfo $relationSetInfo Func __getAccessibleRelationSet($vmId, $ac, byref $relationSetInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleRelationSet", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $relationSetInfo) If @error Then Return SetError(1, 0, 0) $relationSetInfo = $result[3] Return $result[0] EndFunc ;========================================Accessible Hypertext Functions========================================================= ; BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, AccessibleHypertextInfo *hypertextInfo) ; Returns hypertext information associated with a component. ; $tAccessibleHyperlinkInfo $hypertextInfo Func __getAccessibleHypertext($vmId, $ac, byref $hypertextInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHypertext", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $hypertextInfo) If @error Then Return SetError(1, 0, 0) $hypertextInfo = $result[3] Return $result[0] EndFunc ; BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, AccessibleHyperlink accessibleHyperlink) ; Requests that a hyperlink be activated. Func __activateAccessibleHyperlink($vmId, $ac, $accessibleHyperlink) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "activateAccessibleHyperlink", "long", $vmId, $c_JOBJECT64, $ac, $c_JOBJECT64, $accessibleHyperlink) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; jint getAccessibleHyperlinkCount(const long vmID, const AccessibleHypertext hypertext) ; Returns the number of hyperlinks in a component. Maps to AccessibleHypertext.getLinkCount. Returns -1 on error. Func __getAccessibleHyperlinkCount($vmId, $hypertext) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleHyperlinkCount", "long", $vmId, $c_JOBJECT64, $hypertext) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL getAccessibleHypertextExt(const long vmID, const AccessibleContext accessibleContext, const jint nStartIndex, AccessibleHypertextInfo *hypertextInfo) ; Iterates through the hyperlinks in a component. Returns hypertext information for a component starting at hyperlink index nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will be returned for each call to this method. Returns FALSE on error. ; $tAccessibleHyperlinkInfo $hypertextInfo Func __getAccessibleHypertextExt($vmId, $ac, $nStartIndex, byref $hypertextInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHypertextExt", "long", $vmId, $c_JOBJECT64, $ac, "int", $nStartIndex, "struct*", $hypertextInfo) If @error Then Return SetError(1, 0, 0) $hypertextInfo = $result[4] Return $result[0] EndFunc ; jint getAccessibleHypertextLinkIndex(const long vmID, const AccessibleHypertext hypertext, const jint nIndex) ; Returns the index into an array of hyperlinks that is associated with a character index in document. Maps to AccessibleHypertext.getLinkIndex. Returns -1 on error. Func __getAccessibleHypertextLinkIndex($vmId, $hypertext, $nIndex) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleHypertextLinkIndex", "long", $vmId, $c_JOBJECT64, $hypertext, "int", $nIndex) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL getAccessibleHyperlink(const long vmID, const AccessibleHypertext hypertext, const jint nIndex, AccessibleHypertextInfo *hyperlinkInfo) ; Returns the nth hyperlink in a document. Maps to AccessibleHypertext.getLink. Returns FALSE on error. ; $tAccessibleHyperlinkInfo $hypertextInfo Func __getAccessibleHyperlink($vmId, $hypertext, $nIndex, byref $hypertextInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHyperlink", "long", $vmId, $c_JOBJECT64, $hypertext, "int", $nIndex, "struct*", $hypertextInfo) If @error Then Return SetError(1, 0, 0) $hypertextInfo = $result[4] Return $result[0] EndFunc ;========================================Accessible Key Binding Function========================================================= ;~ BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, AccessibleKeyBindings *keyBindings) ; Returns a list of key bindings associated with a component. ; $tAccessibleKeyBindings $keyBindings Func __getAccessibleKeyBindings($vmId, $ac, byref $keyBindings) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleKeyBindings", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $keyBindings) If @error Then Return SetError(1, 0, 0) $keyBindings = $result[3] Return $result[0] EndFunc ;========================================Accessible Icon Function========================================================= ; BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, AccessibleIcons *icons) ; Returns a list of icons associate with a component. ; $tAccessibleIconInfo $icons Func __getAccessibleIcons($vmId, $ac, byref $icons) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleIcons", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $icons) If @error Then Return SetError(1, 0, 0) $icons = $result[3] Return $result[0] EndFunc ;========================================Accessible Action Functions========================================================= ;~ BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, AccessibleActions *actions) ; Returns a list of actions that a component can perform. ; $tAccessibleActions $actions Func __getAccessibleActions($vmId, $ac, byref $actions) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleActions", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $actions) If @error Then Return SetError(1, 0, 0) $actions = $result[3] Return $result[0] EndFunc ;~ BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, AccessibleActionsToDo *actionsToDo, jint *failure) ; Request that a list of AccessibleActions be performed by a component. ; $tAccessibleActionsToDo $actionsToDo Func __doAccessibleActions($vmId, $ac, byref $actionsToDo, byref $failure) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "doAccessibleActions", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $actionsToDo, "int*", $failure) If @error Then Return SetError(1, 0, 0) $actionsToDo = $result[3] $failure = $result[4] Return $result[0] EndFunc ;========================================Utility Functions========================================================= ;~ BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) ; Returns whether two object references refer to the same object. Func __isSameObject($vmId, $obj1, $obj2) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isSameObject", "long", $vmId, $c_JOBJECT64, $obj1, $c_JOBJECT64, $obj2) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) ;Returns the AccessibleContext with the specified role that is the ancestor of a given object. The role is one of the role strings defined in Java Access Bridge API Data Stuctures. Func __getParentWithRole($vmId, $ac, $role) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getParentWithRole", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $role) If @error Then Return SetError(1, 0, 0) $role = $result[3] Return $result[0] EndFunc ; AccessibleContext getParentWithRoleElseRoot(const long vmID, const AccessibleContext accessibleContext, const wchar_t *role); ; Returns the AccessibleContext with the specified role that is the ancestor of a given object. If an object with the specified role does not exist, returns the top level object for the Java Window. Func __getParentWithRoleElseRoot($vmId, $ac, $role) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getParentWithRoleElseRoot", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $role) If @error Then Return SetError(1, 0, 0) $role = $result[3] Return $result[0] EndFunc ;~ AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) ; Returns the AccessibleContext for the top level object in a Java window. Func __getTopLevelObject($vmId, $ac) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getTopLevelObject", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) ;~ _ArrayDisplay($result) Return $result[0] EndFunc ;~ int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) ; Returns how deep in the object hierarchy a given object is. The top most object in the object hierarchy has an object depth of 0. Returns -1 on error. Func __getObjectDepth($vmId, $ac) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getObjectDepth", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) ; Returns the AccessibleContext of the current ActiveDescendent of an object. This method assumes the ActiveDescendent is the component that is currently selected in a container object. Func __getActiveDescendent($vmId, $ac) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getActiveDescendent", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext) ; Request focus for a component. Returns whether successful. Func __requestFocus($vmId, $ac) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "requestFocus", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;~ int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext) ; Returns the number of visible children of a component. Returns -1 on error. Func __getVisibleChildrenCount($vmId, $ac) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getVisibleChildrenCount", "long", $vmId, $c_JOBJECT64, $ac) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, const int startIndex, VisibleChildrenInfo *visibleChildrenInfo); ; Gets the visible children of an AccessibleContext. Returns whether successful. ; $tVisibleChildenInfo $visibleChildrenInfo Func __getVisibleChildren($vmId, $ac, $startIndex, byref $visibleChildrenInfo) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getVisibleChildren", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "struct*", $visibleChildrenInfo) If @error Then Return SetError(1, 0, 0) $visibleChildrenInfo = $result[4] Return $result[0] EndFunc ; int getEventsWaiting() ; Gets the number of events waiting to fire. Func __getEventsWaiting() $result = DllCall($hAccessBridgeDll, "int:cdecl", "getEventsWaiting") If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ;========================================Accessible Value Functions========================================================= ;~ BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) Func __getCurrentAccessibleValueFromContext($vmId, $av, $value, $len) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getCurrentAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len) If @error Then Return SetError(1, 0, 0) $value = $result[3] Return $result[0] EndFunc ; BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len) Func __getMaximumAccessibleValueFromContext($vmId, $av, $value, $len) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getMaximumAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len) If @error Then Return SetError(1, 0, 0) $value = $result[3] Return $result[0] EndFunc ; BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len) Func __getMinimumAccessibleValueFromContext($vmId, $av, $value, $len) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getMinimumAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len) If @error Then Return SetError(1, 0, 0) $value = $result[3] Return $result[0] EndFunc ;========================================Accessible Selection Functions========================================================= ; void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) Func __addAccessibleSelectionFromContext($vmId, $as, $i) $result = DllCall($hAccessBridgeDll, "NONE", "addAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as) Func __clearAccessibleSelectionFromContext($vmId, $as) $result = DllCall($hAccessBridgeDll, "NONE", "clearAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; jobject GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) Func __getAccessibleSelectionFromContext($vmId, $as, $i) $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as) Func __getAccessibleSelectionCountFromContext($vmId, $as) $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleSelectionCountFromContext", "long", $vmId, $c_JOBJECT64, $as) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i) Func __isAccessibleChildSelectedFromContext($vmId, $as, $i) $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleChildSelectedFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) Func __removeAccessibleSelectionFromContext($vmId, $as, $i) $result = DllCall($hAccessBridgeDll, "NONE", "removeAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc ; void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as) Func __selectAllAccessibleSelectionFromContext($vmId, $as) $result = DllCall($hAccessBridgeDll, "NONE", "selectAllAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as) If @error Then Return SetError(1, 0, 0) Return $result[0] EndFunc Full demo as was described in thread on page 3 #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <constants.au3> #include <WinAPI.au3> #include <WinAPIEx.au3> #include <debug.au3> #include <memory.au3> #include <Misc.au3> #include "JavaUI.au3" Global $__g_vmId ;~ Holds the global JVM ID (in case you have running multiple java programs you can expect different id's) Global $__g_acJavaMainWindow ;~ The accessibility context (ac) to the main java window Global $__g_acJavaDialogWindow ;~ The accessibility context (ac) to the java popup dialog window Global $__g_hwndJavaWindow ;~ The hwnd to the main Java Control Panel Window Global $__g_hwndJavaDialogWindow ;~ The hwnd to the java popup dialog window Global $__g_acJavaTLO main() func main() startJavaProgram() Local $wintitle = "Java Control Panel" $__g_hwndJavaWindow = WinActivate($wintitle) $result = __isJavaWindow($__g_hwndJavaWindow) __getAccessibleContextFromHWND($__g_hwndJavaWindow, $__g_vmId, $__g_acJavaMainWindow) ;~ Get our vmid into the global variable printMainWindowInformation() ;Works ok sleep(250) handleMainWindow() sleep(2500) handlePopupPage() sleep(250) $okButton= _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaMainWindow, "Ok", "push button") _JAB_singleAction($__g_vmId, $okButton) sleep(1500) EndFunc func handleMainWindow() printTopLevelObjectInformation() ;~ In general its equal to java main window ;Works ok sleep(250) handleAboutButton() ;Works ok sleep(250) clickSecurityTab() ;Works ok sleep(250) clickSiteListButton();Works ok sleep(250) EndFunc func handlePopupPage() ;~ Main window ;~ So now we have a new window which we should determine before we can continue sleep(2000) consolewrite("Handle popup functionn" & @CRLF) $__g_hwndJavaDialogWindow= WinGetHandle("[TITLE:Exception Site List]","") ;~ Local $winHandle2= WinGetHandle("[CLASS:SunAwtDialog]","") ;~ Local $winHandle2= WinGetHandle("[ACTIVE]","") consolewrite( "Handle sunawt: " & $__g_hwndJavaDialogWindow & "(" & Dec(hex($__g_hwndJavaDialogWindow)) & ") from vm: " & $__g_vmId & @CRLF) ;~ winListInfo() ;~As above was troublesome to get right window some debughelper consolewrite("Main information" & @CRLF) __getAccessibleContextFromHWND($__g_hwndJavaDialogWindow, $__g_vmId, $__g_acJavaDialogWindow) consolewrite( "Handle sunawt 2: " & $__g_hwndJavaDialogWindow & "(" & Dec(hex($__g_hwndJavaDialogWindow)) & ") from vm: " & $__g_vmId & @CRLF) consolewrite("Returned ac : " & $__g_acJavaDialogWindow & @CRLF) highLightAC($__g_vmId,$__g_acJavaDialogWindow) $AddButton= _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaDialogWindow, "Add", "push button") _JAB_singleAction($__g_vmId, $AddButton) ;~ Most likely we have to deal with information in the table ;~ $table= _JAB_getAccessibleContextByRole($__g_vmId, $__g_acJavaDialogWindow, "table",1) $table= _JAB_getAccessibleChildNByRole($__g_vmId, $__g_acJavaDialogWindow, "table",1) highLightAC($__g_vmId, $table) local $tableInfo=DllStructCreate($tagAccessibleTableInfo) __getAccessibleTableInfo($__g_vmId, $table, $tableInfo) ;~ So we now know the row and col count printDescriptionTable($tableInfo) ;~ TODO: ;~ $textBox= _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaDialogWindow, "", "text") ;~ local $textBox ;~ __getAccessibleContextWithFocus($__g_hwndJavaDialogWindow, $__g_vmId, $textBox) ;~ __setTextContents($__g_vmId, $textBox, "https://www.autoitscript.com") ;~ _JAB_setvalue($__g_vmId, $textBox, "https://www.autoitscript.com") send("https://www.autoitscript.com") send("{ENTER}") sleep(1500) $okButton= _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaDialogWindow, "Ok", "push button") _JAB_singleAction($__g_vmId, $okButton) sleep(1500) EndFunc func clickSiteListButton() $SiteListButton= _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaMainWindow, "Edit Site List...", "push button") highLightAC($__g_vmId, $SiteListButton) printdescription($SiteListButton) sleep(2500) ;~ TODO: Somewhere here it hangs ;~ consolewrite("Just before it causes a blocking ..." & @CRLF) ;~ _JAB_singleAction($__g_vmId, $SiteListButton) ;~ consolewrite("Just after it causes a blocking ..." & @CRLF) clickac($__g_vmId, $SiteListButton) sleep(1500) __releaseJavaObject($__g_vmId, $SiteListButton) ;~ consolewrite("Just after it causes a blocking ... 2" & @CRLF) EndFunc func printMainWindowInformation() local $acInfo= DllStructCreate($tagAccessibleContextInfo) ;~ Main window consolewrite("Main information" & @CRLF) __getAccessibleContextInfo($__g_vmId, $__g_acJavaMainWindow, $acInfo) printDescription($acInfo) __releaseJavaObject($__g_vmId, $acInfo) ;~ Just for showing how to get a button by index showInfoPushButton(1) sleep(250) showInfoPushButton(2) sleep(250) showInfoPushButton(3) sleep(250) EndFunc func printTopLevelObjectInformation() local $acInfo= DllStructCreate($tagAccessibleContextInfo) consolewrite("Top Level Object information" & $__g_vmId & @CRLF) local $acJavaTLO $acJavaTLO=__getTopLevelObject($__g_vmId, $__g_acJavaMainWindow) consolewrite("TLO" & $__g_acJavaTLO & @CRLF) __getAccessibleContextInfo($__g_vmId, $acJavaTLO, $acInfo) printDescription($acInfo) __releaseJavaObject($__g_vmId, $acInfo) __releaseJavaObject($__g_vmId, $acJavaTLO) endfunc func startJavaProgram() shellexecute("C:\Program Files\Java\jdk1.8.0_172\jre\bin\javacpl.exe") sleep(3000) EndFunc func handleAboutButton() Local $sName = "About..." Local $sRole = "push button" ;~ Local $acInfo2 = DllStructCreate($tagAccessibleContextInfo) handleButton($sName, $sRole) endFunc func showInfoPushButton($index=1) ;~ First pushbutton by type/role ;~ local $re_ac=_JAB_getAccessibleContextByRole($__g_vmId, $__g_acJavaMainWindow, "push button", 1) local $re_ac=_JAB_getAccessibleChildNByRole($__g_vmId, $__g_acJavaMainWindow, "push button", $index) highLightAC($__g_vmId, $re_ac) printInfoPushButton($re_ac) __releaseJavaObject($__g_vmId, $re_ac) EndFunc func printInfoPushbutton($ac) ;~ Details from first pushbutton consolewrite("Button information" & @CRLF) local $sName = _JAB_getName($__g_vmId, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($__g_vmId, $ac, $acInfo) $acX = DllStructGetData($acInfo, "x") $acY = DllStructGetData($acInfo, "y") $acW = DllStructGetData($acInfo, "width") $acH = DllStructGetData($acInfo, "height") ConsoleWrite("Name:" & $sName & @CRLF) ConsoleWrite(" rect:" & $acX & $acX+$acW & $acy & $acY+$acH & @CRLF) printDescription($acInfo) __releaseJavaObject($__g_vmId, $acInfo) EndFunc func handleButton($sName, $sRole) ;~ First pushbutton by type/role with matching title/name local $ac = _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaMainWindow, $sName, $sRole) $sName = _JAB_getName($__g_vmId, $ac) ;~ Details from first pushbutton Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($__g_vmId, $ac, $acInfo) printDescription($acinfo) __releaseJavaObject($__g_vmId, $acInfo) __releaseJavaObject($__g_vmId, $ac) EndFunc func clickSecurityTab() ;- Find security tabpage local $SecurityTab = _JAB_getAccessibleContextByFindAll($__g_vmId, $__g_acJavaMainWindow, "Security", "page tab") ;~ Accessible action not supported according to access bridge explorer ;~ TODO: define tag/interface AccessibleComponent to call request focus Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($__g_vmId, $SecurityTab, $acInfo) $blnAccessibleComponent = DllStructGetData($acInfo, "accessibleComponent") $blnAccessibleAction = DllStructGetData($acInfo, "accessibleAction") consolewrite("accessibleComponent supported: " & $blnAccessibleComponent & @CRLF) consolewrite("accessibleAction supported: " & $blnAccessibleAction & @CRLF) $acX = DllStructGetData($acInfo, "x") $acY = DllStructGetData($acInfo, "y") $acW = DllStructGetData($acInfo, "width") $acH = DllStructGetData($acInfo, "height") ConsoleWrite("rect:" & $acX & $acX+$acW & $acy & $acY+$acH & @CRLF) _UIA_DrawRect($acX, $acX+$acW, $acy,$acY+$acH) sleep(500) __requestFocus($__g_vmId,$SecurityTab) ;~ TODO: Screen not refreshed when requesting focus Return ;~ Many ways to click, for demo in 2 steps mousemove(int($acx+($acw/2)), int($acy +($ach/2))) MouseClick($MOUSE_CLICK_LEFT) ;~ _JAB_singleAction($vmId, $SecurityTab) not possible so we should have interface iAccessibleComponent.requestfocus or as done above move mouse and click __releaseJavaObject($__g_vmId, $acInfo) __releaseJavaObject($__g_vmId, $SecurityTab) EndFunc func clickAC($vmid, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) __getAccessibleContextInfo($vmid, $ac, $acInfo) $acX = DllStructGetData($acInfo, "x") $acY = DllStructGetData($acInfo, "y") $acW = DllStructGetData($acInfo, "width") $acH = DllStructGetData($acInfo, "height") ConsoleWrite("rect:" & $acX & $acX+$acW & $acy & $acY+$acH & @CRLF) _UIA_DrawRect($acX, $acX+$acW, $acy,$acY+$acH) sleep(500) ;~ Many ways to click, for demo in 2 steps mousemove(int($acx+($acw/2)), int($acy +($ach/2))) MouseClick($MOUSE_CLICK_LEFT) ;~ _JAB_singleAction($vmId, $SecurityTab) not possible so we should have interface iAccessibleComponent.requestfocus or as done above move mouse and click __releaseJavaObject($__g_vmId, $acInfo) EndFunc Func _JAB_getAccessibleChildNByRole($vmId, $ac, $sRole,$index=1, $depth=0) Static $matchCount=0 if ($depth=0) then $matchCount=0 EndIf Local $iCount = _JAB_getChildrenCount($vmId, $ac) ;~ consolewrite("Investigating" & $iCount & ";" & $index & ";" & $matchCount & ";" & _JAB_getRole($vmId, $ac) & ";") If $iCount = 0 Then Return -1 EndIf local $retVal=-1 For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i) Local $child_ac_s3 = _JAB_getRole($vmId, $child_ac) ;~ consolewrite($child_ac_s3 & @CRLF) If $child_ac_s3 = $sRole Then $matchCount+=1 ;~ consolewrite("Partial match" & $matchCount & @CRLF) if $index=$matchCount Then ;~ consolewrite("Full match" & $matchCount & @CRLF) Return $child_ac endif EndIf $depth+=1 local $retVal=_JAB_getAccessibleChildNByRole($vmId, $child_ac, $sRole, $index, $depth) if ($retVal <>-1) Then exitloop EndIf Next Return $retVal EndFunc ;~ Must use the AccessibleContext got from the win handle which include the target element Func _JAB_getAccessibleContextByRole($vmId, $ac, $sRole, $sIndex) Local $find_ac = 0 Local $iCount =_JAB_getChildrenCount($vmId, $ac) If $iCount = 0 Then Return EndIf For $i = 0 To $iCount - 1 Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i) Local $s3 = _JAB_getRole($vmId, $child_ac) ; consolewrite($child_ac & "|" & $s1 & "," & $s3 & @CRLF) If $s3 = $sRole Then $find_ac = $child_ac ExitLoop Else If $find_ac = 0 Then $find_ac = _JAB_getAccessibleContextByRole($vmId, $child_ac, $sRole, $sIndex) EndIf EndIf Next Return $find_ac EndFunc Func _JAB_setValue2($vmId, $ac, $sValue) Local $actions = DllStructCreate($tagAccessibleActions) __getAccessibleActions($vmId, $ac, $actions) Local $s1 = DllStructGetData($actions, "actionsCount") If $s1 = 0 Then consolewrite("_JAB_setValue: this element has no action" & @CRLF) Return EndIf Local $re1 = 0 Local $re2 = 0 For $i = 2 To $s1 + 1 Local $s = DllStructGetData($actions, $i) If $s = "select-all" Then $re1 = 1 ExitLoop EndIf Next If $re1 = 0 Then consolewrite("_JAB_setValue: this element doesn't support select-all action" & @CRLF) Return EndIf For $i = 2 To $s1 + 1 Local $s = DllStructGetData($actions, $i) If $s = "paste-from-clipboard" Then $re2 = 1 ExitLoop EndIf Next If $re2 = 0 Then consolewrite("_JAB_setValue: this element doesn't support paste-from-clipboard action" & @CRLF) Return EndIf Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo) Local $failure ClipPut($sValue) DllStructSetData($actionsToDo, "actionsCount", 2) DllStructSetData($actionsToDo, 2, "select-all") DllStructSetData($actionsToDo, 3, "paste-from-clipboard") __doAccessibleActions($vmId, $ac, $actionsToDo, $failure) EndFunc ; Draw rectangle on screen. Func _UIA_DrawRect($tLeft, $tRight, $tTop, $tBottom, $color = 0xFF, $PenWidth = 4) Local $hDC, $hPen, $obj_orig, $x1, $x2, $y1, $y2 $x1 = $tLeft $x2 = $tRight $y1 = $tTop $y2 = $tBottom $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop) $hPen = _WinAPI_CreatePen($PS_SOLID, $PenWidth, $color) $obj_orig = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_DrawLine($hDC, $x1, $y1, $x2, $y1) ; horizontal to right _WinAPI_DrawLine($hDC, $x2, $y1, $x2, $y2) ; vertical down on right _WinAPI_DrawLine($hDC, $x2, $y2, $x1, $y2) ; horizontal to left right _WinAPI_DrawLine($hDC, $x1, $y2, $x1, $y1) ; vertical up on left ; clear resources _WinAPI_SelectObject($hDC, $obj_orig) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc ;==>_UIA_DrawRect Func printDescription($acInfo) $s1 = DllStructGetData($acInfo, "name") $s2 = DllStructGetData($acInfo, "description") $s3 = DllStructGetData($acInfo, "role") $s4 = DllStructGetData($acInfo, "role_en_US") $s5 = DllStructGetData($acInfo, "states") $s6 = DllStructGetData($acInfo, "states_en_US") $s7 = DllStructGetData($acInfo, "indexInParent") $s8 = DllStructGetData($acInfo, "childrenCount") $s9 = DllStructGetData($acInfo, "x") $s10 = DllStructGetData($acInfo, "y") $s11 = DllStructGetData($acInfo, "width") $s12 = DllStructGetData($acInfo, "height") $s13 = DllStructGetData($acInfo, "accessibleComponent") $s14 = DllStructGetData($acInfo, "accessibleAction") $output="" $output&=" name: <" & $s1 & ">" & @CRLF $output&=" description: <" & $s2 & ">" & @CRLF $output&=" role: <" & $s3 & ">" & @CRLF $output&=" role_en_US: <" & $s4 & ">" & @CRLF $output&=" states: <" & $s5 & ">" & @CRLF $output&=" states_en_US: <" & $s6 & ">" & @CRLF $output&=" indexInParent: <" & $s7 & ">" & @CRLF $output&=" childrenCount: <" & $s8 & ">" & @CRLF $output&=" x: <" & $s9 & ">" & @CRLF $output&=" y: <" & $s10 & ">" & @CRLF $output&=" width: <" & $s11 & ">" & @CRLF $output&=" height: <" & $s12 & ">" & @CRLF $output&=" accessibleComponent: <" & $s13 & ">" & @CRLF $output&=" accessibleAction: <" & $s14 & ">" & @CRLF tooltip($output,10,10,"tooltip") consolewrite($output) EndFunc ;==>printDescription Func printDescriptionTable($acTableInfo) $s1 = DllStructGetData($acTableInfo, "caption") $s2 = DllStructGetData($acTableInfo, "summary") $s3 = DllStructGetData($acTableInfo, "rowCount") $s4 = DllStructGetData($acTableInfo, "columnCount") $s5 = DllStructGetData($acTableInfo, "accessibleContext") $s6 = DllStructGetData($acTableInfo, "accessibleTable") $output="" $output&=" caption: <" & $s1 & ">" & @CRLF $output&=" description: <" & $s2 & ">" & @CRLF $output&=" rowCount: <" & $s3 & ">" & @CRLF $output&=" columnCount: <" & $s4 & ">" & @CRLF $output&=" accessibleContext: <" & $s5 & ">" & @CRLF $output&=" accessibleTable: <" & $s6 & ">" & @CRLF tooltip($output,10,10,"tooltip") consolewrite($output) EndFunc ;==>printDescriptionTable func winlistinfo() ; Retrieve a list of window handles. Local $aList = WinList() ; Loop through the array displaying only visable windows with a title. For $i = 1 To $aList[0][0] If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then consolewrite("Title: " & $aList[$i][0] & @CRLF & "Handle: " & $aList[$i][1]) if (__isJavaWindow($aList[$i][1])=true ) then consolewrite("Java Title: " & $aList[$i][0] & @CRLF & "Handle: " & $aList[$i][1]) endif EndIf Next EndFunc func highLightAC($vmid, $ac) Local $acInfo = DllStructCreate($tagAccessibleContextInfo) $sName = _JAB_getName($vmid, $ac) __getAccessibleContextInfo($vmid, $ac, $acInfo) $acX = DllStructGetData($acInfo, "x") $acY = DllStructGetData($acInfo, "y") $acW = DllStructGetData($acInfo, "width") $acH = DllStructGetData($acInfo, "height") ConsoleWrite("Name:" & $sName & @CRLF) ConsoleWrite("rect:" & $acX & $acX+$acW & $acy & $acY+$acH & @CRLF) ;~ _JAB_singleAction($vmId, $re_ac) ; for type button there is only 1 action _UIA_DrawRect($acX, $acX+$acW, $acy,$acY+$acH) printDescription($acInfo) __releaseJavaObject($vmid, $acInfo) EndFunc1 point
-
Hi, i think, that many scripts exist to compare arrays or strings. In my version i use object "System.Collections.ArrayList", that gives a good performances for great sets. Test it and form your own opinion. Explanation you find in function-header. EDIT 14.10.2008 - now using Default and Opt("GUIDataSeparatorChar") for $Delim - fixed a bug by using @CRLF as separator #include <array.au3> Local $1 = '1,1,2,3,3,3,4,4,5,6,7' Local $2[10] = ['5','5','5','8','8','9','12','12','3','1'] Local $ret = _GetIntersection($1, $2, 0, ',') If IsArray($ret) Then _ArrayDisplay($ret) $ret = _GetIntersection($1, $2, 1, ',') If IsArray($ret) Then _ArrayDisplay($ret) ;================================================================================================== ; Function Name: _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]]) ; Description:: Detect from 2 sets ; - Intersection (elements are contains in both sets) ; - Difference 1 (elements are contains only in $Set1) ; - Difference 2 (elements are contains only in $Set2) ; Parameter(s): $Set1 set 1 (1D-array or delimited string) ; $Set2 set 2 (1D-array or delimited string) ; optional: $GetAll 0 - only one occurence of every different element are shown (Default) ; 1 - all elements of differences are shown ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") ) ; Return Value(s): Succes 2D-array [i][0]=Intersection ; [i][1]=Difference 1 ; [i][2]=Difference 2 ; Failure -1 @error set, that was given as array, is'nt 1D-array ; Note: Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'! ; Author(s): BugFix (bugfix@autoit.de) ;================================================================================================== Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll=0, $Delim=Default) Local $o1 = ObjCreate("System.Collections.ArrayList") Local $o2 = ObjCreate("System.Collections.ArrayList") Local $oUnion = ObjCreate("System.Collections.ArrayList") Local $oDiff1 = ObjCreate("System.Collections.ArrayList") Local $oDiff2 = ObjCreate("System.Collections.ArrayList") Local $tmp, $i If $GetAll <> 1 Then $GetAll = 0 If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar") If Not IsArray($Set1) Then If Not StringInStr($Set1, $Delim) Then $o1.Add($Set1) Else $tmp = StringSplit($Set1, $Delim, 1) For $i = 1 To UBound($tmp) -1 $o1.Add($tmp[$i]) Next EndIf Else If UBound($Set1, 0) > 1 Then Return SetError(1,0,-1) For $i = 0 To UBound($Set1) -1 $o1.Add($Set1[$i]) Next EndIf If Not IsArray($Set2) Then If Not StringInStr($Set2, $Delim) Then $o2.Add($Set2) Else $tmp = StringSplit($Set2, $Delim, 1) For $i = 1 To UBound($tmp) -1 $o2.Add($tmp[$i]) Next EndIf Else If UBound($Set2, 0) > 1 Then Return SetError(1,0,-1) For $i = 0 To UBound($Set2) -1 $o2.Add($Set2[$i]) Next EndIf For $tmp In $o1 If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o2 If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o1 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp) EndIf Next For $tmp In $o2 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp) EndIf Next Local $UBound[3] = [$oDiff1.Count,$oDiff2.Count,$oUnion.Count], $max = 1 For $i = 0 To UBound($UBound) -1 If $UBound[$i] > $max Then $max = $UBound[$i] Next Local $aOut[$max][3] If $oUnion.Count > 0 Then $i = 0 For $tmp In $oUnion $aOut[$i][0] = $tmp $i += 1 Next EndIf If $oDiff1.Count > 0 Then $i = 0 For $tmp In $oDiff1 $aOut[$i][1] = $tmp $i += 1 Next EndIf If $oDiff2.Count > 0 Then $i = 0 For $tmp In $oDiff2 $aOut[$i][2] = $tmp $i += 1 Next EndIf Return $aOut EndFunc ;==>_GetIntersection_GetIntersection.au31 point
-
It's that time of the year again. Well, not quite yet, but soon, from March 25th to 28th 2016 in Saarbrücken, Germany to be precise. Revision is a demoparty held yearly on Easter since 2011 in Saarbrücken, the state capital of Saarland, located in southwest Germany. It is organized by the non-profit organization Tastatur und Maus e.V. and a large, international team of sceners. As an event purely from and for the demoscene Revision features everything you could wish for: multiplatform competitions, socializing and partying, awesome seminars and of course the unique Revision atmosphere created by us and YOU! It's time to prepare to meet and chat with awesome developers and learn new skills in seminars (with usually drunk hosts). Maybe you'll even spot some AutoIt folks there. It has happened before: (@UEZ and @AndyG if you wondered). This years theme is the return of EvilBot. A demoscene-hating robot that was introduced as Revision's main antagonist in 2012. Now he's taking over again, and even tries to run for president (#StillBetterThanTrump). How did that happen? You can watch the official 2016 invitation here (below) or download it here and run it on your own PC.1 point
-
mLipok, In the same sense, ask yourself: "Why doesn't Microsoft write fault-tolerant software?" I was just making fun on the over-cryptic message noone sensible can reasonably understand.1 point
-
How to read value from ComboBox from another form?
Xandy reacted to cdebel2005 for a topic
I don't see how this will help to get the ID at a specific screen coordinates. I've found what i neede here from _WinAPI_GetAncestor and _Mouse_Control_GetInfo. Thanks for the help you have provided1 point -
How to read value from ComboBox from another form?
Xandy reacted to cdebel2005 for a topic
It work, but is there any way to get the informations of what's below the cursor or at a specific X,Y coord on the screen? I've got the $handle_3rdparty_window from the Dialog Title ("Preferences"), and got the $i_3rdparty_comobox_control_id from "AutoIt Windows Info" but i would prefer to do it programmatically. Thanks1 point -
mLipok, Very interesting, it errors in the LH ListView, but not in the RH one - Sherlock Holmes mode now activated! M23 Edit: Found it - I was not forcing the correct colour array to be reloaded before redrawing. Files re-uploaded in post #21.1 point
-
Schau Dir bitte die Beispiel-Skripte für _AD_GetObjectsInOu.au3 an. Ein Beispiel zeigt "ANR".1 point
-
Creating a Directory passing variable information
CyberjoFrank reacted to JohnOne for a topic
DirCreate("N:\#User_Backups\"& @year & @mon & @mday & "." & $Lastname & "." & $FirstName) Something like that.1 point -
For that you have to read a lot on java accessibility bridge and study source of jaws and other open source implementations of java accessibility bridge. It all starts with building a ui tree and traversing that to get the right item. And if its internally developed explain developers that they have to fill the accessibility properties.1 point
-
Omega19, This UDF is extremely complex so I am not at all surprised that there is the odd "hiccup" from time to time, particularly if there are lots of drag/drop operations. If you ever do manage to find a reproducible script to demonstrate the bug please let me know. M231 point
-
How to read value from ComboBox from another form?
cdebel2005 reacted to Xandy for a topic
Does this work? #include <GuiComboBox.au3> local $iCombo_index= -1 local $hControl= controlgethandle($handle_3rdparty_window, "", $i_3rdparty_combobox_control_id) local $sData= "None" $iCombo_index= _GUICtrlComboBox_GetCurSel($hControl); -1 on null unchoosen dropdown value if $iCombo_index > -1 then _GUICtrlComboBox_GetLBText($hControl, $iCombo_index, $sData) endif consolewrite($sData) Edit tried to touch it up by hand here and there were a few errors that I hopefully cleaned up. You''ll have to get the handle to the 3rd party window and the control ID of the combobox query.1 point -
now, suppose you want to install your scheduled task into a subfolder. that way it will be visible to the user only if the "Task Scheduler Library" branch is expanded, so it is visually segregated from users' tasks - same way Microsoft do with their phenomenal list of tasks (some 88 tasks in 58 folders...). the trick is to prefix the task name with the subfolder, e.g. au3\au3@task instead of just au3@task as in the example above, for the task to be placed in the au3 subfolder. also, don't forget to remove it at uninstall. so this is the updated setup script: #RequireAdmin #AutoIt3Wrapper_Res_Fileversion=0.0.1.0 #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=y #NoTrayIcon #include <MsgBoxConstants.au3> Global $sTitle = 'au3@task Setup' Global $sDrive = StringLeft(@WindowsDir, 3) Global $sTaskDir = 'au3' Global $sTaskName = 'au3@task' Global $sTaskFullName = $sTaskDir & '\' & $sTaskName If AlreadyInstalled() Then If MsgBox($MB_ICONQUESTION + $MB_YESNO, $sTitle, 'Uninstall? ') = $IDYES Then If Uninstall() Then MsgBox($MB_ICONINFORMATION, $sTitle, 'Uninstallation completed successfully. ') Else MsgBox($MB_ICONERROR, $sTitle, 'Uninstallation error. ') EndIf Else MsgBox($MB_ICONINFORMATION, $sTitle, 'Uninstallation aborted. ') EndIf Else If MsgBox($MB_ICONQUESTION + $MB_YESNO, $sTitle, 'Install? ') = $IDYES Then If Install() Then If MsgBox($MB_ICONQUESTION + $MB_YESNO, $sTitle, 'Installation completed successfully. Run task now? ') = $IDYES Then If RunWait('schtasks.exe /Run /TN ' & $sTaskFullName, '', @SW_HIDE) = 0 Then MsgBox($MB_ICONINFORMATION, $sTitle, 'Task is running. ') Else MsgBox($MB_ICONERROR, $sTitle, 'Error running the task. ') EndIf Else MsgBox($MB_ICONINFORMATION, $sTitle, 'Done. ') EndIf Else MsgBox($MB_ICONERROR, $sTitle, 'Installation error. ') EndIf Else MsgBox($MB_ICONINFORMATION, $sTitle, 'Installation aborted. ') EndIf EndIf Func AlreadyInstalled() If Not FileExists($sDrive & 'au3@task.exe') Then Return False If RunWait('schtasks.exe /Query /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False Return True EndFunc ;==>AlreadyInstalled Func Install() If Not FileInstall('au3@task.exe', $sDrive, 1) Then Return False Local $sXML = _ '<?xml version="1.0" encoding="UTF-16"?>' & @CRLF & _ '<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">' & @CRLF & _ ' <Triggers>' & @CRLF & _ ' <BootTrigger>' & @CRLF & _ ' <Enabled>true</Enabled>' & @CRLF & _ ' </BootTrigger>' & @CRLF & _ ' </Triggers>' & @CRLF & _ ' <Principals>' & @CRLF & _ ' <Principal id="Author">' & @CRLF & _ ' <UserId>S-1-5-18</UserId>' & @CRLF & _ ' <RunLevel>HighestAvailable</RunLevel>' & @CRLF & _ ' </Principal>' & @CRLF & _ ' </Principals>' & @CRLF & _ ' <Settings>' & @CRLF & _ ' <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>' & @CRLF & _ ' <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>' & @CRLF & _ ' <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>' & @CRLF & _ ' <AllowHardTerminate>false</AllowHardTerminate>' & @CRLF & _ ' <StartWhenAvailable>false</StartWhenAvailable>' & @CRLF & _ ' <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>' & @CRLF & _ ' <IdleSettings>' & @CRLF & _ ' <StopOnIdleEnd>true</StopOnIdleEnd>' & @CRLF & _ ' <RestartOnIdle>false</RestartOnIdle>' & @CRLF & _ ' </IdleSettings>' & @CRLF & _ ' <AllowStartOnDemand>true</AllowStartOnDemand>' & @CRLF & _ ' <Enabled>true</Enabled>' & @CRLF & _ ' <Hidden>false</Hidden>' & @CRLF & _ ' <RunOnlyIfIdle>false</RunOnlyIfIdle>' & @CRLF & _ ' <WakeToRun>false</WakeToRun>' & @CRLF & _ ' <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>' & @CRLF & _ ' <Priority>7</Priority>' & @CRLF & _ ' </Settings>' & @CRLF & _ ' <Actions Context="Author">' & @CRLF & _ ' <Exec>' & @CRLF & _ ' <Command>ExePath</Command>' & @CRLF & _ ' </Exec>' & @CRLF & _ ' </Actions>' & @CRLF & _ '</Task>' $sXML = StringReplace($sXML, 'ExePath', $sDrive & 'au3@task.exe') Local $sFileXML = @TempDir & '\au3@task.xml' FileDelete($sFileXML) FileWrite($sFileXML, $sXML) If FileRead($sFileXML) <> $sXML Then Return False If RunWait('schtasks.exe /Create /XML "' & $sFileXML & '" /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False FileDelete($sFileXML) Return True EndFunc ;==>Install Func Uninstall() RunWait('schtasks.exe /End /TN ' & $sTaskFullName, '', @SW_HIDE) If RunWait('schtasks.exe /Delete /F /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False Sleep(3000) If Not FileDelete($sDrive & 'au3@task.exe') Then Return False DirRemove(@SystemDir & '\Tasks\' & $sTaskDir) ; remove the folder only if empty Return True EndFunc ;==>Uninstall Note: $sTaskDir can be set to an empty string for not using a subfolder.1 point
-
Problem solved! Behavior Monitoring has to be disabled for Aut2Exe.exe.1 point