т.е. в целом все работает.
А из аксапты у меня не получилось.
Вот джоб
X++:
static void AotInspectWindows(Args _args)
{
HWND hwnd = 67552;
// HWND hwnd = 0;
DLL dllOleacc;
DLLFunction dllFuncAccessibleObjectFromWindow;
Binary guidBinary;
// guid guidXpp;
Binary ptrIAccessibleBinary;
int hResult;
COM comIAccessible;
COMDispFunction comFunc;
COMVariant varChild;
COMVariant pszString;
#define.OBJID_WINDOW (0x00000000)
#define.OBJID_SYSMENU (0xFFFFFFFF)
#define.OBJID_TITLEBAR (0xFFFFFFFE)
#define.OBJID_MENU (0xFFFFFFFD)
#define.OBJID_CLIENT (0xFFFFFFFC)
#define.OBJID_VSCROLL (0xFFFFFFFB)
#define.OBJID_HSCROLL (0xFFFFFFFA)
#define.OBJID_SIZEGRIP (0xFFFFFFF9)
#define.OBJID_CARET (0xFFFFFFF8)
#define.OBJID_CURSOR (0xFFFFFFF7)
#define.OBJID_ALERT (0xFFFFFFF6)
#define.OBJID_SOUND (0xFFFFFFF5)
Binary guid2Binary(str _guidStr)
{
guid guidVar;
System.Guid guidNet;
System.Byte[] buffer;
System.IO.MemoryStream stream;
Binary ret;
;
guidVar = str2guid(_guidStr);
stream = new System.IO.MemoryStream();
// stream.Write(guidVar);
guidNet = guidVar;
buffer = guidNet.ToByteArray();
// infoCon(["length", CLRInterop::getAnyTypeForObject(buffer.get_Length())]);
stream.Write(buffer, 0, 16);
// info(ClrMethod_MRC::toString(stream));
// info(ClrMethod_MRC::toString(stream.get_Length()));
ret = Binary::constructFromMemoryStream(stream);
/*
// info(ret.xml());
info(int2Hex(ret.byte(0), 2));
info(int2Hex(ret.byte(1), 2));
info(int2Hex(ret.byte(2), 2));
info(int2Hex(ret.byte(3), 2));
info(int2Hex(ret.byte(4), 2));
info(int2Hex(ret.byte(5), 2));
info(int2Hex(ret.byte(6), 2));
info(int2Hex(ret.byte(7), 2));
info(int2Hex(ret.byte(8), 2));
info(int2Hex(ret.byte(9), 2));
info(int2Hex(ret.byte(10), 2));
info(int2Hex(ret.byte(11), 2));
info(int2Hex(ret.byte(12), 2));
info(int2Hex(ret.byte(13), 2));
info(int2Hex(ret.byte(14), 2));
info(int2Hex(ret.byte(15), 2));
info('');
*/
stream.Close();
return ret;
}
;
dllOleacc = new DLL('oleacc.dll');
dllFuncAccessibleObjectFromWindow = new DLLFunction(dllOleacc, 'AccessibleObjectFromWindow');
// [url]https://learn.microsoft.com/en-us/windows/win32/api/oleacc/nf-oleacc-accessibleobjectfromwindow[/url]
// HRESULT AccessibleObjectFromWindow(
// [in] HWND hwnd,
// [in] DWORD dwId,
// [in] REFIID riid,
// [out] void **ppvObject
// );
dllFuncAccessibleObjectFromWindow.arg(
ExtTypes::DWord, // [in] HWND hwnd,
ExtTypes::DWord, // [in] DWORD dwId,
ExtTypes::Pointer, // [in] REFIID riid, // TO DO
ExtTypes::Pointer // [out] void **ppvObject // TO DO
);
guidBinary = guid2Binary('{618736E0-3C3D-11CF-810C-00AA00389B71}'); // IAccessible Interface // [url]https://learn.microsoft.com/en-us/dotnet/api/accessibility.iaccessible?view=windowsdesktop-7.0[/url]
// guidXpp = str2guid('{618736E0-3C3D-11CF-810C-00AA00389B71}');
/*
ptrIAccessibleBinary = new Binary(8);
ptrIAccessibleBinary.qWord(0, 0);
*/
ptrIAccessibleBinary = new Binary(4);
ptrIAccessibleBinary.dWord(0, 0);
infoCon(["ptrIAccessibleBinary = ", ptrIAccessibleBinary.dWord(0)]);
dllFuncAccessibleObjectFromWindow.returns(ExtTypes::DWord); // HRESULT
hResult = dllFuncAccessibleObjectFromWindow.call(
hwnd,
#OBJID_WINDOW,
guidBinary,
// guidXpp,
ptrIAccessibleBinary
);
infoCon(["hResult = ", hResult]);
if (hResult)
{
infoCon(["LastError = ", WinAPI::getLastError()]);
}
// infoCon(["ptrIAccessibleBinary = ", ptrIAccessibleBinary.qWord(0)]);
infoCon(["ptrIAccessibleBinary = ", ptrIAccessibleBinary.dWord(0)]);
comIAccessible = COM::createFromInterface(ptrIAccessibleBinary.dWord(0));
// comFunc = new COMDispFunction(comIAccessible, "get_accName", COMDispContext::PropertyGet);
varChild = COMVariant::createFromInt(0, COMVariantInOut::In); // CHILDID_SELF
info(any2str_MRC(varChild.variantType()));
// pszString = COMVariant::createFromStr('', COMVariantInOut::Out_retVal);
pszString = new COMVariant(
COMVariantInOut::Out_retVal,
COMVariantType::VT_BSTR);
// comFunc = new COMDispFunction(comIAccessible, "accName", COMDispContext::PropertyGet);
// hResult = comFunc.call(varChild, pszString); Метод "accName" в COM-объекте класса "IAccessible" возвратил код ошибки 0x8002000E (DISP_E_BADPARAMCOUNT), который означает: Число аргументов, указанных в вызове функции, отличается от числа аргументов в объявлении метода.
// comFunc = new COMDispFunction(comIAccessible, "get_accName", COMDispContext::Method); // Метод "get_accName" не поддерживается интерфейсом Automation COM-объекта класса "IAccessible".
// hResult = comFunc.call(varChild, pszString);
comFunc = new COMDispFunction(comIAccessible, "accName", COMDispContext::Method);
hResult = comFunc.call(varChild, pszString); // Метод "accName" в COM-объекте класса "IAccessible" возвратил код ошибки 0x80020003 (DISP_E_MEMBERNOTFOUND), который означает: Запрошенный метод не существует или во время вызова была осуществлена попытка присвоить некоторое значение свойству, доступному только для чтения.
// comIAccessible.accName(varChild, pszString); // пустая строка
// comIAccessible.get_accName(varChild, pszString); // ошибка
info(pszString.toString());
info(pszString.bStr());
}
Вызываю AccessibleObjectFromWindow
получаю интерфейс IAccessible
дальше непонятно как из аксапты вызвать на нем метод.
Попробовал через Com - он даже его видит, но что-то с числом параметров ругается.
Натравил на oleacc.dll мастер оберток com объектов в аксапте. А он видит интерфейс IAccessible но обертку делает пустую - т.е. не видит ничего в нем, нет свойств и методов. И это странно.