Get the URL of the current (active) browser tab

Post your working scripts, libraries and tools for AHK v1.1 and older
yar_man
Posts: 3
Joined: 08 Jun 2016, 10:51

Re: Get the URL of the current (active) browser tab

08 Jun 2016, 13:17

atnbueno,

Thanks so much for this code. I have it working successfully as you have implemented above (triggered by the user) but I am trying another implementation without success. I'm hoping somebody can help.

I want to use the code as a function within an expression after #if similar to the way you might use, #IfWinActive. The web window I want to work in has a changing title so it doesn't play nice with #IfWinActive.

I am close but not quite there. Here is an example you can try by adding it to your code:

Code: Select all

#If IS_SiteByURL("google")

::hh::Huzzah!

#If

IS_SiteByURL(text_in_url) {
	If (InStr(GetActiveBrowserURL(), text_in_url))
		return "1"
	else
		return
}

^!Numpad0::
{
	MsgBox, % IS_SiteByURL("google")
	return
}
The function works perfectly when fired with ^!Numpad0. Feel free to try it at on google.com. However it does not work when trying it with #if as a requisite for the hotstring "hh".

Here is a link to the output: https://www.dropbox.com/s/8ag8dae1ws8ai ... t.txt?dl=0

It looks like the significant part is " ErrorLevel := "Invalid IAccessible Object" " any time ACC tries to do its thing (FireFox or Chrome).

I think this implementation could be very useful if we can sort it out. Any Ideas?
User avatar
atnbueno
Posts: 89
Joined: 12 Oct 2013, 04:45
Contact:

Re: Get the URL of the current (active) browser tab

08 Jun 2016, 14:23

Hello yar_man.

I'm sorry but I'm not familiar with #If. But before that, your IS_google() function always returns 1 :wtf:

This one works for me (the function, not the #if):

Code: Select all

isGoogle() {
	Return InStr(GetActiveBrowserURL(), "google") > 0
}
I've tried to tweak your #if code and the 'hh' hotkey sometimes works and sometimes doesn't :crazy:

But this always works :)

Code: Select all

if_in_URL_send(fragment, text) {
	If InStr(GetActiveBrowserURL(), fragment)
		SendRaw % text
}

::hh::
	if_in_URL_send("google", "Huzza!")
Return
Regards,
Antonio B.
yar_man
Posts: 3
Joined: 08 Jun 2016, 10:51

Re: Get the URL of the current (active) browser tab

08 Jun 2016, 17:05

Antonio,

Thanks for responding. The first post had a broken function in it. Sorry about that. I realized it but couldn't delete the post so I re-posted with a corrected example function and example:

Code: Select all

#If IS_SiteByURL("google")
 
::hh::Huzzah!
 
#If
 
IS_SiteByURL(text_in_url) {
	If (InStr(GetActiveBrowserURL(), text_in_url))
		return "1"
	else
		return
}
 
^!Numpad0::
{
	MsgBox, % IS_SiteByURL("google")
	return
}
The #if directive is a condition as an alternative to making a hotkey window specific with #Ifwinactive. I have a few hundred hotkeys that perform other functions more complicated than text replacement. HH to Huzzah was just a simplified example. In my use case, the example hh hotkey does something different in a few windows. I can easily write a single example to have a few if's and perform properly. The purpose of using the #If directive instead is to have a few hundred hotkeys listed below it, that are window specific based on the url, without having the "if's" listed out in each one. (I would have to add it to a few hundred hotkeys and any time it needs editing it would be the same)

I could do that creatively and get it done quickly enough but I'm interested in solving this directive riddle because I use functions in directives a lot and I think this will be valuable regardless of application.

With your knowledge of functions, do you know why the GetActiveBrowserURL() would be able to use the ACC library successfully when triggered directly by a hotkey but not when triggered by a directive? Or, do you get a different output than I did? (I'm referring to the errors in the output I linked when ACC fails and you set errorlevel. " ErrorLevel := "Invalid IAccessible Object" ")

Thanks again for the script. I'm going to keep researching. If you think you can shed some light on the ACC error, I'm interested.

Cheers,

Stan
capeably
Posts: 47
Joined: 10 Jul 2014, 14:38

Re: Get the URL of the current (active) browser tab

10 Jun 2016, 01:58

Thanks for your work on this!

How could I adapt the script to copy both the current tab page title and url to the clipboard with a line break like this:

This is the Page Title
https://autohotkey.com

Thanks in advance!
User avatar
atnbueno
Posts: 89
Joined: 12 Oct 2013, 04:45
Contact:

Re: Get the URL of the current (active) browser tab

10 Jun 2016, 12:07

Stan, this problem reminds me the conversation with mc-lemons from last January. I'm guessing that #If calls the function too frequently, everytime there's a window event, and my code is not ready for that. The particular error you mention is typical when the code tries to access an object that doesn't exists anymore.

I'm testing a slightly more sophisticated version of the code that should be a bit more robust, but I'm afraid it's still too far from being able to process a few hundred calls per second :( I'll try to keep this case in mind, though.

capeably, it's very easy. Replace/compare this block in/to the original code:

Code: Select all

^+!u::
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	WinGetTitle, sTitle, A
	If (sURL != "")
		Clipboard := sTitle "`n" sURL "`n"
	Else If sClass In % DDE_Browsers "," ACC_Browsers
		MsgBox, % "The URL couldn't be determined (" sClass ")"
	Else
		MsgBox, % "Not a browser or browser not supported (" sClass ")"
Return
Regards,
Antonio B.
capeably
Posts: 47
Joined: 10 Jul 2014, 14:38

Re: Get the URL of the current (active) browser tab

10 Jun 2016, 13:02

Thanks so much!

I adapted the hotkey actions so that it removes "Mozilla Firefox" from the title, and I added a splash message showing the clipboard contents

Code: Select all

^+!u::
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	WinGetTitle, sTitle, A
	sTitle := RegExReplace(sTitle, "- Mozilla Firefox", "")
	SplashTextOn, 500, 100,, %sTitle% `n %sURL%
	If (sURL != "")
		Clipboard := sTitle "`n" sURL
		;SplashTextOn, 250, 50, %sTitle% `n %sURL%
	Else If sClass In % DDE_Browsers "," ACC_Browsers
		MsgBox, % "The URL couldn't be determined (" sClass ")"
	Else
		MsgBox, % "Not a browser or browser not supported (" sClass ")"
	Sleep, 2000
	SplashTextOff
Return
yar_man
Posts: 3
Joined: 08 Jun 2016, 10:51

Re: Get the URL of the current (active) browser tab

13 Jun 2016, 14:56

Antonio,

#If does not call the function over and over like a loop would. It only evaluates the expression after #If when a hotkey below that #If is called. That said, when looking at the output from testing this method, it is apparent that the ACC library features you use are not able to operate with the same authority or permissions when called as part of an #If directive vs. being called by a hotkey.

I was thinking about trying to convert a few key functions to subroutines in order to fix this but I haven't gotten to it yet. I also read something about putting certain functions inside a subroutine and using settimer as a workaround to activate them. Somehow that made a difference in how they performed. I need to research that more.

Thanks for reading. Let me know if you have any thoughts.
ToKa
Posts: 26
Joined: 23 Apr 2016, 04:37

Re: Get the URL of the current (active) browser tab

21 Jun 2016, 23:10

Thanks for the routine, works great running Chrome on Windows XP
User avatar
JoeSchmoe
Posts: 129
Joined: 08 Dec 2014, 08:58

Re: Get the URL of the current (active) browser tab

05 Jul 2016, 19:37

I just want to say that I use some code based on this code every day. It works wonderfully!
doctorMe
Posts: 8
Joined: 07 Jul 2016, 03:31

Re: Get the URL of the current (active) browser tab

13 Aug 2016, 07:24

The code is not getting the url from Internet Explorer 11 under x64 Windows 8.1 version. With x86 Windows works fine.
stealzy
Posts: 91
Joined: 01 Nov 2015, 13:43

Re: Get the URL of the current (active) browser tab

11 Sep 2016, 03:22

Acc method search control with url too long for firefox (2600 ms - GetAddressBar() is called 360! times) vs DDE (31 ms function).
For modern Opera GetAddressBar() is called 47 times.
Maybe we can to narrow the search, using AccPath?

Regex in IsURL() is overhead. Also, you can't detect "chrome://extensions" and similar.
I turn off IsURL() completely, and still have no mistake in Firefox 47 (ofcourse, using acc method) and Opera 39. Did you have any mistakes?

Not work with Edge 10.10240 on Windows 10x32.
For Edge in my case sometimes works this code:

Code: Select all

#SingleInstance force
sClass := "ApplicationFrameWindow", AccPath := "4.2.4.10", Item := "Name"
; sClass := "Chrome_WidgetWin_1", AccPath := "4.1.2.1.1.5.1.3", Item := "Value"
; sClass := "MozillaWindowClass", AccPath := "4.55.8.2", Item := "Value"
x := Acc_Get(Item, AccPath,, "ahk_class" sClass)
MsgBox % x
Return

Acc_Init() {
	Static h
	If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
	Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
	{
		Acc_Init()
		If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
		Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
	}

	Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
	{
		Acc_Init()
		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 = -4)
	{
		Acc_Init()
		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_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_GetStateText(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_SetWinEventHook(eventMin, eventMax, pCallback)
	{
		Return	DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
	}

	Acc_UnhookWinEvent(hHook)
	{
		Return	DllCall("UnhookWinEvent", "Ptr", hHook)
	}

	; Written by jethrow
	Acc_Role(Acc, ChildId=0) {
		try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
	}
	Acc_State(Acc, ChildId=0) {
		try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
	}
	Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
		try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
		catch
			return
		Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
		return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
	}
	Acc_Parent(Acc) {
		try parent:=Acc.accParent
		return parent?Acc_Query(parent):
	}
	Acc_Child(Acc, ChildId=0) {
		try child:=Acc.accChild(ChildId)
		return child?Acc_Query(child):
	}
	Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
		try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
	}
	Acc_Error(p="") {
		static setting:=0
		return p=""?setting:setting:=p
	}
	Acc_Children(Acc) {
		if ComObjType(Acc,"Name") != "IAccessible"
			ErrorLevel := "Invalid IAccessible Object"
		else {
			Acc_Init(), 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:
			} else
				ErrorLevel := "AccessibleChildren DllCall Failed"
		}
		if Acc_Error()
			throw Exception(ErrorLevel,-1)
	}
	Acc_ChildrenByRole(Acc, Role) {
		if ComObjType(Acc,"Name")!="IAccessible"
			ErrorLevel := "Invalid IAccessible Object"
		else {
			Acc_Init(), 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(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)
	}
Also I modify your code to get tooltip with url acc path. Opera 39 - 4.1.2.1.1.5.1.3, Firefox 47 - 4.55.8.2.
What path do you have?
Maybe we should search from the end of this path, based on this information? Try search 4.1.2.1.1.5.1.x; if not, then try search 4.1.2.1.1.5.x; 4.1.2.1.1.x; 4.1.2.1.x; 4.1.2.x; 4.1.x; 4.x.

Code: Select all

#SingleInstance force
Esc::ExitApp
#x::
	nTime := A_TickCount
	WinGetClass, sClass, A
	URL := GetBrowserURL(sClass)
	MsgBox, % "The URL is """ URL """`nEllapsed time: " (A_TickCount - nTime) " ms (" sClass ")"
Return


GetBrowserURL(sClass) {
	Static AccBrowsersClass := "MozillaWindowClass,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,Slimjet_WidgetWin_1"
	Static DDEBrowsersClass := "MozillaWindowClass,IEFrame,OperaWindowClass"
	If sClass In % AccBrowsersClass
		Return GetBrowserURL_ACC(sClass)
	Else If sClass In % DDEBrowsersClass
		Return GetBrowserURL_DDE(sClass)
}
GetBrowserURL_DDE(sClass) {
	WinGet, sServer, ProcessName, % "ahk_class " sClass
	StringTrimRight, sServer, sServer, 4
	iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
	DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
	hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
	hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
	hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
	hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
	hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
	sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
	DllCall("DdeUnaccessData", "UPtr", hData)
	DllCall("DdeFreeDataHandle", "UPtr", hData)
	DllCall("DdeDisconnect", "UPtr", hConv)
	DllCall("DdeUninitialize", "UPtr", idInst)
	csvWindowInfo := StrGet(&sData, "CP0")
	StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
	Return sWindowInfo2
}
GetBrowserURL_ACC(sClass) {
	static nWindow, accAddressBar
	If (nWindow != WinExist("ahk_class " sClass)) ; reuses accAddressBar if it's the same window
	{
		nWindow := WinExist("ahk_class " sClass)
		accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindow))
	}
	Try sURL := accAddressBar.accValue(0)
	If (sURL == "") {
		WinGet, nWindows, List, % "ahk_class " sClass ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
		If (nWindows > 1) {
			accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindows2))
			Try sURL := accAddressBar.accValue(0)
		}
	}
	If (sURL == "")
		nWindow := -1 ; Don't remember the window if there is no URL
	Return sURL
}
GetAddressBar(accObj, accPath:="") {
	; static a:=0
	; ToolTip % a++ ; 360 for firefox, 47 for modern Opera
	n := 0
	Try If ((accObj.accRole(0) == 42) and accObj.accValue(0))
		Return accObj
	For nChild, accChild in Acc_Children(accObj) {
		n++
		currentPath := accPath n "."
		ToolTip % currentPath
		If IsObject(accAddressBar := GetAddressBar(accChild, currentPath)) {
			Return accAddressBar
		}
	}
}
~LButton::ToolTip

Acc_Init() {
	static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0) {
	Acc_Init()
	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_Query(Acc) {
	Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Children(Acc) {
	If ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	Else {
		Acc_Init(), 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:
		} Else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
}
Last edited by stealzy on 11 Sep 2016, 07:44, edited 5 times in total.
stealzy
Posts: 91
Joined: 01 Nov 2015, 13:43

Re: Get the URL of the current (active) browser tab

11 Sep 2016, 07:23

Common wishes: don't use global variables; remove from function WinGetClass, sClass, A - this generate questions like: "how get url in not active browser window".
iseahound
Posts: 1427
Joined: 13 Aug 2016, 21:04
Contact:

Re: Get the URL of the current (active) browser tab

11 Sep 2016, 13:30

I'm enjoying this script so far. Two points though:

1) Could you explain how the speed-up works? Is it being loaded into memory?

2) It's not working with ftp://

Code: Select all

; ACTUAL:   ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt
; RESULT    http://ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt
	If ((sURL != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
		sURL := "http://" sURL
Fix:

Code: Select all

	If ((sURL != "") and !(sURL ~= "^(http|ftp)")) ; Modern browsers omit "http:// BUT TEND TO USE HTTPS ANYWAYS
		sURL := "http://" sURL
"
stealzy wrote:Common wishes: don't use global variables; remove from function WinGetClass, sClass, A - this generate questions like: "how get url in not active browser window".
Just make them static.

Code: Select all

GetActiveBrowserURL() {
	static ModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,MozillaWindowClass,Slimjet_WidgetWin_1"
	static LegacyBrowsers := "IEFrame,OperaWindowClass"
	WinGetClass, sClass, A
	If sClass In % ModernBrowsers
		Return GetBrowserURL_ACC(sClass)
	Else If sClass In % LegacyBrowsers
		Return GetBrowserURL_DDE(sClass) ; empty string if DDE not supported (or not a browser)
	Else
		Return ""
}
stealzy
Posts: 91
Joined: 01 Nov 2015, 13:43

Re: Get the URL of the current (active) browser tab

12 Sep 2016, 00:40

iseahound, thank you, captain obvious!
In my second sample of code you can see static variables and other changes. I wrote this not for me, but for TC.
1) If you run my second code, you can understand, how speed-up works. It search for URL among all Acc controls, then save id of url control in static var accAddressBar.
----
* ThunderBird has the same class "MozillaWindowClass", so if it run at the same time with firefox, script sometimes fails.
iseahound
Posts: 1427
Joined: 13 Aug 2016, 21:04
Contact:

Re: Get the URL of the current (active) browser tab

12 Sep 2016, 10:55

It's tedious for me to mentally diff your code as I am not the author. It'd be much easier if you highlighted/cut-out the changes you made to the original code. Or even added comments. Still it was my mistake, I didn't realize you had implemented those changes already.
Danny

Re: Get the URL of the current (active) browser tab

16 Nov 2016, 17:16

Hello Antonio Bueno! Your script no longer works with Firefox as of release version 50 on Nov, 15, 2016.
Your script is wonderful, and I hope you can fix it for the new release. Thank you!
Johnny R
Posts: 348
Joined: 03 Oct 2013, 02:07

Re: Get the URL of the current (active) browser tab

16 Nov 2016, 20:05

@Danny, I don't have a problem with the new version 50. Antonio Bueno's script works.
Danny

Re: Get the URL of the current (active) browser tab

16 Nov 2016, 21:13

Hi Johnny R. Thank you for that information. Maybe it is because I am using Windows Vista.
I made a simple replacement that works fine for my purposes:

Code: Select all

		WinActivate, ahk_class MozillaWindowClass
		WinWaitActive, ahk_class MozillaWindowClass
		Send, ^l
		Sleep, 80
		Clipboard =
		Send, ^c
		ClipWait, 1
		sURL = %Clipboard%
		Clipboard =
Danny

Re: Get the URL of the current (active) browser tab

17 Nov 2016, 03:24

If anyone had this script fail with the Firefox version 50 release, here was my solution:
Just put Mozilla with the Legacy Browsers, so it uses DDE instead of ACC.

Code: Select all

ModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,Slimjet_WidgetWin_1"
LegacyBrowsers := "IEFrame,MozillaWindowClass,OperaWindowClass"
drdutw
Posts: 5
Joined: 23 Oct 2013, 12:20

Re: Get the URL of the current (active) browser tab

06 Dec 2016, 00:22

Thank you so much! I've been waiting for this for the last 8.5 years.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 69 guests