Get active Tab URL in FireFox with C++

Deadly 提交于 2021-01-28 18:38:32

问题


I'm trying to get a URL from Firefox using UI Automation, but it keeps failing.

It worked fine in Chrome. but it doesn't work in Firefox. i think Search Or Enter Address is same 'Address and search bar' in Chrome

#include <Windows.h>
#include <AtlBase.h>
#include <AtlCom.h>
#include <UIAutomation.h>
#include <stdlib.h>
#define UNICODE

int main()
{
    CoInitialize(NULL);
    HWND hwnd = NULL;
    while (true)
    {
        hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
        if (!hwnd)
            break;
        if (!IsWindowVisible(hwnd))
            continue;

        CComQIPtr<IUIAutomation> uia;
        if (FAILED(uia.CoCreateInstance(CLSID_CUIAutomation)) || !uia)
            break;

        CComPtr<IUIAutomationElement> root;
        if (FAILED(uia->ElementFromHandle(hwnd, &root)) || !root)
            break;

        CComPtr<IUIAutomationCondition> condition;


        uia->CreatePropertyCondition(UIA_ControlTypePropertyId,
            CComVariant(0xC354), &condition);


        CComPtr<IUIAutomationElement> edit;
        if (FAILED(root->FindFirst(TreeScope_Descendants, condition, &edit))
            || !edit)
            continue; //maybe we don't have the right tab, continue...

        CComVariant url;
        edit->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url);
        MessageBox(0, url.bstrVal, 0, 0);
        break;
    }
    CoUninitialize();
    return 0;
}

A blank value is displayed in the message box I want to get Active tab URL


回答1:


The main section of above code is designed to work with Chrome, not Firefox.

Use the Inspect tool to examine arrangement of controls in Firefox. You will see the following structure:

Firefox window
    -> "" toobar
    -> "" toobar
    -> "Navigation Toolbar" toobar
        -> "" combobox
            -> "Search with Google" edit //<- url editbox
        -> "Search" combobox //<- we don't want this

We need the control with label "Search with Google". But this can be language dependent, also the order of the controls could be different, because the user can customized the browser and rearrange the controls.

To get around this problem, we can go through the toolbars and find the url edit control as follows:

bool firefox_geturl(HWND hwnd)
{
    CComQIPtr<IUIAutomation> uia;
    if(FAILED(uia.CoCreateInstance(CLSID_CUIAutomation)) || !uia)
        return false;

    CComPtr<IUIAutomationElement> element;
    if(FAILED(uia->ElementFromHandle(hwnd, &element)) || !element)
        return false;

    //initialize conditions
    CComPtr<IUIAutomationCondition> toolbar_cond;
    uia->CreatePropertyCondition(UIA_ControlTypePropertyId,
        CComVariant(UIA_ToolBarControlTypeId), &toolbar_cond);

    CComPtr<IUIAutomationCondition> combobox_cond;
    uia->CreatePropertyCondition(UIA_ControlTypePropertyId, 
        CComVariant(UIA_ComboBoxControlTypeId), &combobox_cond);

    CComPtr<IUIAutomationCondition> editbox_cond;
    uia->CreatePropertyCondition(UIA_ControlTypePropertyId, 
        CComVariant(UIA_EditControlTypeId), &editbox_cond);

    //find the top toolbars
    CComPtr<IUIAutomationElementArray> toolbars;
    if(FAILED(element->FindAll(TreeScope_Children, toolbar_cond, &toolbars)) || !toolbars)
        return false;

    int toolbars_count = 0;
    toolbars->get_Length(&toolbars_count);
    for(int i = 0; i < toolbars_count; i++)
    {
        CComPtr<IUIAutomationElement> toolbar;
        if(FAILED(toolbars->GetElement(i, &toolbar)) || !toolbar)
            continue;

        //find the comboxes for each toolbar
        CComPtr<IUIAutomationElementArray> comboboxes;
        if(FAILED(toolbar->FindAll(TreeScope_Children, combobox_cond, &comboboxes)) || !comboboxes)
            return false;

        int combobox_count = 0;
        comboboxes->get_Length(&combobox_count);
        for(int j = 0; j < combobox_count; j++)
        {
            CComPtr<IUIAutomationElement> combobox;
            if(FAILED(comboboxes->GetElement(j, &combobox)) || !combobox)
                continue;

            CComVariant test;
            if(FAILED(combobox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &test)))
                continue;

            //we are interested in a combobox which has no lable
            if(wcslen(test.bstrVal))
                continue;

            //find the first editbox
            CComPtr<IUIAutomationElement> edit;
            if(FAILED(combobox->FindFirst(TreeScope_Descendants, editbox_cond, &edit)) || !edit)
                continue;

            CComVariant bstr;
            if(FAILED(edit->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &bstr)))
                continue;

            MessageBoxW(0, bstr.bstrVal, L"success", 0);
            return true;
        }
    }
    return false;
}

int main()
{
    CoInitialize(NULL);
    HWND hwnd = NULL;
    while(true)
    {
        hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
        if(!hwnd)
            break;
        if(!IsWindowVisible(hwnd))
            continue;
        firefox_geturl(hwnd);
        break;
    }
    CoUninitialize();
    return 0;
}


来源:https://stackoverflow.com/questions/57355191/get-active-tab-url-in-firefox-with-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!