Get the URL of the current (active) browser tab

Post your working scripts, libraries and tools for AHK v1.1 and older
newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 27 Jun 2023, 00:03

Descolada wrote:
26 Jun 2023, 23:13
@newcod3r, in the chrome://accessibility/ site try checking "Screen reader support". Also make sure that when you run the GetURL function that the Chrome browser is at least partially visible - otherwise UIA methods won't work. Also, what is the ErrorLevel after the function? Try running this and output the result:

Code: Select all

WinActivate, % "ahk_exe chrome.exe"
WinWaitActive, % "ahk_exe chrome.exe",, 1
MsgBox % GetUrl("ahk_exe chrome.exe") "`nErrorLevel: " ErrorLevel 

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", cHwnd, "ptr*", documentEl)   ; IUIAutomation::ElementFromHandle
	DllCall(NumGet(NumGet(documentEl+0)+10*A_PtrSize),"ptr",documentEl,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(documentEl)
	ObjRelease(IUIAutomation)
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}
have enabled screen reader support too - no dice..
image.png
image.png (8.74 KiB) Viewed 2553 times

Descolada
Posts: 1169
Joined: 23 Dec 2021, 02:30

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

Post by Descolada » 27 Jun 2023, 00:23

@newcod3r, but I see the messagebox you posted shows the URL of the page? What are you expecting to see?

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 27 Jun 2023, 00:41

Descolada wrote:
27 Jun 2023, 00:23
@newcod3r, but I see the messagebox you posted shows the URL of the page? What are you expecting to see?
Sometimes I need to trigger it multiple times in order for the URL to be captured, even though there's already Winactivate at the start.. not sure why?
image.png
image.png (10.85 KiB) Viewed 2533 times
I used it like this previously and it worked, but not sure why it stopped executing based on what URL I'm on:

Code: Select all

url := GetUrl("ahk_exe chrome.exe") ; ChatGPT Commands
If InStr(url, "chat.openai.com") {
::rew::Rewrite this in the style of
}
If InStr(url, "instagram.com") {
:X:z::SendInput n
}
return

User avatar
xMaxrayx
Posts: 202
Joined: 06 Dec 2022, 02:56
Contact:

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

Post by xMaxrayx » 27 Jun 2023, 01:50

@newcod3r

use "web address in title" addon
-----------------------ヾ(•ω•`)o------------------------------
https://github.com/xmaxrayx/

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 27 Jun 2023, 08:51

sorry I don't understand what you mean?

Descolada
Posts: 1169
Joined: 23 Dec 2021, 02:30

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

Post by Descolada » 28 Jun 2023, 10:09

@newcod3r, I don't understand how the example code you provided could ever have worked as you intended, because as far as I know you can't use hotstrings inside normal if-else statements.

I tested with this and it worked fine (only in Chrome of course):

Code: Select all

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", cHwnd, "ptr*", documentEl)   ; IUIAutomation::ElementFromHandle
	DllCall(NumGet(NumGet(documentEl+0)+10*A_PtrSize),"ptr",documentEl,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(documentEl)
	ObjRelease(IUIAutomation)
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}

IsPageActive(url, wTitle:="ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(wTitle)
        return 0
    WinGetTitle, currentTitle, %wTitle%
    if (!lastTitle || currentTitle != lastTitle) {
        currentUrl := GetUrl(wTitle)
        lastUrl := currentUrl, lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

#If IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#If IsPageActive("instagram.com")
::sth::Something else

deets
Posts: 43
Joined: 29 Mar 2022, 02:00

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

Post by deets » 28 Jun 2023, 18:17

Descolada wrote:
28 Jun 2023, 10:09
@newcod3r, I don't understand how the example code you provided could ever have worked as you intended, because as far as I know you can't use hotstrings inside normal if-else statements.

I tested with this and it worked fine (only in Chrome of course):

Code: Select all

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", cHwnd, "ptr*", documentEl)   ; IUIAutomation::ElementFromHandle
	DllCall(NumGet(NumGet(documentEl+0)+10*A_PtrSize),"ptr",documentEl,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(documentEl)
	ObjRelease(IUIAutomation)
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}

IsPageActive(url, wTitle:="ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(wTitle)
        return 0
    WinGetTitle, currentTitle, %wTitle%
    if (!lastTitle || currentTitle != lastTitle) {
        currentUrl := GetUrl(wTitle)
        lastUrl := currentUrl, lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

#If IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#If IsPageActive("instagram.com")
::sth::Something else
I also don't understand - my code worked for a long time until recently. Have been using this method for domain specific actions:

Code: Select all

^s:: ; Domain Specific Actions
	url := GetURL()
	if ( InStr(url, "autohotkey.com") || InStr(url, "outlook") )
		ChromeClick("Submit")
		return
I rewrote my script based on your code above and now it works. Thank you so much!

deets
Posts: 43
Joined: 29 Mar 2022, 02:00

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

Post by deets » 14 Jul 2023, 20:24

Descolada wrote:
28 Jun 2023, 10:09
@newcod3r, I don't understand how the example code you provided could ever have worked as you intended, because as far as I know you can't use hotstrings inside normal if-else statements.

I tested with this and it worked fine (only in Chrome of course):

Code: Select all

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", cHwnd, "ptr*", documentEl)   ; IUIAutomation::ElementFromHandle
	DllCall(NumGet(NumGet(documentEl+0)+10*A_PtrSize),"ptr",documentEl,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(documentEl)
	ObjRelease(IUIAutomation)
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}

IsPageActive(url, wTitle:="ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(wTitle)
        return 0
    WinGetTitle, currentTitle, %wTitle%
    if (!lastTitle || currentTitle != lastTitle) {
        currentUrl := GetUrl(wTitle)
        lastUrl := currentUrl, lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

#If IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#If IsPageActive("instagram.com")
::sth::Something else
Hi there,

I used this code for awhile now, and realized it only works intermittently. able to advise why? Thank you so much.

Descolada
Posts: 1169
Joined: 23 Dec 2021, 02:30

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

Post by Descolada » 16 Jul 2023, 08:08

@deets, it seems for some reason sometimes Chrome "forgets" it's content control and it goes blank. I rewrote the function to find the Document element instead, which seems to be more reliable. Also I added logic to clear the hotstring matching when Ctrl+A is followed by a backspace.

Code: Select all

global HostringAllSelected := 0

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", wId, "ptr*", winElement)   ; IUIAutomation::ElementFromHandle
    VarSetCapacity(value, 8 + 2 * A_PtrSize, 0)
    NumPut(3, value, 0, "UShort")
    NumPut(50030, value, 8, "Ptr")
    if (A_PtrSize = 8) {
        DllCall(NumGet(NumGet(IUIAutomation + 0) + 23 * A_PtrSize), "Ptr", IUIAutomation, "UInt", 30003, "Ptr", &value, "Ptr*", documentCondition)
    } else {
        DllCall(NumGet(NumGet(IUIAutomation + 0) + 23 * A_PtrSize), "Ptr", IUIAutomation, "UInt", 30003, "UInt64", NumGet(value, 0, "UInt64"), "UInt64", NumGet(value, 8, "UInt64"), "Ptr*", documentCondition)
    }
    DllCall(NumGet(NumGet(winElement + 0) + 5 * A_PtrSize), "Ptr", winElement, "UInt", 4, "Ptr", documentCondition, "Ptr*", documentElement)
	DllCall(NumGet(NumGet(documentElement+0)+10*A_PtrSize),"ptr",documentElement,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    ObjRelease(documentCondition)
    ObjRelease(documentElement)
	ObjRelease(IUIAutomation)
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}

IsPageActive(url, wTitle:="ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(wTitle)
        return 0
    WinGetTitle, currentTitle, %wTitle%
    if (!lastTitle || currentTitle != lastTitle) {
        lastUrl := GetUrl(wTitle), lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

~^a::
    HostringAllSelected := 1
    return
~Left::
~Right::
~Up::
~Down::
~Tab::
~LButton::
    HostringAllSelected := 0
    return
~Backspace::
    if (HostringAllSelected)
        Hotstring("Reset")
    return
~^v::Hotstring("Reset")

#If IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#If IsPageActive("instagram.com")
::sth::Something else
Though at this point you might prefer to use one of anonymous1184 GetUrl functions instead :)

User avatar
JoeSchmoe
Posts: 129
Joined: 08 Dec 2014, 08:58

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

Post by JoeSchmoe » 24 Jul 2023, 21:36

DataLife wrote:
15 Jun 2023, 20:53
Did you find a solution for this? I also have this issue.
I'm afraid this was a while ago and I don't remember the error. The bottom line is that I learned the code well enough to customize it heavily and now it works 99% of the time. I have it ignore the other 1%. Perhaps I could fix that 1%, but I don't mind it enough to do so. I've been running it like this ever since that post.

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 16 Aug 2023, 23:37

Descolada wrote:
16 Jul 2023, 08:08
@deets, it seems for some reason sometimes Chrome "forgets" it's content control and it goes blank. I rewrote the function to find the Document element instead, which seems to be more reliable. Also I added logic to clear the hotstring matching when Ctrl+A is followed by a backspace.

Code: Select all

global HostringAllSelected := 0

GetUrl(wTitle:="ahk_exe chrome.exe") {
	ErrorLevel := 0
	if !(wId := WinExist(wTitle)) {
		ErrorLevel := 1
		return
	}
    try ControlGet, cHwnd, Hwnd,, Chrome_RenderWidgetHostHWND1, ahk_id %wId%
    if !cHwnd {
		ErrorLevel := 2
		return
    }
    SendMessage, WM_GETOBJECT := 0x003D, 0, 1, , ahk_id %cHwnd%
	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", wId, "ptr*", winElement)   ; IUIAutomation::ElementFromHandle
    VarSetCapacity(value, 8 + 2 * A_PtrSize, 0)
    NumPut(3, value, 0, "UShort")
    NumPut(50030, value, 8, "Ptr")
    if (A_PtrSize = 8) {
        DllCall(NumGet(NumGet(IUIAutomation + 0) + 23 * A_PtrSize), "Ptr", IUIAutomation, "UInt", 30003, "Ptr", &value, "Ptr*", documentCondition)
    } else {
        DllCall(NumGet(NumGet(IUIAutomation + 0) + 23 * A_PtrSize), "Ptr", IUIAutomation, "UInt", 30003, "UInt64", NumGet(value, 0, "UInt64"), "UInt64", NumGet(value, 8, "UInt64"), "Ptr*", documentCondition)
    }
    DllCall(NumGet(NumGet(winElement + 0) + 5 * A_PtrSize), "Ptr", winElement, "UInt", 4, "Ptr", documentCondition, "Ptr*", documentElement)
	DllCall(NumGet(NumGet(documentElement+0)+10*A_PtrSize),"ptr",documentElement,"uint",30045,"ptr",(VarSetCapacity(currentURL,8+2*A_PtrSize)+NumPut(0,currentURL,0,"short")+NumPut(0,currentURL,8,"ptr"))*0+&currentURL) ;IUIAutomationElement::GetCurrentPropertyValue
    sUrl := StrGet(NumGet(currentURL,8,"ptr"),"utf-16")
    ObjRelease(documentCondition)
    ObjRelease(documentElement)
	ObjRelease(IUIAutomation)
    DllCall("oleaut32\SysFreeString", "ptr", currentURL)
    If !sUrl { ;empty
        ErrorLevel := 3
        return
    }
	return sUrl
}

IsPageActive(url, wTitle:="ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(wTitle)
        return 0
    WinGetTitle, currentTitle, %wTitle%
    if (!lastTitle || currentTitle != lastTitle) {
        lastUrl := GetUrl(wTitle), lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

~^a::
    HostringAllSelected := 1
    return
~Left::
~Right::
~Up::
~Down::
~Tab::
~LButton::
    HostringAllSelected := 0
    return
~Backspace::
    if (HostringAllSelected)
        Hotstring("Reset")
    return
~^v::Hotstring("Reset")

#If IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#If IsPageActive("instagram.com")
::sth::Something else
Though at this point you might prefer to use one of anonymous1184 GetUrl functions instead :)
I tried this code a few weeks ago and now it doesn't return the URL as expected. Any advice please? Thank you.

Descolada
Posts: 1169
Joined: 23 Dec 2021, 02:30

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

Post by Descolada » 17 Aug 2023, 00:22

@newcod3r, yeah I've had the same problem and I'm not exactly sure what they've changed. I think it's the same problem as before: for some reason sometimes Chrome "forgets" it's content control. Before it automatically "woke up" when the window was activated/focused, but now it appears to require ControlFocus, Chrome_RenderWidgetHostHWND1, % "ahk_exe chrome.exe". After using that line even once, it seems to fix the problem for a while.

If you don't have a problem with Chrome being activated every time, you could add the line ControlFocus, Chrome_RenderWidgetHostHWND1, % wTitle as the first line of GetUrl. Or perhaps use a helper function such as

Code: Select all

GetUrlActivate(wTitle) {
    result := GetUrl(wTitle)
    if !result
        ControlFocus, Chrome_RenderWidgetHostHWND1, % wTitle
    return GetUrl(wTitle)
}

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 29 Oct 2023, 17:18

Descolada wrote:
17 Aug 2023, 00:22
@newcod3r, yeah I've had the same problem and I'm not exactly sure what they've changed. I think it's the same problem as before: for some reason sometimes Chrome "forgets" it's content control. Before it automatically "woke up" when the window was activated/focused, but now it appears to require ControlFocus, Chrome_RenderWidgetHostHWND1, % "ahk_exe chrome.exe". After using that line even once, it seems to fix the problem for a while.

If you don't have a problem with Chrome being activated every time, you could add the line ControlFocus, Chrome_RenderWidgetHostHWND1, % wTitle as the first line of GetUrl. Or perhaps use a helper function such as

Code: Select all

GetUrlActivate(wTitle) {
    result := GetUrl(wTitle)
    if !result
        ControlFocus, Chrome_RenderWidgetHostHWND1, % wTitle
    return GetUrl(wTitle)
}
ah it seems to be broken again recently.. any advice? 😔

Descolada
Posts: 1169
Joined: 23 Dec 2021, 02:30

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

Post by Descolada » 30 Oct 2023, 00:46

@newcod3r, apparently now the title "ahk_exe chrome.exe" sometimes matches some kind of empty-titled window which gives an incorrect UIAutomation element. After changing all instances of "ahk_exe chrome.exe" to "Google Chrome ahk_exe chrome.exe" and using SetTitleMatchMode 2 it appeared to start working again.


I've also written a method for AHK v2 using the UIA-v2 library if anyone is interested. Also gets the Chrome URL if Chrome window isn't active or is behind other windows.

Code: Select all

#include UIA.ahk

global HotstringAllSelected := 0

~^a::global HotstringAllSelected := 1
~Left::
~Right::
~Up::
~Down::
~Tab::
~LButton::global HotstringAllSelected := 0
~Backspace::
{
    if (HotstringAllSelected)
        Hotstring("Reset")
}
~^v::Hotstring("Reset")

#HotIf IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of

#HotIf IsPageActive("instagram.com")
::sth::Something else



IsPageActive(url, WinTitle:="Google Chrome ahk_exe chrome.exe") {
    static lastTitle := "", lastUrl := ""
    if !WinActive(WinTitle)
        return 0
    currentTitle := WinGetTitle(WinTitle)
    if (!lastTitle || currentTitle != lastTitle) {
        lastUrl := ChromeGetURL(WinTitle), lastTitle := currentTitle
    }
    if (lastUrl == "")
        return 0
    return InStr(lastUrl, url)
}

ChromeGetURL(WinTitle := "Google Chrome ahk_exe chrome.exe") {
    static cache := Map()
    if !(hWnd := WinExist(WinTitle))
        throw TargetError("No matching Chrome window found", -1)
    if !(chWnd := ActivateChromiumAccessibility(WinTitle))
        throw TargetError("Unable to find Chrome content element!", -1)  

    if !cache.Has(chWnd) {
        try cache[chWnd] := UIA.ElementFromHandle(chWnd)
        catch
            throw TargetError("Failed to get the document element", -1)

        for k in [cache*]
            if !WinExist(k)
                cache.Delete(k)
    }

    try return cache[chWnd].Value
}

ActivateChromiumAccessibility(WinTitle := "Google Chrome ahk_exe chrome.exe") {
    static SWP_NOREDRAW := 0x0008, SWP_NOSIZE := 0x0001, SWP_NOMOVE := 0x0002, SWP_NOACTIVATE := 0x0010
    hWnd := IsInteger(WinTitle) ? WinTitle : WinExist(WinTitle)
    if !IsWindowVisible() || !(cHwnd := TryGetChromiumHwnd()) {
        list := WinGetList(), index := 0
        for i, win in list
            if win = hWnd {
                index := i
                break
            }

        active := WinExist("A")
        tp := WinGetTransparent(hWnd)
        prevDelay := A_WinDelay
        SetWinDelay -1
        WinSetTransparent(0, hWnd)
        ; Bring to front
        DllCall("SetWindowPos", "ptr", hWnd, "ptr", 0, "int", 0, "int", 0, "int", 0, "int", 0, "int", SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW)
        WinActivate(hWnd)
        WinActivate(active)
        end := A_TickCount + 100
        while (A_TickCount < end && !(cHwnd := TryGetChromiumHwnd()))
            Sleep -1
        if index > 1
            DllCall("SetWindowPos", "ptr", hWnd, "ptr", list[index-1], "int", 0, "int", 0, "int", 0, "int", 0, "int", SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE)
        WinSetTransparent(tp, hWnd)
        SetWinDelay prevDelay
    }
    return chWnd

    TryGetChromiumHwnd() {
        try return ControlGetHwnd("Chrome_RenderWidgetHostHWND1", hWnd)
        return 0
    }

    IsWindowVisible() {
        WinGetPosEx(hWnd, &x, &y, &w, &h)
        l := Max(0, x), t := Max(0, y), r := Min(x+w-1, A_ScreenWidth), b := Min(y+h-1, A_ScreenHeight)
        if !(hWnd = UIA.WindowFromPoint(l, t) || hWnd = UIA.WindowFromPoint(r, t) || hWnd = UIA.WindowFromPoint(l, b) || hWnd = UIA.WindowFromPoint(r, b))
            return 0
        return 1
    }

    ; https://www.autohotkey.com/boards/viewtopic.php?t=114183&p=508461
    WinGetPosEx(hWindow, &X := "", &Y := "", &W := "", &H := "") {
        static S_OK := 0x0, DWMWA_EXTENDED_FRAME_BOUNDS := 9
        RECTPlus := Buffer(24,0)
        try {
            DWMRC := DllCall("dwmapi\DwmGetWindowAttribute",
                                "Ptr",  hWindow,                     ;-- hwnd
                                "UInt", DWMWA_EXTENDED_FRAME_BOUNDS, ;-- dwAttribute
                                "Ptr",  RECTPlus,                    ;-- pvAttribute
                                "UInt", 16,                          ;-- cbAttribute
                                "UInt")
        } catch
        return False

        X := NumGet(RECTPlus,  0, "Int"), Y := NumGet(RECTPlus,  4, "Int")
        , R := NumGet(RECTPlus,  8, "Int"), B := NumGet(RECTPlus, 12, "Int")
        , W := R - X, H := B - Y
    }
}

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 30 Oct 2023, 01:49

hmm I updated the window title to "Google Chrome ahk_exe chrome.exe" but it's still not working. I'm on v1 by the way.

User avatar
boiler
Posts: 17192
Joined: 21 Dec 2014, 02:44

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

Post by boiler » 30 Oct 2023, 04:19

@newcod3r — Did you do this part?
Descolada wrote: and using SetTitleMatchMode 2

newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

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

Post by newcod3r » 04 Nov 2023, 21:18

yes I did.

Kudos
Posts: 8
Joined: 23 Aug 2015, 05:52

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

Post by Kudos » 14 May 2024, 14:00

Greetings Antonio! Do you know how to make it work on Arc browser? (arc.net)

Thank you! :)

Post Reply

Return to “Scripts and Functions (v1)”