Advertisement
AZJIO

Захват элементов под курсором

Jun 11th, 2012
1,297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 7.11 KB | None | 0 0
  1.  
  2. ; Ссылка по которой были использованы материалы
  3. ; http://www.autoitx.com/archiver/tid-14317.html
  4.  
  5. #AutoIt3Wrapper_Run_Obfuscator=y
  6. #Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
  7.  
  8. #include <EditConstants.au3>
  9. #include <WindowsConstants.au3>
  10.  
  11. ;  opt("MustDeclareVars", 1)
  12. Opt("GUIOnEventMode", 1)
  13.  
  14. Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
  15. Global Const $hOLE32 = DllOpen("ole32.dll")
  16. Global Const $hOLEACC = DllOpen("oleacc.dll")
  17. Global Const $hOleAut = DllOpen("oleaut.dll")
  18.  
  19. Global Const $VT_I2 = 2
  20. Global Const $VT_I4 = 3
  21. Global Const $VT_R8 = 5
  22. Global Const $VT_BSTR = 8
  23. Global Const $VT_DISPATCH = 9
  24. Global Const $VT_I1 = 16
  25.  
  26. Global Const $tagVARIANT = "ushort vt;ushort r1;ushort r2;ushort r3;uint64 data"
  27. Global Const $tagLOOKUP_TABLE_ENTRY = "ptr name;ptr value;dword flags;"
  28. Global Const $LOOKUP_TABLE_ENTRY_SIZE = DllStructGetSize(DllStructCreate($tagLOOKUP_TABLE_ENTRY))
  29. Global Const $hOLEOUT = DllOpen("oleaut32.dll")
  30. Global Const $SizeOfPtr = DllStructGetSize(DllStructCreate("ptr"))
  31.  
  32. Global $aCall, $oIAccesible
  33. Global $oChild
  34.  
  35. Global Const $__Au3Obj_tagVARIANT = "ushort vt;ushort r1;ushort r2;ushort r3;ptr data; ptr"
  36. Global $tVar = DllStructCreate($__Au3Obj_tagVARIANT)
  37. Global $pVar = DllStructGetPtr($tVar)
  38.  
  39. Global $myEdit, $aMPx, $aMPy, $TmpEdit, $sbl=ChrW('0x25CF'), $sep=ChrW('0x25BA')&' '
  40.  
  41. GUICreate('Элемент под курсором')
  42. $myEdit = GUICtrlCreateEdit("First line" & @CRLF, 10, 10, 380, 330, $ES_AUTOVSCROLL + $WS_VSCROLL)
  43. GUISetOnEvent(-3, "_Quit")
  44. GUISetState()
  45. __Au3Obj_VariantInit($pVar)
  46.  
  47. While 1
  48.     _GetInfo()
  49.     Sleep(200)
  50. WEnd
  51.  
  52. Func _GetInfo()
  53.     Local $aMousePos, $aRoleCall, $oIAccesible, $tInfo, $tmp
  54.     $aMousePos = MouseGetPos()
  55.     If $aMPx = $aMousePos[0] And $aMPy = $aMousePos[1] Then ; если координаты мыши не изменились, то ничего не делаем
  56.         Return
  57.     Else
  58.         $aMPx = $aMousePos[0]
  59.         $aMPy = $aMousePos[1]
  60.     EndIf
  61.  
  62.     $aCall = DllCall($hOLEACC, "int", "AccessibleObjectFromPoint", _
  63.             "int", $aMousePos[0], _
  64.             "int", $aMousePos[1], _
  65.             "ptr*", 0, _
  66.             "ptr", $pVar)
  67.  
  68.     If @error Or $aCall[0] <> 0 Then
  69.         ; Ошибка в получении доступа
  70.         Sleep(200)
  71.         Return
  72.     EndIf
  73.     $oIAccesible = __Au3Obj_ConvertPtrToIDispatch($aCall[3]) ; Создаёт IDispatch при отсутствии ошибок
  74.  
  75.     If IsObj($oIAccesible) Then ; если является объектом
  76.  
  77.         $oChild = Execute(COMVariantToValue($pVar)) ; int64 в int32
  78.         $tInfo = ''
  79.         ; $tInfo &= $sbl & " Событие: " &@Tab&$sep& $oIAccesible.accDefaultAction($oChild) & @CRLF
  80.         $tInfo &= $sbl & " Описание системных элементов: " &@Tab&$sep& $oIAccesible.accDescription($oChild) & @CRLF
  81.         $tInfo &= $sbl & ' Номер пункта в списке: ' &@Tab&$sep& $oChild & @CRLF
  82.         $tInfo &= $sbl & " >>> Текст: " &@Tab&$sep& $oIAccesible.accName($oChild) & @CRLF
  83.         ; Dim $sText
  84.  
  85.         ; Получает текстовое описание типа элемента (кнопка, окно редактирования, переключатель, флажок)
  86.         $aRoleCall = DllCall($hOLEACC, "int", "GetRoleText", "DWORD", $oIAccesible.accRole($oChild), "str", '', "int", 255)
  87.         $tInfo &= $sbl & " Тип элемента: " &@Tab&$sep& $oIAccesible.accRole($oChild) & " : " & $aRoleCall[2] & @CRLF
  88.         $tInfo &= $sbl & " Состояние: " &@Tab&$sep& $oIAccesible.accState($oChild) & @CRLF
  89.         $tInfo &= $sbl & " Содержимое: " &@Tab&$sep& $oIAccesible.accValue($oChild) & @CRLF
  90.  
  91.         If Not($TmpEdit == $tInfo) Then
  92.             $TmpEdit = $tInfo
  93.             GUICtrlSetData($myEdit, $tInfo)
  94.         EndIf
  95.  
  96.     EndIf
  97.  
  98.     ;  Не забудьте очистить обратный результат
  99.     If UBound($aCall) > 3 Then __Au3Obj_VariantClear($aCall[4])
  100.     $oIAccesible = 0 ; очистить Объект
  101. EndFunc
  102.  
  103. ; Зарегистрированная функция вывода COM ошибок
  104. Func MyErrFunc()
  105.     ConsoleWrite("!Ошибка COM!   " & "Номер: " & Hex($oMyError.number, 8) & "  описание: " & $oMyError.windescription & @CRLF)
  106. EndFunc
  107.  
  108. ; В итоге мы все же хотим объект AutoIt. Эта функция преобразовывает указатель в объект AutoIt
  109. Func ConvertPtrToIDispatch($pIDispatch)
  110.     ; Это было бы в 10000 раз проще, если бы autoit поддерживал тип idispatch* в dllstructs...
  111.     ; К счастью memcpy может скопировать указатель в idispatch*, повезло нам.
  112.     Local $aCall = DllCall("kernel32.dll", "none", "RtlMoveMemory", _
  113.             "idispatch*", 0, _
  114.             "ptr*", $pIDispatch, _
  115.             "dword", 4)
  116.  
  117.     If @error Then
  118.         Return SetError(1, 0, 0)
  119.     EndIf
  120.  
  121.     Return $aCall[1]
  122.  
  123. EndFunc
  124.  
  125. Func __Au3Obj_ConvertPtrToIDispatch($pIDispatch)
  126.     ; Автор: monoceres
  127.     Local $iSize = 4 + (4 * @AutoItX64)
  128.     Local $aCall = DllCall("kernel32.dll", "none", "RtlMoveMemory", "idispatch*", 0, "ptr*", $pIDispatch, "dword", $iSize)
  129.     If @error Then Return SetError(1, 0, 0)
  130.     Return $aCall[1]
  131. EndFunc
  132.  
  133. Func __Au3Obj_VariantClear($pvarg)
  134.     ; Автор: Prog@ndy
  135.     Local $aCall = DllCall($hOleAut, "long", "VariantClear", "ptr", $pvarg)
  136.     If @error Then Return SetError(1, 0, 1)
  137.     Return $aCall[0]
  138. EndFunc
  139.  
  140. Func __Au3Obj_VariantInit($pvarg)
  141.     ; Автор: Prog@ndy
  142.     Local $aCall = DllCall($hOleAut, "long", "VariantInit", "ptr", $pvarg)
  143.     If @error Then Return SetError(1, 0, 1)
  144.     Return $aCall[0]
  145. EndFunc
  146.  
  147. Func VTType2AutoitType($iVT_Type)
  148.     Switch $iVT_Type
  149.         Case $VT_I1
  150.             Return "byte"
  151.         Case $VT_I2
  152.             Return "short"
  153.         Case $VT_I4
  154.             Return "int"
  155.         Case $VT_BSTR
  156.             Return "wstr"
  157.         Case $VT_R8
  158.             Return "double"
  159.         Case $VT_DISPATCH
  160.             Return "idispatch"
  161.     EndSwitch
  162. EndFunc
  163.  
  164. Func COMVariantToValue($pVariant)
  165.     Local $hVariant = DllStructCreate($tagVARIANT, $pVariant)
  166.     ; Translate the vt id to a autoit dllcall type
  167.     $sType = VTType2AutoitType(DllStructGetData($hVariant, "vt"))
  168.  
  169.     If $sType = "wstr" Then
  170.         $pString = DllStructCreate("ptr", DllStructGetPtr($hVariant, "data"))
  171.         ; Getting random crashes when trusting autoit to automatically use right size.
  172.         ; doing it myself instead (also, it should be a BSTR, but it's not. Is autoit not obeying the rules!?
  173.         $iString_Size = wcslen(DllStructGetData($pString, 1))
  174.  
  175.         ; Sorry trancexx, doesn't seem to work on large strings (crashes like crazy when trying to use on 1 MB string)
  176.         ;$tSub = DllStructCreate("dword", DllStructGetData($str_ptr, 1) - 4) ; <- move pointer back 4 bytes!
  177.  
  178.         $hData = DllStructCreate("wchar[" & $iString_Size & "]", DllStructGetData($pString, 1))
  179.  
  180.     ElseIf $sType = "idispatch" Then
  181.  
  182.         Return ConvertPtrToIDispatch(DllStructGetData(DllStructCreate("ptr", DllStructGetPtr($hVariant, "data")), 1))
  183.  
  184.     Else
  185.         $hData = DllStructCreate($sType, DllStructGetPtr($hVariant, "data"))
  186.     EndIf
  187.  
  188.     Return DllStructGetData($hData, 1)
  189. EndFunc
  190.  
  191. ; Find out length of string. I do not trust autoit to do this.
  192. Func wcslen($pWString)
  193.     $aCall = DllCall("ntdll.dll", "dword:cdecl", "wcslen", "ptr", $pWString)
  194.     Return $aCall[0]
  195. EndFunc
  196.  
  197. Func _Quit()
  198.     Exit
  199. EndFunc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement