c++ - UIAutomation:AddAutomationEventHandler() 返回 E_INVALIDARG
问题描述
这是我的代码:
// Defines an event handler for general UI Automation events. It listens for
// tooltip and window creation and destruction events.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>
class EventHandler :
public IUIAutomationEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
// Constructor.
EventHandler() : _refCount(1), _eventCount(0)
{
}
// IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface = static_cast<IUIAutomationEventHandler*>(this);
else if (riid == __uuidof(IUIAutomationEventHandler))
*ppInterface = static_cast<IUIAutomationEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationEventHandler methods
HRESULT STDMETHODCALLTYPE HandleAutomationEvent(IUIAutomationElement * pSender, EVENTID eventID)
{
_eventCount++;
switch (eventID)
{
case UIA_AutomationFocusChangedEventId:
wprintf(L">> Event FocusChanged Received! (count: %d)\n", _eventCount);
break;
case UIA_ToolTipOpenedEventId:
wprintf(L">> Event ToolTipOpened Received! (count: %d)\n", _eventCount);
break;
case UIA_ToolTipClosedEventId:
wprintf(L">> Event ToolTipClosed Received! (count: %d)\n", _eventCount);
break;
case UIA_Window_WindowOpenedEventId:
wprintf(L">> Event WindowOpened Received! (count: %d)\n", _eventCount);
break;
case UIA_Window_WindowClosedEventId:
wprintf(L">> Event WindowClosed Received! (count: %d)\n", _eventCount);
break;
default:
wprintf(L">> Event (%d) Received! (count: %d)\n", eventID, _eventCount);
break;
}
return S_OK;
}
};
int main(int argc, char* argv[])
{
HRESULT hr;
int ret = 0;
IUIAutomationElement* pTargetElement = NULL;
EventHandler* pEHTemp = NULL;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
IUIAutomation* pAutomation = NULL;
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
if (FAILED(hr) || pAutomation == NULL)
{
ret = 1;
goto cleanup;
}
// Use root element for listening to window and tooltip creation and destruction.
hr = pAutomation->GetRootElement(&pTargetElement);
if (FAILED(hr) || pTargetElement == NULL)
{
ret = 1;
goto cleanup;
}
pEHTemp = new EventHandler();
if (pEHTemp == NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Adding Event Handlers.\n");
hr = pAutomation->AddAutomationEventHandler(UIA_ToolTipOpenedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_ToolTipClosedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_Window_WindowOpenedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_Window_WindowClosedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
// Error is here. hr returns E_INVALIDARG.
hr = pAutomation->AddAutomationEventHandler(UIA_AutomationFocusChangedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
wprintf(L"-Press any key to remove event handlers and exit\n");
getchar();
wprintf(L"-Removing Event Handlers.\n");
cleanup:
// Remove event handlers, release resources, and terminate
if (pAutomation != NULL)
{
hr = pAutomation->RemoveAllEventHandlers();
if (FAILED(hr))
ret = 1;
pAutomation->Release();
}
if (pEHTemp != NULL)
pEHTemp->Release();
if (pTargetElement != NULL)
pTargetElement->Release();
CoUninitialize();
return ret;
}
此代码来自 Microsoft 关于实现 UIAutomation 事件类的示例。
我稍微编辑了代码,以便它可以支持焦点事件,但我未能尝试初始化一行代码。
我不明白为什么hr = pAutomation->AddAutomationEventHandler(UIA_AutomationFocusChangedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)pEHTemp)
返回 E_INVALIDARG。
尝试阅读文档,但我找不到原因。
请帮忙。
解决方案
有一个单独的处理程序来处理FocusChanged
,AddFocusChangedEventHandler
应该用于监视焦点更改。由于您试图发送一个EventHandler
函数指针来处理FocusChanged
,运行时错误即将到来。
要创建该处理程序,需要一个继承自IUIAutomationFocusChangedEventHandler
.
class FocusChangedEventHandler :
public IUIAutomationFocusChangedEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
//Constructor.
FocusChangedEventHandler() : _refCount(1), _eventCount(0)
{
}
//IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface = static_cast<IUIAutomationFocusChangedEventHandler*>(this);
else if (riid == __uuidof(IUIAutomationFocusChangedEventHandler))
*ppInterface = static_cast<IUIAutomationFocusChangedEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationFocusChangedEventHandler methods.
HRESULT STDMETHODCALLTYPE HandleFocusChangedEvent(IUIAutomationElement * pSender)
{
_eventCount++;
wprintf(L">> FocusChangedEvent Received! (count: %d)\n", _eventCount);
return S_OK;
}
};
在main()
pFHTemp = new FocusChangedEventHandler();
hr = pAutomation->AddFocusChangedEventHandler(NULL, (IUIAutomationFocusChangedEventHandler*)pFHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
推荐阅读
- aurelia - Aurelia 服务器端渲染 - 避免不必要的客户端 api 调用
- python-3.x - 使用 Selenium 收集的 cookie 的到期日期格式
- wordpress - 如何在循环帖子到引导网格时获取 WordPress?
- azure - Azure DevOps (VSTS / TFS) - 通过 OData/API 添加讨论
- r - 如何使用 R 中的绘图功能绘制具有不同颜色的不同组
- c# - Identity Server 4 - API 在部署到服务器时返回 401 Unauthorized
- python - 在python中使用变量的Mysql Update语句
- c# - 具有多个部分的 C# xml 到字典转换
- r - 如何从 zip 读取多个 csv 文件并导入 R 中的不同数据帧?
- ios - 适用于 iOS 的 HERE SDK - 切换服务器环境