【发布时间】:2020-09-09 05:53:22
【问题描述】:
c#代码:
var nativeAutomation = new UIAutomationClient.CUIAutomation8();
nativeAutomation.AddPropertyChangedEventHandler(ele, UIA.TreeScope.TreeScope_Element, null, new handler(), pidarray);
AddPropertyChangedEventHandler 中使用的处理程序
class handler : UIAutomationClient.IUIAutomationPropertyChangedEventHandler
{
public void HandlePropertyChangedEvent(UIA.IUIAutomationElement src, int propertyId, object newValue)
{
UIA.IUIAutomationElement sourceElement = src as UIA.IUIAutomationElement;
Console.WriteLine(propertyId + ":" + newValue);
}
}
效果很好
但是当我使用 c++ 时:
#include "stdafx.h"
#include <Windows.h>
#include "test.h"
#include "cbt.h"
#include <UIAutomationClient.h>
#include <iostream>
#include <string>
#pragma comment(lib,"testDll.lib")
class A :public IUIAutomationPropertyChangedEventHandler {
ULONG m_ref;
public:
A() :m_ref(0)
{}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID &id, void** p) override {
// return IUnknown::QueryInterface(id,p);
REFIID d = { 0x0000001b,0x0000,0x0000, {0xC0,00,00,00,00,00,00,0x46} };// IdentityUnmarshal.
if (id == d) {
return E_NOINTERFACE;
}
*p = this;
return S_OK;
//return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef() override {
++m_ref;
//return IUnknown::AddRef();
return m_ref;
}
virtual ULONG STDMETHODCALLTYPE Release() override {
// return IUnknown::Release();
--m_ref;
if (!m_ref)
delete this;
return m_ref;
}
virtual HRESULT STDMETHODCALLTYPE HandlePropertyChangedEvent(
/* [in] */ __RPC__in_opt IUIAutomationElement *sender,
/* [in] */ PROPERTYID propertyId,
/* [in] */ VARIANT newValue) {
printf("dsdsdsdsddsd\n");
return S_OK;
};
};
int main()
{
// cbt::Instance();
CoInitializeEx(NULL, COINIT_MULTITHREADED);
IUIAutomation* am = NULL;
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation8), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation), (void**)&am);
if (S_OK != hr)
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation), (void**)&am);
A* a = new A;
std::string hx;
std::getline(std::cin, hx);
char* s = NULL;
HWND h = (HWND)strtol(hx.c_str(), &s, 16);
IUIAutomationElement* ele = NULL;
am->ElementFromHandle(h, &ele);
/*SAFEARRAY* sa = SafeArrayCreateVector(VT_I4, 0, 4);
LONG i = 0;
long pid = UIA_AutomationIdPropertyId;
SafeArrayPutElement(sa, &i, &pid);
i = 1;
pid = UIA_BoundingRectanglePropertyId;
SafeArrayPutElement(sa, &i, &pid);
i = 2;
pid = UIA_ClassNamePropertyId;
SafeArrayPutElement(sa, &i, &pid);
i = 3;
pid = UIA_NamePropertyId;
SafeArrayPutElement(sa, &i, &pid);
am->AddPropertyChangedEventHandler(ele, TreeScope_Element, NULL, p,sa );
SafeArrayDestroy(sa);*/
PROPERTYID *pids = new PROPERTYID[4];
pids[0] = UIA_AutomationIdPropertyId;
pids[1] = UIA_BoundingRectanglePropertyId;
pids[2] = UIA_ClassNamePropertyId;
pids[3] = UIA_NamePropertyId;
am->AddPropertyChangedEventHandlerNativeArray(ele, TreeScope_Element, NULL, a, pids, 4);
getchar();
CoUninitialize();
return 0;
}
所以,在 c# 中很容易。
但是,使用 c++,我需要覆盖 Addref()、Release()、QueryInterface()。
调用时出错
am->AddPropertyChangedEventHandlerNativeArray(ele, TreeScope_Element, NULL, a, pids, 4);
看起来我应该在 QueryInterface() 中返回一个 IMarshal 对象。
我认为它需要一个 otherThread 来循环事件。
各位,这个 IMarshal 对象如何编码?
【问题讨论】:
标签: c# c++ com ui-automation microsoft-ui-automation