'Is it possible to get the URL of a chrome window not controlled by the selenium driver?

I would be grateful for any advice as to whether the task below is possible in VBA using the chrome Selenium driver.

The task is to automatically fill in a form in Chrome from a URL link sent by email (Outlook). The problem is that the URL changes each time, so I cannot simply insert a defined URL into my code to open with the Selenium driver. So whilst clicking on the emailed link will open the URL in chrome - it is not the driven window and so cannot be accessed by any of the Selenium functions e.g. driver.Url.

I can get the window handle and title of the non-driven (manually opened) using Windows API functions through the code below (found on stackOverflow). Is there any way I can then use this windows handle to capture the URL displayed in the non driven chrome window rather than just its title? I could then navigate to it in the driven window and continue from there.

I have a feeling that it will be some other type of API function but so far my research is turning up nothing. Is what I am trying to do even possible?

Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr

Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As LongPtr

Public Sub GetWindows()
    '~~> Pass Full Name or Partial Name. This is not case sensitive
    Debug.Print GetAllWindowHandles("Microsoft Visual Basic")
End Sub

Private Function GetAllWindowHandles(partialName As String)
    Dim hWnd As Long, lngRet As Long
    Dim strText As String

    hWnd = FindWindowEx(0&, 0&, vbNullString, vbNullString)

    While hWnd <> 0
        strText = String$(100, Chr$(0))
        lngRet = GetWindowText(hWnd, strText, 100)

        If InStr(1, strText, partialName, vbTextCompare) > 0 Then
            Debug.Print "The Handle of the window is " & hWnd & " and " & vbNewLine & _
                        "The title of the window is " & Left$(strText, lngRet) & vbNewLine & _
                        "----------------------"
        End If

        '~~> Find next window  
        hWnd = FindWindowEx(0&, hWnd, vbNullString, vbNullString)
    Wend
End Function


Solution 1:[1]

You can use UI Automation to retrieve the Edit control type's IValueProvider Control Pattern which holds the url.
The following code is based on ElementFromPoint. Here is a ElementFromHandle sample.

#include <Windows.h>
#include <UIAutomation.h>
#include <wchar.h>

int Element(IUIAutomation* automation)
{
    // Get the element under the cursor
// Use GetPhysicalCursorPos to interact properly with
// High DPI
    POINT pt;
    GetPhysicalCursorPos(&pt);

    IUIAutomationElement* pAtMouse;
    HRESULT hr = automation->ElementFromPoint(pt, &pAtMouse);
    if (FAILED(hr))
        return hr;

    // Get the element's name and print it
    BSTR name;
    hr = pAtMouse->get_CurrentName(&name);
    if (SUCCEEDED(hr))
    {
        wprintf(L"Element's Name: %s \n", name);
        SysFreeString(name);

        IUIAutomationValuePattern* pattern;
        pAtMouse->GetCurrentPatternAs(UIA_ValuePatternId, IID_IUIAutomationValuePattern,(void**)&pattern);
        //TODO
        BSTR url;
        pattern->get_CurrentValue(&url);
        wprintf(L"Element's ValuePattern: %s \n", url);
        SysFreeString(url);
    }

    // Get the element's Control Type (in the current languange)
    // and print it
    BSTR controlType;
    hr = pAtMouse->get_CurrentLocalizedControlType(&controlType);
    if (SUCCEEDED(hr))
    {
        wprintf(L"Element's Control Type: %s \n", controlType);
        SysFreeString(controlType);
    }

    // Clean up our COM pointers
    pAtMouse->Release();
    return hr;
}

int main(int argc, TCHAR* argv[])
{
    // Initialize COM and create the main Automation object
    IUIAutomation* g_pAutomation;
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
        CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation),
        (void**)&g_pAutomation);
    if (FAILED(hr))
        return (hr);

    bool quit = false;
    while (!quit)
    {
        SHORT leftControlMod = GetAsyncKeyState(VK_LCONTROL);
        if (leftControlMod != 0)
        {
            Element(g_pAutomation);
        }
        quit = GetAsyncKeyState(VK_ESCAPE);
    }

    g_pAutomation->Release();
    CoUninitialize();
    return 0;
}

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 YangXiaoPo - MSFT