1,601

Re: AHK: Замена "Window Spy"

Никак.

1,602

Re: AHK: Замена "Window Spy"

Malcev
А какой тогда смысл, если нет возможности использовать данные из этого Spy?

Если технология не освобождает людей от рутины, тогда весь технический прогресс бессмысленен.
© Жак Фреско

1,603

Re: AHK: Замена "Window Spy"

user7256, этот инструмент не для программного использования. С его помощью вы можете визуально ознакомиться со структурой окна, и скопировать какие-либо данные в буфер обмена.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

1,604 (изменено: user7256, 2020-12-31 02:22:03)

Re: AHK: Замена "Window Spy"

Плохо. Большинство - хочет строить свою логику на основе выдаваемых данных, а не просто скопировать в буфер.

Если технология не освобождает людей от рутины, тогда весь технический прогресс бессмысленен.
© Жак Фреско

1,605

Re: AHK: Замена "Window Spy"

Почему плохо? Просто эта программа не для этого. Вы можете посмотреть в коде, какие методы используются, и применять их отдельно. Либо спросить здесь, если чего-то не понимаете.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

1,606

Re: AHK: Замена "Window Spy"

user7256

Какой смысл использовать огромный кусок кода для своих мелких поделок? Не легче разобраться как оно устроено и сделать свою версию?

1,607

Re: AHK: Замена "Window Spy"

Библиотека Acc настолько сложна и забагованна, что без обертки пользоваться ей невозможно.
То тут, то там возникают ошибки.
Яркий тому пример - протухшая библиотека AccV2.ahk на гитхабе.

Хорошие программисты всегда стремились к понижению сложности.
Для уменьшения затрат на программирование практикуется code reuse, разбивка на модули и много других техник.
У вас ничего этого нет. Все в кучу на 8 тыс строк на 280 кб.

Вы предлагаете выдирать отдельные функции из вашего скрипта для использования в моих скриптах.
Но логичнее было бы один раз создать библиотеку Acc.ahk, и подключать к вашему AhkSpy.ahk где была бы только рисовалка формы с выводом данных в нее.
Это и было бы настоящим code reuse и разбивкой на модули на практике.
Так чтобы другие могли ей пользоваться, а не только трое программистов на свете, участвовавших в разработке.

Вы потратили столько времени на скрипт, это похвально.
Но ваш код очень быстро придет в негодность как только исчезнет желание его поддерживать.
И все сотни часов разработки окажутся потрачены зря, как у того самого юзера sancarn на гите.

Если технология не освобождает людей от рутины, тогда весь технический прогресс бессмысленен.
© Жак Фреско

1,608

Re: AHK: Замена "Window Spy"

Вот я выдрал все процедуры и хочу получить адрес бар из firefox с помощью GetBrowserURL()
Вот что получаю в результате:
https://i.imgur.com/C99WU58.png


ComObjError(false)

Global WS_EX_APPWINDOW := 0x40000, WS_CHILDWINDOW := 0x40000000, WS_EX_LAYERED := 0x80000
		, WS_EX_TRANSPARENT := 0x20, WS_POPUP := 0x80000000, WS_EX_NOACTIVATE := 0x8000000

#NoEnv
#UseHook
#KeyHistory 0

SetBatchLines, -1
ListLines, Off
DetectHiddenWindows, On
CoordMode, Pixel
CoordMode, Menu

oOther.anchor := {}, oOther.CurrentProcessId := DllCall("GetCurrentProcessId")

; If MemoryAnchor
; {
; 	If oOther.anchor["Win_text"] := IniRead("Win_Anchor")
; 		oOther.anchor["Win"] := 1
; 	If oOther.anchor["Control_text"] := IniRead("Control_Anchor")
; 		oOther.anchor["Control"] := 1
; } 

SeDebugPrivilege() 
oBody := oDoc.body 
oJScript := oDoc.Script
oJScript.WordWrap := WordWrap
oJScript.MoveTitles := MoveTitles
ComObjConnect(oDoc, Events)





url := GetBrowserURL()
OutputDebug, url: %url%

GetBrowserURL()
{
	WinGet, hw, ID, ahk_exe firefox.exe
	AccAccFocus(hw, name, value, role, irole)
	OutputDebug, value: %value%
	return value
}

SeDebugPrivilege() {
	Static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2

	hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, oOther.CurrentProcessId, Ptr)
	DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
	DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
	VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
	NumPut(1, TOKEN_PRIVILEGES, "UInt")
	NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
	NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
	DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
	res := A_LastError
	DllCall("CloseHandle", Ptr, token)
	DllCall("CloseHandle", Ptr, hProc)
	Return res  ;; в случае удачи 0
}


AccWindowFromObject(pacc) {
	If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc) ? ComObjValue(pacc) : pacc, "Ptr*", hWnd) = 0
		Return hWnd
}
	;;	http://forum.script-coding.com/viewtopic.php?pid=130762#p130762

AccAccFocus(hWnd, byref name, byref value, byref role, byref irole) {
	Acc := Acc_ObjectFromWindow(hWnd)
	While IsObject(Acc.accFocus)
		Acc := Acc.accFocus
	try 
	{
		child := Acc.accFocus
		name := Acc.accName(child)
		value := Acc.accValue(child)
		role := AccRole(Acc, child) 
		irole := Acc.accRole(0) 
	}
}

AccRole(Acc, ChildId=0) {
	Return ComObjType(Acc, "Name") = "IAccessible" ? AccGetRoleText(Acc.accRole(ChildId)) : ""
}

AccGetRoleText(nRole) {
	nSize := DllCall("oleacc\GetRoleText", "UInt", nRole, "Ptr", 0, "UInt", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "UInt", nRole, "str", sRole, "UInt", nSize+1)
	Return sRole
}

AccGetStateText(nState) {
	nSize := DllCall("oleacc\GetStateText", "UInt", nState, "Ptr", 0, "UInt", 0)
	VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetStateText", "UInt", nState, "str", sState, "UInt", nSize+1)
	Return sState
}

Acc_GetPath(byref arr) {
    Static DesktopHwnd := DllCall("User32.dll\GetDesktopWindow", "ptr") 
	If oPubObj.Acc.CLOAKED
		Return 0
	Acc := Object(oPubObj.Acc.AccObj) 
	arr := []
	
	While Hwnd := Acc_WindowFromObject(Parent := Acc_Parent(Acc)) { 
		If (DesktopHwnd != Hwnd)
			t1 := GetEnumIndex(Acc)
		If t1 = -1
			Return arr := ""
		If (PrHwnd != "" && Hwnd != PrHwnd)
		{
			PrHwnd := Format("0x{:06X}", PrHwnd)
			WinGetClass, WinClass, ahk_id %PrHwnd%
			WinGet, ProcessName, ProcessName, ahk_id %PrHwnd%
			arr.InsertAt(1, {Hwnd: PrHwnd, Path: SubStr(t2, 1, -1), WinClass: WinClass, ProcessName: ProcessName})
		}
		if (t1 = "" || Hwnd = DesktopHwnd)
		   break
		t2 := t1 "." t2
		PrHwnd := Hwnd
		Acc := Parent 
	}
	Return arr.Count()
}

GetEnumIndex(Acc) {	
	If oPubObj.Acc.CLOAKED
		Return -1
	For Each, child in Acc_Children(Acc_Parent(Acc))
	{ 
		if CompareAcc(child, Acc) 
			return A_Index
	}
}

CompareAcc(Acc1, Acc2) { 
	if IsObject(Acc1) && IsObject(Acc2)
	&& (Acc_Location(Acc1) = Acc_Location(Acc2))
	&& (Acc1.accDefaultAction(0) = Acc2.accDefaultAction(0)) 	
	&& (Acc1.accDescription(0) = Acc2.accDescription(0)) 	
	&& (Acc1.accHelp(0) = Acc2.accHelp(0)) 	
	&& (Acc1.accKeyboardShortcut(0) = Acc.accKeyboardShortcut(0)) 
	
	&& (Acc1.accChildCount = Acc2.accChildCount) 
	&& (Acc1.accName(0) = Acc2.accName(0)) 	
	&& (Acc1.accRole(0) = Acc2.accRole(0)) 	
	&& (Acc1.accState(0) = Acc2.accState(0)) 
	&& (Acc1.accValue(0) = Acc2.accValue(0))
		return 1
}

Acc_Children(Acc) {
	if ComObjType(Acc, "Name") != "IAccessible"
		return
	else
	{
		cChildren := Acc.accChildCount, Children := [] 
		if DllCall("oleacc\AccessibleChildren"
		, "Ptr", ComObjValue(Acc)
		, "Int", 0, "Int", cChildren
		, "Ptr", VarSetCapacity(varChildren, cChildren * (8 + 2 * A_PtrSize), 0) * 0 + &varChildren
		, "Int*", cChildren) = 0 
		{
			Loop %cChildren%
				i := (A_Index - 1) * (A_PtrSize * 2 + 8) + 8
				, child := NumGet(varChildren, i)
				, Children.Insert(NumGet(varChildren, i - 8) = 9 ? Acc_Query(child) : child)
				, NumGet(varChildren, i - 8) = 9 ? ObjRelease(child) : ""
			return Children.MaxIndex() ? Children : ""
		}
	}
}
AccGetLocation(Acc, ChildId=0) {
	Static x := 0, y := 0, w := 0, h := 0
	try Acc.accLocation(ComObj(0x4003,&x), ComObj(0x4003,&y), ComObj(0x4003,&w), ComObj(0x4003,&h), ChildId)
	AccCoord[1]:=NumGet(x,0,"int"), AccCoord[2]:=NumGet(y,0,"int"), AccCoord[3]:=NumGet(w,0,"int"), AccCoord[4]:=NumGet(h,0,"int")
}
Acc_Location(Acc, ChildId=0) {
	Static x := 0, y := 0, w := 0, h := 0
	try Acc.accLocation(ComObj(0x4003,&x), ComObj(0x4003,&y), ComObj(0x4003,&w), ComObj(0x4003,&h), ChildId)
	return "x" NumGet(x, 0, "int") " y" NumGet(y, 0, "int") " w" NumGet(w, 0, "int") " h" NumGet(h, 0, "int")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	If DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32
		, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
		Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_ObjectFromWindow(hWnd, idObject = 0) {
	If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF
		, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81
		,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
		Return ComObjEnwrap(9,pacc,1)
}
Acc_WindowFromObject(pacc) {
	If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc) ? ComObjValue(pacc) : pacc, "Ptr*", hWnd)=0
		Return	hWnd
} 
Acc_Parent(Acc) { 
	try parent := Acc.accParent 
	return parent ? Acc_Query(parent) : ""
}
Acc_Query(Acc) {
	try return ComObj(9, ComObjQuery(Acc, "{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
	static setting:=0
	return p=""?setting:setting:=p
}
Acc_Role(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_GetRoleText(nRole)
{
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	Return	sRole
}
Acc_ChildrenByRole(Acc, Role) {
	if ComObjType(Acc,"Name")!="IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren% {
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
				if NumGet(varChildren,i-8)=9
					AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
				else
					Acc_Role(Acc, child)=Role?Children.Insert(child):
			}
			return Children.MaxIndex()?Children:, ErrorLevel:=0
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
	static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
	AccObj :=   IsObject(WinTitle)? WinTitle
			:   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
	if ComObjType(AccObj, "Name") != "IAccessible"
		ErrorLevel := "Could not access an IAccessible Object"
	else {
		StringReplace, ChildPath, ChildPath, _, %A_Space%, All
		AccError:=Acc_Error(), Acc_Error(true)
		Loop Parse, ChildPath, ., %A_Space%
			try {
				if A_LoopField is digit
					Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
				else
					RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
				if Not Children.HasKey(m2)
					throw
				AccObj := Children[m2]
			} catch {
				ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
				if Acc_Error()
					throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
				return   ; Acc_Error
			}
		Acc_Error(AccError)
		StringReplace, Cmd, Cmd, %A_Space%, , All
		properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
		try {
			if (Cmd = "Location")
				AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
			  , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
			else if (Cmd = "Object")
				ret_val := AccObj
			else if Cmd in Role,State
				ret_val := Acc_%Cmd%(AccObj, ChildID+0)
			else if Cmd in ChildCount,Selection,Focus
				ret_val := AccObj["acc" Cmd]
			else
				ret_val := AccObj["acc" Cmd](ChildID+0)
		} catch {
			ErrorLevel := """" Cmd """ Cmd Not Implemented"
			if Acc_Error()
				throw Exception("Cmd Not Implemented", -1, Cmd)
			return
		}
		return ret_val, ErrorLevel:=0
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}


AccUnderMouse(WinID, ByRef child) {
	Static h
	If Not h
		h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
	If DllCall("oleacc\AccessibleObjectFromPoint"
		, "Int64", 0 * DllCall("GetCursorPos", "Int64*", pt) + pt, "Ptr*", pacc
		, "Ptr", VarSetCapacity(varChild, 8 + 2 * A_PtrSize, 0) * 0 + &varChild) = 0
	Acc := ComObjEnwrap(9, pacc, 1)
	If IsObject(Acc)
		Return Acc, child := NumGet(varChild, 8, "UInt")
}
Если технология не освобождает людей от рутины, тогда весь технический прогресс бессмысленен.
© Жак Фреско

1,609

Re: AHK: Замена "Window Spy"

user7256 пишет:

Библиотека Acc настолько сложна и забагованна, что без обертки пользоваться ей невозможно.

Пока я багов не обнаружил и по сравнению с UIA ничуть не сложна.

1,610

Re: AHK: Замена "Window Spy"

user7256, думаю, не стоит в этой теме обсуждать неудачные попытки использования выдранного наугад кода. Эта тема предназначена для обсуждения AhkSpy. Создайте свою тему со внятным заголовком, напишите, что пытались сделать, задайте конкретный вопрос.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

1,611

Re: AHK: Замена "Window Spy"

serzh82saratov, у меня последняя версия не подсвечивает acc-элементы на семёрке, на десятке работает.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

1,612

Re: AHK: Замена "Window Spy"

У меня нет семёрки, а координаты и размер правильно определяет?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,613

Re: AHK: Замена "Window Spy"

Отбой, я просто не включил режим Control.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

1,614

Re: AHK: Замена "Window Spy"

Такой вопрос на гитхабе задали:

Is it possible to retrieve the caret position in edit fields? I know this is possible in standard Win32 control edits, but I wonder if UIA allows this.

тоже интересно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,615

Re: AHK: Замена "Window Spy"

Через UIA нельзя.
Только через MSAA.

1,616

Re: AHK: Замена "Window Spy"

У тебя есть что то работающее?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,617

Re: AHK: Замена "Window Spy"

Хотя через uia можно наверное так:
https://docs.microsoft.com/en-us/window … caretrange
Работающего нету. Но на нашем форуме через iaccessible это обсуждалось.

1,618

Re: AHK: Замена "Window Spy"

IUIAutomationTextPattern2 тоже смотрел, нигде не нашёл примеров.

Malcev пишет:

на нашем форуме

Ссылки нет?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,619

Re: AHK: Замена "Window Spy"

serzh82saratov пишет:

IUIAutomationTextPattern2 тоже смотрел, нигде не нашёл примеров.

Не думаю, что в этом будет толк, так как контрол должен поддерживать text pattern, а это далеко не всегда.

serzh82saratov пишет:

Ссылки нет?

http://forum.script-coding.com/viewtopic.php?id=10392

1,620

Re: AHK: Замена "Window Spy"

Но если уж так хочется потестировать text pattern, то можешь добавить его в класс от jethrow, как я сделал тут:
https://www.autohotkey.com/boards/viewtopic.php?t=69627
Либо самому вызывать, как я сделал тут:
https://www.autohotkey.com/boards/viewt … p?p=329332

1,621

Re: AHK: Замена "Window Spy"

Это работает http://forum.script-coding.com/viewtopi … 940#p97940, нашёл сразу.

Malcev пишет:

как я сделал тут

Так сразу не сообразишь, какой именно там код?
Я даже не знаю какой из способов мне проще адаптировать к UIASub в AhkSpy.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,622

Re: AHK: Замена "Window Spy"

f11::
if !hVolume
{
   ControlGet, hVolume, hwnd,, ToolbarWindow323, ahk_class Shell_TrayWnd
   IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
   DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", hVolume, "ptr*", tray)   ; IUIAutomation::ElementFromHandle
   VOLUME_GUID := DllCall("oleaut32\SysAllocString", "str", "{7820AE73-23E3-4229-82C1-E41CB67D5B9C}", "ptr")
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_BSTR := 8, variant, 0, "ushort")
   NumPut(VOLUME_GUID, variant, 8, "ptr")
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_AutomationIdPropertyId := 30011, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_AutomationIdPropertyId := 30011, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   DllCall("oleaut32\SysFreeString", "ptr", VOLUME_GUID)
}
DllCall(NumGet(NumGet(tray+0)+5*A_PtrSize), "ptr", tray, "int", TreeScope_Descendants := 0x4, "ptr", condition, "ptr*", element) ; IUIAutomationElement::FindFirst
DllCall(NumGet(NumGet(element+0)+16*A_PtrSize), "ptr", element, "int", UIA_InvokePatternId := 10000, "ptr*", invoke)   ; IUIAutomationElement::GetCurrentPattern
DllCall(NumGet(NumGet(invoke+0)+3*A_PtrSize), "ptr", invoke)   ; IInvokeProvider::Invoke
ObjRelease(element)
ObjRelease(invoke)

1,623

Re: AHK: Замена "Window Spy"

Ладно, долго разбираться, асс пойдёт.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,624

Re: AHK: Замена "Window Spy"

Ну и правильно.
Например в адресной строке  у фаерфокса положение каретки через UIA не получить, так как  textpattrern не поддерживается.
А через ACC получается без проблем.

1,625

Re: AHK: Замена "Window Spy"

Думаю не очень правильно, или ты считаешь что не может быть такого, когда UIA работает а MSAA нет.
Да, и как ты узнал что UIA не работает, в inspect не нашёл такого.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,626

Re: AHK: Замена "Window Spy"

serzh82saratov пишет:

или ты считаешь что не может быть такого, когда UIA работает а MSAA нет.

Утверждать такого не буду, но я проверил на пару программах и пока таких случаев не обнаружил.
В inspect надо смотреть IsTextPattern2Available: true/false.

1,627

Re: AHK: Замена "Window Spy"

Спасибо.
Добавил в 4.70.
Accessible > Caret position relative.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,628

Re: AHK: Замена "Window Spy"

Looking forward to the retrieval of the caret position index in the text field.

Теперь такое хотят.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,629

Re: AHK: Замена "Window Spy"

Ты можешь открыть донат и выполнять подобные хотелки за пожертвования.

1,630

Re: AHK: Замена "Window Spy"

Malcev

Следующая версия будет вся напичкана рекламой того, что может реализовать автор программы. Придётся искать Adblock.ahk для использования.

1,631

Re: AHK: Замена "Window Spy"

Зачем напичкана?
Я бы сделал обычное стандартное меню у программы и в меню help прописал бы donate.
Как это сделано, например, у WinSCP.

1,632

Re: AHK: Замена "Window Spy"

Вопрос сам по себе интересный. Так понимаю в MSAA этого нет, в IUIAutomationTextPattern2 не знаю.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,633

Re: AHK: Замена "Window Spy"

4.71 добавил в Buttton тест ControlSend из определённого перед этим контрола, если такого нет то окна.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,634 (изменено: Malcev, 2021-01-20 04:57:31)

Re: AHK: Замена "Window Spy"

serzh82saratov пишет:

Вопрос сам по себе интересный

Ну если уж такой интересный, то так вызывается.
ЗЫ Освобождать ресурсы не интересно (лень).

f11::
IUIAutomation := ComObjCreate(CLSID_CUIAutomation8 := "{e22ad333-b25f-460c-83d0-0581107395c9}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
DllCall(NumGet(NumGet(IUIAutomation+0)+7*A_PtrSize), "ptr", IUIAutomation, "int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "ptr*", ElementFromPoint)   ; IUIAutomation::ElementFromPoint
DllCall(NumGet(NumGet(ElementFromPoint+0)+16*A_PtrSize), "ptr", ElementFromPoint, "int", UIA_TextPattern2Id := 10024, "ptr*", ITextProvider2)   ; IUIAutomationElement::GetCurrentPattern
DllCall(NumGet(NumGet(ITextProvider2+0)+7*A_PtrSize), "ptr", ITextProvider2, "ptr*", ITextRangeProvider_DocumentRange)   ; ITextProvider2::get_DocumentRange
DllCall(NumGet(NumGet(ITextProvider2+0)+10*A_PtrSize), "ptr", ITextProvider2, "int*", isActive, "ptr*", ITextRangeProvider_CaretRange)   ; ITextProvider2::GetCaretRange
DllCall(NumGet(NumGet(ITextRangeProvider_CaretRange+0)+5*A_PtrSize), "ptr", ITextRangeProvider_CaretRange, "int", TextPatternRangeEndpoint_Start := 0, "ptr", ITextRangeProvider_DocumentRange, "int", TextPatternRangeEndpoint_Start := 0, "uint*", caretPos)   ; ITextRangeProvider2::CompareEndpoints
msgbox % caretPos

1,635

Re: AHK: Замена "Window Spy"

Пока ничего не понятно, но жутко интересно. Можешь ещё раз вкратце объяснить, где ты берёшь смещения и Id.
ITextProvider2 это не IUIAutomationTextPattern2?

На первый взгляд  действительно бесполезная штука, показывает только в обычном блокноте. Если isActive = 0, то нет смысла пробовать другие интерфейсы UIA?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,636 (изменено: Malcev, 2021-01-20 14:18:40)

Re: AHK: Замена "Window Spy"

Я взял код отсюда:
https://stackoverflow.com/questions/613 … on-not-the
Создал IUIAutomation2 интерфейс:

IUIAutomation := ComObjCreate(CLSID_CUIAutomation8 := "{e22ad333-b25f-460c-83d0-0581107395c9}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")

https://docs.microsoft.com/en-us/previo … 6(v=vs.85)
После чего взял код получения элемента под курсором мыши

DllCall(NumGet(NumGet(IUIAutomation+0)+7*A_PtrSize), "ptr", IUIAutomation, "int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "ptr*", ElementFromPoint)   ; IUIAutomation::ElementFromPoint

отсюда
https://github.com/jethrow/UIA_Interfac … ce.ahk#L72
После чего нам надо получить нужный нам паттерн элемента через IUIAutomationElement::GetCurrentPattern

DllCall(NumGet(NumGet(ElementFromPoint+0)+16*A_PtrSize), "ptr", ElementFromPoint, "int", UIA_TextPattern2Id := 10024, "ptr*", ITextProvider2)   ; IUIAutomationElement::GetCurrentPattern

Заходишь по этой ссылке, смотришь, что надо вписывать:
https://docs.microsoft.com/en-us/window … entpattern

PATTERNID
The identifier of the control pattern. For a list of control pattern IDs, see Control Pattern Identifiers.

Там видишь, что UIA_TextPattern2Id = 10024.
Дальше идешь в самый низ метода и видишь что интерфейс расписан в

Header uiautomationclient.h (include UIAutomation.h)

Гуглишь его - выходишь на гитхаб
https://github.com/tpn/winsdk-10/blob/m … onClient.h
Вбиваешь там в поиск GetCurrentPattern.
Получаешь
https://github.com/tpn/winsdk-10/blob/m … nt.h#L1766
После чего считаешь какой он идет по счету.
Получаешь 16.
И так далее.

serzh82saratov пишет:

ITextProvider2 это не IUIAutomationTextPattern2?

Не, это разные интерфейсы. Нам правильней использовать IUIAutomationTextPattern2.
Это я названия попутал.

1,637

Re: AHK: Замена "Window Spy"

serzh82saratov пишет:

На первый взгляд  действительно бесполезная штука, показывает только в обычном блокноте. Если isActive = 0, то нет смысла пробовать другие интерфейсы UIA?

Не понял, а при чем тут isActive = 0?
При isActive = 0 в блокноте всё-равно показывает.

1,638

Re: AHK: Замена "Window Spy"

Спасибо, всё понятно, тебе надо в педагоги.

Malcev пишет:

Не понял, а при чем тут isActive = 0?

Спутал её с проверкой наличия у элемента TextPattern.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,639 (изменено: Malcev, 2021-03-18 07:57:02)

Re: AHK: Замена "Window Spy"

Malcev пишет:

Предлагаю всегда вставлять в Acc Do Default Action, так как оно может быть прописано, даже когда не определено.

Malcev пишет:

если свойство DefaultAction у элемента не определено, то применив к этому элементу метод DoDefaultAction в результате может дать нажатие на этот элемент.

Не совсем правильно.
DoDefaultAction убираем.
Если возвращает пустоту, но ошибки нету, значит пишем в Action

[null]  ▪   Execute

Если же возвращает ошибку, то пишем в defaultaction

[Error: hr=0x80020003 - Member not found.] без Execute

1,640

Re: AHK: Замена "Window Spy"

Malcev
Забыл там уже всё, можешь кусок кода показать?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,641 (изменено: Malcev, 2021-03-25 22:22:57)

Re: AHK: Замена "Window Spy"

Это убираем:

id='acc_DoDefaultAction2'>

А вот сюда

id='acc_DoDefaultAction'>

вставляем если нету ошибки и ничему не равно, то

[null]  ▪   Execute

или если есть ошибка, то

[Error: hr=0x80020003 - Member not found.] без Execute.
[Error: hr=0x0001 - Does not have a default action.] без Execute.
[Error: hr=0x80070057 - An argument is not valid.] без Execute.

То есть проверяем, что возвращает IAccessible::get_accDefaultAction.
https://docs.microsoft.com/en-us/window … aultaction

1,642

Re: AHK: Замена "Window Spy"

Посмотрю обязательно, сейчас время нет.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

1,643 (изменено: Malcev, 2021-04-08 20:05:24)

Re: AHK: Замена "Window Spy"

Баг в проверке acc пути.
На броузере vivaldi при дефалтных установках путь для получения адресной строки должен  быть таким

4.1.2.1.1.1.1.1.2.1.2.3.1.1

AhkSpy же выводит

4.1.1.1.2.1.2.3.1.1

Так же если есть желание, то можно добавить нахождение пути в буквенной форме через role properties.