Как использовать модель автоматизации пользовательского интерфейса для создания доступа к элементу ActiveX без окон
В этой статье описывается, как использовать API microsoft модель автоматизации пользовательского интерфейса для обеспечения доступности элемента управления Microsoft ActiveX без окон для клиентских приложений со специальными возможностями (AT).
- C/C++
- Программирование Microsoft Win32 и com-модели
- Элементы ActiveX без окон
- поставщики модель автоматизации пользовательского интерфейса
Чтобы сделать приложение доступным, необходимо реализовать интерфейсы поставщика модель автоматизации пользовательского интерфейса для элемента Управления ActiveX без окон, включая IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRoot и IRawElementProviderAdviseEvents. Эти интерфейсы следует реализовать так же, как и для оконного элемента управления, за исключением описанных ниже действий. Дополнительные сведения о реализации интерфейсов поставщика UIA см. в руководстве программиста поставщика модель автоматизации пользовательского интерфейса.
Когда клиенту требуются сведения о специальных возможностях для вашего элемента управления без окон, контейнер элемента управления вызывает метод IServiceProvider::QueryService элемента управления для получения указателя интерфейса IRawElementProviderSimple для элемента управления.
В следующем примере показано, как реализовать метод QueryService .
STDMETHODIMP CMyAccessibleUIAControl::QueryService(REFGUID guidService,
REFIID riid, void **ppvObject)
{
if (ppvObject == NULL)
{
return E_INVALIDARG;
}
*ppvObject = NULL;
HRESULT hr = E_FAIL;
if (guidService == __uuidof(IRawElementProviderSimple))
{
hr = QueryInterface(riid, ppvObject);
}
return hr;
}
При вызове метода IRawElementProviderFragment::Navigate элемента управления без окон для перехода к родительскому или одноуровневым элементам корневого поставщика элемента управления без окна метод Navigate должен делегироваться методу IRawElementProviderWindowlessSite::GetAdjacentFragment контейнера элемента управления.
В следующем примере показано, как реализовать метод Navigate .
STDMETHODIMP CMyAccessibleUIAControl::Navigate(NavigateDirection direction,
IRawElementProviderFragment **ppRetVal)
{
if (ppRetVal == NULL)
{
return E_INVALIDARG;
}
*ppRetVal = NULL;
HRESULT hr = E_FAIL;
IRawElementProviderWindowlessSite *pWindowlessSite = NULL;
if (direction == NavigateDirection_Parent)
{
// Query the control container's windowless site
// for the parent.
if (SUCCEEDED(m_pClientSite->QueryInterface(
IID_PPV_ARGS(&pWindowlessSite))))
{
hr = pWindowlessSite->GetAdjacentFragment(direction, ppRetVal);
}
}
else if (direction == NavigateDirection_FirstChild)
{
// GetFragmentForChild is an application-defined function that
// retrieves the first or last child fragment.
hr = GetFragmentForChild(FIRST, ppRetVal);
}
else if (direction == NavigateDirection_LastChild)
{
hr = GetFragmentForChild(LAST, ppRetVal);
}
SafeRelease(&pWindowlessSite);
return S_OK;
}
Когда элемент управления без окон получает вызов метода IRawElementProviderFragment::GetRuntimeId , элемент управления должен выполнять следующие действия:
- Получите префикс идентификатора среды выполнения, вызвав метод IRawElementProviderWindowlessSite::GetRuntimeIdPrefix сайта элемента управления.
- Создайте уникальный идентификатор среды выполнения для элемента управления , добавив целое число к префиксу идентификатора среды выполнения.
- Возврат идентификатора среды выполнения вызывающей объекту.
В следующем примере показано, как реализовать метод GetRuntimeId .
STDMETHODIMP CMyAccessibleUIAControl::GetRuntimeId(SAFEARRAY **ppRetVal)
{
if (ppRetVal == NULL)
{
return E_INVALIDARG;
}
*ppRetVal = NULL;
HRESULT hr = E_FAIL;
IRawElementProviderWindowlessSite *pWindowlessSite = NULL;
if (SUCCEEDED(m_pClientSite->QueryInterface(IID_PPV_ARGS(&pWindowlessSite))))
{
// Create a safe array to hold runtime ID.
SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 1, 3);
if (psa == NULL)
{
hr = E_OUTOFMEMORY;
}
// Retrieve the runtime ID prefix from the control container. The prefix
// consists of UiaAppendRuntimeId followed by the windowless site ID.
if (SUCCEEDED(hr))
{
hr = pWindowlessSite->GetRuntimeIdPrefix(&psa);
}
if (SUCCEEDED(hr))
{
// Append this fragment's ID to the retrieved runtime ID prefix.
long i = 2;
hr = SafeArrayPutElement(psa, &i, (void*)&m_Id);
}
if (SUCCEEDED(hr))
{
*ppRetVal = psa;
}
}
SafeRelease(&pWindowlessSite);
return hr;
}