getting a link's URL or the content of a tooltip

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Benny-D
Posts: 302
Joined: 12 Mar 2014, 10:09

getting a link's URL or the content of a tooltip

09 Jul 2014, 11:51

In FireFox, whenever I place the cursor on a hyper-link, in the lower left corner of the screen I see the URL of that link ("link's location"), and right next to the cursor a tool-tip appears containing one word that I want to "catch" (for example, to place it into the clipboard or some other variable). The URL that is shown in the lower left corner of the screen also contains that word, which I can "fish out" of the URL by means of RegExMatch. So I only need to catch either that URL or the content of the tooltip. How can I do that in AHK?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: getting a link's URL or the content of a tooltip

10 Jul 2014, 02:08

You will need Acc.ahk.

Code: Select all

; From http://www.autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/?p=493839

f1:: MsgBox % GetTextUnderMouse()

GetTextUnderMouse() {
	Acc := Acc_ObjectFromPoint(child)
	try value := Acc.accValue(child)
	if Not value
		try value := Acc.accName(child)
	return value
}
And check out Accessible Info Viewer.
User avatar
Benny-D
Posts: 302
Joined: 12 Mar 2014, 10:09

Re: getting a link's URL or the content of a tooltip

10 Jul 2014, 10:02

WOW! Thank you very much tmplinshi! It works.

And thank you also for the links.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: getting a link's URL or the content of a tooltip

14 Dec 2018, 06:10

Code: Select all

f1:: MsgBox % GetTextUnderMouse()

GetTextUnderMouse() {
	Acc := Acc_ObjectFromPoint(child)
	try value := Acc.accValue(child)
	if Not value
		try value := Acc.accName(child)
	return value
}
This code does not work with google chrome address bar.
But this code works:

Code: Select all

f1::
hwndChrome := WinExist("ahk_class Chrome_WidgetWin_1")
AccChrome := Acc_ObjectFromWindow(hwndChrome)
AccAddressBar := GetElementByName(AccChrome, "Address and search bar")
MsgBox % AccAddressBar.accValue(0)
return

GetElementByName(AccObj, name) {
   if (AccObj.accName(0) = name)
      return AccObj

   for k, v in Acc_Children(AccObj)
      if IsObject(obj := GetElementByName(v, name))
         return obj
}
Anybody knows why?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: getting a link's URL or the content of a tooltip

14 Dec 2018, 14:39

This worked for me by using accParent. Perhaps the element under the cursor was too far down the hierarchy. Cheers.

Code: Select all

q:: ;google chrome - get address bar text (when hovered over it)
Acc := Acc_ObjectFromPoint()
Acc := Acc.accParent
Acc := GetElementByName(Acc, "Address and search bar")
if IsObject(Acc)
	MsgBox, % Acc.accValue(0)
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: getting a link's URL or the content of a tooltip

15 Dec 2018, 07:23

Thank You.
Do You think is it possible to get text without using GetElementByName(Acc, "Address and search bar")?
I mean - how to mofify GetTextUnderMouse() function to show text in such situations?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: getting a link's URL or the content of a tooltip

15 Dec 2018, 22:58

Here's an attempt at a function to get the text from under the cursor. Cheers.

Code: Select all

q:: ;acc get text under cursor
;first available name and value (may be from different elements):
MsgBox, % JEE_AccGetTextUnderCursor("n") "`r`n`r`n" JEE_AccGetTextUnderCursor("v")
JEE_AccGetTextUnderCursor("v", oAcc1, vChildID1)
JEE_AccGetTextUnderCursor("n", oAcc2, vChildID2)
;name/value from element with first available value:
MsgBox, % oAcc1.accName(vChildID1) "`r`n`r`n" oAcc1.accValue(vChildID1)
;name/value from element with first available name:
MsgBox, % oAcc2.accName(vChildID2) "`r`n`r`n" oAcc2.accValue(vChildID2)
return

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

JEE_AccGetTextUnderCursor(vOpt:="v", ByRef oAcc2:="", ByRef vChildID2:=0)
{
	local
	vType := InStr(vOpt, "v") ? "accValue" : "accName"
	oAcc := Acc_ObjectFromPoint(vChildID)
	vText := ""
	try vText := oAcc[vType](vChildID)
	if (vText = "") && vChildID
		try vText := oAcc[vType](0)
	if (vText = "")
	{
		oRect := Acc_Location(oAcc, vChildID)
		VarSetCapacity(RECT1, 16)
		VarSetCapacity(RECT2, 16)
		VarSetCapacity(RECT3, 16)
		DllCall("user32\SetRect", Ptr,&RECT1, Int,oRect.x, Int,oRect.y, Int,oRect.x+oRect.w, Int,oRect.y+oRect.h)
		oAcc := oAcc.accParent
		for _, oChild in Acc_Children(oAcc)
		{
			vText := ""
			oRect := Acc_Location(oChild)
			DllCall("user32\SetRect", Ptr,&RECT2, Int,oRect.x, Int,oRect.y, Int,oRect.x+oRect.w, Int,oRect.y+oRect.h)
			if !DllCall("user32\IntersectRect", Ptr,&RECT3, Ptr,&RECT1, Ptr,&RECT2)
				continue
			try vText := oChild[vType](0)
			if (vText = "")
				continue
			oAcc2 := oChild
			break
		}
	}
	else
		oAcc2 := oAcc
	vChildID2 := vChildID
	oAcc := oChild := ""
	return vText
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: getting a link's URL or the content of a tooltip

15 Dec 2018, 23:15

Thank You.
It does not work with chrome bookmarks bar.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: getting a link's URL or the content of a tooltip

15 Dec 2018, 23:39

This quick fix works, although it breaks the script for lower level text.

Code: Select all

;before:
oAcc := oAcc.accParent
;after:
Loop, 2
	oAcc := oAcc.accParent
The problem is that there isn't an easy way to decide how many levels up to check text, as mentioned here:
How to get the full ACC path for control on cursor? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=56470

[EDIT:] Here's an improved function that can check further up the hierarchy until a match is found.

Code: Select all

q:: ;acc get text under cursor
;first available name and value (may be from different elements):
MsgBox, % JEE_AccGetTextUnderCursor("n") "`r`n`r`n" JEE_AccGetTextUnderCursor("v")
JEE_AccGetTextUnderCursor("v", oAcc1, vChildID1)
JEE_AccGetTextUnderCursor("n", oAcc2, vChildID2)
;name/value from element with first available value:
MsgBox, % oAcc1.accName(vChildID1) "`r`n`r`n" oAcc1.accValue(vChildID1)
;name/value from element with first available name:
MsgBox, % oAcc2.accName(vChildID2) "`r`n`r`n" oAcc2.accValue(vChildID2)
return

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

JEE_AccGetTextUnderCursor(vOpt:="v", ByRef oAcc2:="", ByRef vChildID2:=0, vRecurseDepth:=3)
{
	local
	vType := InStr(vOpt, "v") ? "accValue" : "accName"
	oAcc := Acc_ObjectFromPoint(vChildID)
	vText := ""
	try vText := oAcc[vType](vChildID)
	if (vText = "") && vChildID
		try vText := oAcc[vType](0)
	if (vText = "")
	{
		VarSetCapacity(RECT1, 16)
		VarSetCapacity(RECT2, 16)
		VarSetCapacity(RECT3, 16)
		oRect := Acc_Location(oAcc, vChildID)
		DllCall("user32\SetRect", Ptr,&RECT1, Int,oRect.x, Int,oRect.y, Int,oRect.x+oRect.w, Int,oRect.y+oRect.h)
		vIsMatch := 0
		Loop, % vRecurseDepth - 1
		{
			oAcc := oAcc.accParent
			for _, oChild in Acc_Children(oAcc)
			{
				vText := ""
				oRect := Acc_Location(oChild)
				DllCall("user32\SetRect", Ptr,&RECT2, Int,oRect.x, Int,oRect.y, Int,oRect.x+oRect.w, Int,oRect.y+oRect.h)
				if !DllCall("user32\IntersectRect", Ptr,&RECT3, Ptr,&RECT1, Ptr,&RECT2)
					continue
				try vText := oChild[vType](0)
				if (vText = "")
					continue
				oAcc2 := oChild
				vIsMatch := 1
				break
			}
			if vIsMatch
				break
		}
	}
	else
		oAcc2 := oAcc
	vChildID2 := vChildID
	oAcc := oChild := ""
	return vText
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: getting a link's URL or the content of a tooltip

16 Dec 2018, 02:46

Here's a script to get the url under the cursor from Chrome. Tested with Chrome v70. Is there a better way?

Code: Select all

q:: ;chrome - get url under cursor
SendInput, {Click right}
Clipboard := ""
Sleep, 30
SendInput, e ;Copy link address
ClipWait, 3
MsgBox, % Clipboard
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: getting a link's URL or the content of a tooltip

16 Dec 2018, 09:15

It is interesting for me is it possible with acc always get info under cursor.
Your last improved function works good, but it is no so fast, therefore I think it is better to modify it like this:
And it does not work with chrome "Bookmark this page icon" - it shows wrong element, also it does not work with blank url in address bar - it shows "search icon".

Code: Select all

f1:: MsgBox % GetTextUnderMouse()

GetTextUnderMouse() {
	Acc := Acc_ObjectFromPoint(child)
	try value := Acc.accValue(child)
	if Not value
		try value := Acc.accName(child)
	if (value = "")
                    value := JEE_AccGetTextUnderCursor("v")
	if (value = "")
                    value := JEE_AccGetTextUnderCursor("n")
        return value
}
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: getting a link's URL or the content of a tooltip

17 Dec 2018, 15:06

While testing I notice that this situation is only with object pane, therefore I modify function like this:

Code: Select all

f1:: MsgBox % GetTextUnderMouse()

GetTextUnderMouse()
{
   Acc := Acc_ObjectFromPoint(child)
   try value := Acc.accValue(child)
   if Not value
      try value := Acc.accName(child)
   if (Acc.accRole(child) = 16)   ; pane
   {
      CoordMode, Mouse
      MouseGetPos, OutputVarX, OutputVarY, OutputVarWin
      loop
      {
         Acc := Acc.accParent
         if (Acc_WindowFromObject(Acc) != OutputVarWin)
            break
         try oChildren := Acc_Children(Acc)
         for _, oChild in oChildren
         {
            oCoords := Acc_Location(oChild)
            if (OutputVarX >= oCoords.x) and (OutputVarX <= oCoords.x + oCoords.w) and (OutputVarY >= oCoords.y) and (OutputVarY <= oCoords.y + oCoords.h)
            {
               try value := oChild.accValue(0)
               if Not value
                  try value := oChild.accName(0)
               try role := oChild.accRole(0)
               if (role != 16)  ; pane
                  break 2
            }
         }
      }
   }
   return value
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: jeves, mikeyww, Thorlian and 284 guests