Цитата:
Сообщение от
Товарищ ♂uatr
Привет.
X++:
CLRObject IAccessibleObject = System.Runtime.InteropServices.Marshal::GetObjectForIUnknown(new System.IntPtr(ptrIAccessibleBinary.dWord(0)));
System.String accName = IAccessibleObject.get_accName();
Работает, спасибо.
Но почему то не всегда.
Подправил джоб
Основная проблема вот в чем :
1. При первых запусках метод iAccessibleObject.get_accName();
почему-то возвращает null
А потом когда и так и сяк покрутил, вдруг раз, - его "пробило" и стал не null возвращать. Как-то это стремно. То работает то нет. словно изначально не все подгрузилось и проинициализировалось.
2. Если при вызове dllFuncAccessibleObjectFromWindow.call()
передавать не #OBJID_WINDOW, а #OBJID_CLIENT то возвращаются null и для iAccessibleObject.get_accName() и для iAccessibleObject.get_accDescription(). В то время как в консольном приложении на C# возвращаются непустые значения. Для get_accName - имя AOT объекта а для get_accDescription полный путь в AOT. И именно этот вариант и хотелось задействовать.
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;
CLRObject iAccessibleObject;
System.String accName;
System.String accDescription;
int64 obj_clientUint = 0xFFFFFFFC;
#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)
Exception infoCon(container _con, str _delimiter = " ", URL helpUrl = '', SysInfoAction _sysInfoAction = null)
{
SysInfoLogStr txt = con2Str(_con, _delimiter);
;
return infolog.add(Exception::Info, getPrefix()+txt, helpUrl, _sysInfoAction, false);
}
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,
// #OBJID_CLIENT,
// obj_clientUint,
guidBinary,
// guidXpp,
ptrIAccessibleBinary
);
infoCon(["hResult = ", hResult]);
if (hResult)
{
infoCon(["LastError = ", WinAPI::getLastError()]);
}
// infoCon(["ptrIAccessibleBinary = ", ptrIAccessibleBinary.qWord(0)]);
infoCon(["ptrIAccessibleBinary = ", ptrIAccessibleBinary.dWord(0)]);
iAccessibleObject = System.Runtime.InteropServices.Marshal::GetObjectForIUnknown(new System.IntPtr(ptrIAccessibleBinary.dWord(0)));
accName = iAccessibleObject.get_accName();
// accDescription = iAccessibleObject.get_accDescription();
// accName = iAccessibleObject.accName();
// accDescription = iAccessibleObject.accDescription();
// System.Runtime.InteropServices.Marshal::GetComInterfaceForObject(
/*
try
{
info(ClrMethod_MRC::toString(iAccessibleObject));
}
catch
{
info(AifUtil::getClrErrorMessage());
return;
}
*/
if (CLRInterop::isNull(accName))
{
infoCon(["accName = ", "null"]);
}
else
{
infoCon(["accName = ", CLRInterop::getAnyTypeForObject(accName)]);
}
if (CLRInterop::isNull(accDescription))
{
infoCon(["accDescription = ", "null"]);
}
else
infoCon(["accDescription = ", CLRInterop::getAnyTypeForObject(accDescription)]);
return;
/*
comIAccessible = COM::createFromInterface(ptrIAccessibleBinary.dWord(0));
// comIAccessible = new COM();
// comIAccessible.attach(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());
*/
}