问题
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