【问题标题】:Get active Tab URL in FireFox with C++使用 C++ 在 FireFox 中获取活动标签 URL
【发布时间】:2019-08-05 08:56:45
【问题描述】:

我正在尝试使用 UI 自动化从 Firefox 获取 URL,但一直失败。

它在 Chrome 中运行良好。但它在 Firefox 中不起作用。 我认为搜索或输入地址与 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;
}

消息框中显示一个空白值 我想获取活动标签 URL

【问题讨论】:

    标签: c++ winapi geturl


    【解决方案1】:

    上述代码的主要部分设计用于 Chrome,而不是 Firefox。

    使用Inspect 工具检查Firefox 中的控件排列。您将看到类似于以下结构的内容:

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

    我们需要带有“使用 Google 搜索”标签的控件。我们可以按名称查找元素,但这可能取决于语言,控件的顺序也可能不同,因为用户可以自定义浏览器并重新排列控件。

    相反,我们可以查找 AutomationId,在这种情况下,它在 Firefox 中可用(并非总是如此)

    “导航”显示AutomationId = "nav-bar" 属性,“编辑框”显示AutomationId = "urlbar-input" 属性

    我们可以使用UIA_AutomationIdPropertyId 来查找这些名称:

    int main()
    {
        if FAILED(CoInitialize(nullptr))
            return 0;
        struct coinit { ~coinit() { CoUninitialize(); } } cleanup;
    
        //find the first visible window in firefox
        HWND hwnd = NULL;
        while (true)
        {
            hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
            if (!hwnd)
                return 0;
            if (IsWindowVisible(hwnd))
                break;
        }
    
        //initialize UIAutomation
        CComPtr<IUIAutomation> uia;
        if FAILED(uia.CoCreateInstance(CLSID_CUIAutomation))
            return 0;
    
        CComPtr<IUIAutomationElement> root, navigation, editbox;
        CComPtr<IUIAutomationCondition> c1, c2;
    
        //find root from hwnd handle
        if FAILED(uia->ElementFromHandle(hwnd, &root))
            return 0;
    
        //find navigation bar as child of root
        uia->CreatePropertyCondition(UIA_AutomationIdPropertyId, 
            CComVariant(L"nav-bar"), &c1);
        if FAILED(root->FindFirst(TreeScope_Children, c1, &navigation))
            return 0;
    
        //find editbox under as descendant of navigation
        uia->CreatePropertyCondition(UIA_AutomationIdPropertyId, 
            CComVariant(L"urlbar-input"), &c2);
        if FAILED(navigation->FindFirst(TreeScope_Descendants, c2, &editbox))
            return 0;
    
        //get the string in editbox 
        CComVariant url;
        if FAILED(editbox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url))
            return 0;
        if(url.bstrVal)
            wprintf(L"[%s]\n", url.bstrVal);
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多