C++ 使用UI自动化通过C++;导致使用Firefox的用户延迟
我们已经创建了一个程序来监控Firefox浏览器的域/url信息,所以每隔几秒钟 此程序将使用UI自动化获取浏览器地址栏信息(类似于此处 ).这是什么时候 如果发生这种情况,则当用户尝试与 Firefox,例如在控件字段中键入字符,在选项卡之间切换(如果有多个选项卡 打开),等等。使用任务管理器资源监视器,我可以看到CPU使用率持续的“平台峰值” 当UI自动化“触发”(尝试获取URL信息)时。所以我的问题是:这会减速吗 性能下降可能是由于UI自动化在浏览器中迭代造成的 页面,或者是否与网页交互(由用户进行)和UI自动化存在某种冲突 (在监视器程序中运行)C++ 使用UI自动化通过C++;导致使用Firefox的用户延迟,c++,firefox,ui-automation,C++,Firefox,Ui Automation,我们已经创建了一个程序来监控Firefox浏览器的域/url信息,所以每隔几秒钟 此程序将使用UI自动化获取浏览器地址栏信息(类似于此处 ).这是什么时候 如果发生这种情况,则当用户尝试与 Firefox,例如在控件字段中键入字符,在选项卡之间切换(如果有多个选项卡 打开),等等。使用任务管理器资源监视器,我可以看到CPU使用率持续的“平台峰值” 当UI自动化“触发”(尝试获取URL信息)时。所以我的问题是:这会减速吗 性能下降可能是由于UI自动化在浏览器中迭代造成的 页面,或者是否与网页交互(
用户界面自动代码示例:
QString firefoxqstr=“使用谷歌搜索或输入地址”;
if(title.contains(“mozilla firefox”,Qt::Case不敏感))
{
addressBarIdentifier=(wchar_t*)firefoxqstr.utf16();
//addressBarIdentifier=(LPWSTR)(L“使用谷歌搜索或输入地址”);
getBrowserDomain(3,topWindow,addressBarIdentifier,title,domain,errqstr);
}
void getBrowserDomain(int-xtrytype、HWND-topWindow、LPWSTR-addressBarIdentifier、QString-title、QString-domain、QString-errqstr)
{
errqstr=“blank”;
//这是一个非IE浏览器。使用addressBarIdentifier获取URL
//主自动化接口
IUIAutomation*uiauto;
//分配给UIAutomation的初始值
uiauto=NULL;
//初始化COM功能
//我的方法使用UI自动化
共初始化(空);
HRESULT hr=
CoCreateInstance(uuuIdof(CUIAutomation),
无效的
CLSCTX_INPROC_服务器,
__uuidof(IUIAutomation),
(void**)和uiauto);
//通常情况下,这不应该发生,只是以防万一
如果(失败(小时))
{
errqstr=“ERROR UIAutomation init failed”;
qWarning()释放();
coninitialize();
返回;
}
//将句柄转换为UIAutomation元素以访问地址栏。
IUIAutomationElement*windElem;
hr=uiauto->ElementFromHandle(顶部窗口和windElem);
如果(失败(小时))
{
errqstr=“ERROR无法访问焦点窗口”;
qWarning()释放();
uiauto->Release();
coninitialize();
返回;
}
变异idVar;
IUIAutomationCondition*cond;
IUIAutomationCondition*条件1;
IUIAutomationCondition*condit2;
//首先,我们将标识符存储在变量中
//这是查找地址栏组件所必需的
//创建访问地址栏的条件
if(xtrytype==3)//SearchFireFoxCase
{
idVar.vt=vt_I4;
idVar.lVal=UIA_EditControlTypeId;
//创建条件以确保它是我们讨论的编辑框(特别是firefox)
hr=uiauto->CreatePropertyCondition(UIA\u ControlTypePropertyId,
idVar,
&康德);
//找到最上面的编辑框
CComPtr编辑框;
//if(失败(windElem->FindAll(TreeScope_子对象、cond和editboxs))| |!editboxs)
if(失败(windElem->FindAll(TreeScope_子体、cond和editboxs))| |!editboxs)//使用子体而不是子体
返回;
int editboxs_count=0;
编辑框->获取长度(&editboxs\u计数);
domain=QString::number(编辑框\u计数);
对于(int-icnt=0;icntGetElement(icnt,&editbox))| |!editbox)
继续;
变异urlVar;
if(失败(editbox->GetCurrentPropertyValue(UIA\u valuePropertyId,&urlVar)))
{
继续;
}
其他的
{
//将URL从BSTR转换为QString
domain=QString::fromStdWString(std::wstring(
urlVar.bstrVal,SysStringLen(urlVar.bstrVal));
icnt=editboxs\u count;//为循环终止
}
}
//清理
cond->Release();
windElem->Release();
uiauto->Release();//UIAutomation的清理代码
coninitialize();//取消初始化COM
返回;
}
}如果地址栏字符串匹配失败(即“使用谷歌搜索或输入地址”),则HTML中控件的继续搜索可能会很长(取决于网页)。因此,解决方案是在多次迭代后放弃UI自动化搜索,因为地址栏编辑框应该在搜索的早期。在本例中,Firefox使用的是Bing搜索引擎,而不是Google,因此要匹配的正确地址栏字符串应该是“使用Bing搜索或输入地址”您提到的与基本示例“类似”。与此相比,您改变了什么。最好是提供一个which.Added代码部分
Example UI Auto code:
QString firefoxqstr = "Search with Google or enter address";
if(title.contains("mozilla firefox", Qt::CaseInsensitive))
{
addressBarIdentifier = (wchar_t*)firefoxqstr.utf16();
//addressBarIdentifier = (LPWSTR)(L"Search with Google or enter address");
getBrowserDomain(3,topWindow, addressBarIdentifier, title, domain, errqstr);
}
void getBrowserDomain(int xtrytype, HWND topWindow, LPWSTR addressBarIdentifier, QString title, QString& domain, QString& errqstr)
{
errqstr = "blank";
// It's a Non IE browser. Get the URL using addressBarIdentifier
// main UIAutomation interface
IUIAutomation *uiauto;
// initial value assigned to UIAutomation
uiauto = NULL;
// Initialing COM functionality
// My approach uses UI Automation
CoInitialize(NULL);
HRESULT hr =
CoCreateInstance(__uuidof(CUIAutomation),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation),
(void**)&uiauto);
// Normally, this shouldn't happen but just in case
if(FAILED(hr))
{
errqstr = "ERROR UIAutomation init failed";
qWarning() << "Get Window Domain: Cannot initialize UIAutomation.";
if (uiauto != NULL) uiauto->Release();
CoUninitialize();
return;
}
// Convert handle to UIAutomation Element to access address bar.
IUIAutomationElement *windElem;
hr = uiauto->ElementFromHandle(topWindow, &windElem);
if(FAILED(hr))
{
errqstr = "ERROR Cannot access Window in focus";
qWarning() << "Get Window Domain: Cannot access Window in focus.";
if (windElem != NULL) windElem->Release();
uiauto->Release();
CoUninitialize();
return;
}
VARIANT idVar;
IUIAutomationCondition *cond;
IUIAutomationCondition *cond1;
IUIAutomationCondition *cond2;
// First we store identifier in a VARIANT
// This is required for finding the Address Bar Component
// Create condition to access Address Bar
if (xtrytype == 3) //SearchFireFoxCase
{
idVar.vt = VT_I4;
idVar.lVal = UIA_EditControlTypeId;
// Create condition to make sure it's an edit box we're talking about (specially with firefox)
hr = uiauto->CreatePropertyCondition(UIA_ControlTypePropertyId,
idVar,
&cond);
//find the top editboxes
CComPtr<IUIAutomationElementArray> editboxes;
//if(FAILED(windElem->FindAll(TreeScope_Children, cond, &editboxes)) || !editboxes)
if(FAILED(windElem->FindAll(TreeScope_Descendants, cond, &editboxes)) || !editboxes) //use Descendants instead of Children
return;
int editboxes_count = 0;
editboxes->get_Length(&editboxes_count);
domain = QString::number(editboxes_count);
for(int icnt = 0; icnt < editboxes_count; icnt++)
{
//domain = domain + "icnt:" + QString::number(icnt);
CComPtr<IUIAutomationElement> editbox;
if(FAILED(editboxes->GetElement(icnt, &editbox)) || !editbox)
continue;
VARIANT urlVar;
if(FAILED(editbox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &urlVar)))
{
continue;
}
else
{
// convert URL from BSTR to QString
domain = QString::fromStdWString(std::wstring(
urlVar.bstrVal, SysStringLen(urlVar.bstrVal)));
icnt = editboxes_count; //terminate for loop
}
}
// Cleanup
cond->Release();
windElem->Release();
uiauto->Release(); // Cleanup code for UIAutomation
CoUninitialize(); // Uninitialize COM
return;
}