c++ com 如何继承 IUIAutomationPropertyChangedEventHandler 接口

c++ com how to inherit IUIAutomationPropertyChangedEventHandler interface

本文关键字:继承 IUIAutomationPropertyChangedEventHandler 接口 com 何继承 c++      更新时间:2023-10-16

c# code:

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("dsdsdsdsddsdn");
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);

看起来我应该在查询接口((中返回一个IMarshal对象。

我认为它需要一个 otherThread 来循环事件。

伙计们,如何编写这个IMarshal对象?

好的,我在 https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-howto-implement-event-handlers 得到了答案

这些天我的互联网不稳定,没有看到页面