#windows #winapi #accessibility
#Windows #winapi #Специальные возможности
Вопрос:
Я переношу настольное приложение, поддерживающее специальные возможности Microsoft, с 32-разрядной версии на 64-разрядную. В этом приложении множество пользовательских элементов управления. При вызове NotifyWinEvent()
:
/*Pseudocode*/
MYSTRUCT *ptr;
allocate and assign data to ptr;
Call NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, (long)ptr).
Код извлекает указатель в IAccessible
реализованном методе и использует его:
/* pseudocode */
TDMETHODIMP CMSAAMyProxy::get_accRole( VARIANT varChild, VARIANT *pvarRole )
{
if (VT_I4 == varChild.vt)
{
MYSTRUCT *ptr = (MYSTRUCT *)varChild.lVal;
/* Use the ptr here */
}
}
Такой код написан во многих файлах. Хотя приведенный выше код хорошо работает на 32-разрядной версии, на 64-разрядной происходит сбой из-за усечения указателя.
Есть ли какой-либо альтернативный API, который я могу использовать для решения этой проблемы?
Комментарии:
1. Чтобы решить эту проблему, вам придется сделать шаг назад и должным образом проанализировать, в чем проблема. Проблема здесь в том, что ваша реализация использует API вне своего документированного контракта. Аргумент idChild для NotifyWinEvent содержит идентификатор объекта, а не указатель. Это то, что необходимо исправить. Не существует альтернативного API, который можно надежно использовать вне его спецификации.
2. Идентификаторы объектов MSAA недостаточно велики для переноса 64-разрядных указателей. Чтобы передать указатель на
NotifyWinEvent()
, вам пришлось бы сохранить указатель в переданномHWND
черезSetWindowsLongPtr()
илиSetProp()
, а затем обратные вызовы WinEvent могут извлечь указатель изHWND
. Очевидно, что это не будет работать в рамках процесса. Реальный вопрос в том, почему вашCMSAAMyProxy
класс не содержит необходимый ему указатель? Почему вы вообще пытаетесь передать указатель черезNotifyWinEvent()
? Оно не предназначено для этой цели.3. @RemyLebeau Я согласен с вашей точкой зрения, NotifyWinEvent не следует передавать указатель. Я думаю, это код десятилетней давности. В любом случае я должен проверить альтернативное решение. Я думаю, что здесь может помочь 32-разрядный хэш указателя.