Реализация обработчиков событий
В этом разделе содержится пример кода, в котором показано, как реализовать интерфейсы, позволяющие клиентам получать и обрабатывать события Microsoft модель автоматизации пользовательского интерфейса. В нем рассматриваются следующие темы:
- Обработка общих событий модель автоматизации пользовательского интерфейса
- Обработка событий Focus-Changed
- Обработка событий Property-Changed
- Обработка событий Structure-Changed
- Связанные темы
Обработка общих событий модель автоматизации пользовательского интерфейса
Следующий пример кода представляет собой консольное приложение Microsoft Windows, реализующее обработчик событий модель автоматизации пользовательского интерфейса для общих событий модель автоматизации пользовательского интерфейса. В этом примере обрабатываются события создания и уничтожения для подсказок и других окон.
// Defines an event handler for general UI Automation events. It listens for
// tooltip and window creation and destruction events.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>
class EventHandler:
public IUIAutomationEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
// Constructor.
EventHandler(): _refCount(1), _eventCount(0)
{
}
// IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface=static_cast<IUIAutomationEventHandler*>(this);
else if (riid == __uuidof(IUIAutomationEventHandler))
*ppInterface=static_cast<IUIAutomationEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationEventHandler methods
HRESULT STDMETHODCALLTYPE HandleAutomationEvent(IUIAutomationElement * pSender, EVENTID eventID)
{
_eventCount++;
switch (eventID)
{
case UIA_ToolTipOpenedEventId:
wprintf(L">> Event ToolTipOpened Received! (count: %d)\n", _eventCount);
break;
case UIA_ToolTipClosedEventId:
wprintf(L">> Event ToolTipClosed Received! (count: %d)\n", _eventCount);
break;
case UIA_Window_WindowOpenedEventId:
wprintf(L">> Event WindowOpened Received! (count: %d)\n", _eventCount);
break;
case UIA_Window_WindowClosedEventId:
wprintf(L">> Event WindowClosed Received! (count: %d)\n", _eventCount);
break;
default:
wprintf(L">> Event (%d) Received! (count: %d)\n", eventID, _eventCount);
break;
}
return S_OK;
}
};
int main(int argc, char* argv[])
{
HRESULT hr;
int ret = 0;
IUIAutomationElement* pTargetElement = NULL;
EventHandler* pEHTemp = NULL;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
IUIAutomation* pAutomation = NULL;
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
if(FAILED(hr) || pAutomation==NULL)
{
ret = 1;
goto cleanup;
}
// Use root element for listening to window and tooltip creation and destruction.
hr = pAutomation->GetRootElement(&pTargetElement);
if (FAILED(hr) || pTargetElement==NULL)
{
ret = 1;
goto cleanup;
}
pEHTemp = new EventHandler();
if (pEHTemp == NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Adding Event Handlers.\n");
hr = pAutomation->AddAutomationEventHandler(UIA_ToolTipOpenedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_ToolTipClosedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_Window_WindowOpenedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
hr = pAutomation->AddAutomationEventHandler(UIA_Window_WindowClosedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
wprintf(L"-Press any key to remove event handlers and exit\n");
getchar();
wprintf(L"-Removing Event Handlers.\n");
cleanup:
// Remove event handlers, release resources, and terminate
if (pAutomation != NULL)
{
hr = pAutomation->RemoveAllEventHandlers();
if (FAILED(hr))
ret = 1;
pAutomation->Release();
}
if (pEHTemp != NULL)
pEHTemp->Release();
if (pTargetElement != NULL)
pTargetElement->Release();
CoUninitialize();
return ret;
}
Обработка событий Focus-Changed
Следующий пример кода представляет собой консольное приложение Windows, реализующее обработчик для событий изменения фокуса.
// Defines an event handler for focus changed events and starts
// listening to them.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>
class EventHandler:
public IUIAutomationFocusChangedEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
//Constructor.
EventHandler(): _refCount(1), _eventCount(0)
{
}
//IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface = static_cast<IUIAutomationFocusChangedEventHandler*>(this);
else if(riid == __uuidof(IUIAutomationFocusChangedEventHandler))
*ppInterface=static_cast<IUIAutomationFocusChangedEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationFocusChangedEventHandler methods.
HRESULT STDMETHODCALLTYPE HandleFocusChangedEvent(IUIAutomationElement * pSender)
{
_eventCount++;
wprintf(L">> FocusChangedEvent Received! (count: %d)\n", _eventCount);
return S_OK;
}
};
int main(int argc, char* argv[])
{
HRESULT hr;
int ret = 0;
EventHandler* pEHTemp = NULL;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
IUIAutomation* pAutomation = NULL;
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
if (FAILED(hr) || pAutomation == NULL)
{
ret = 1;
goto cleanup;
}
pEHTemp = new EventHandler();
if (pEHTemp == NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Adding Event Handlers.\n");
hr = pAutomation->AddFocusChangedEventHandler(NULL, (IUIAutomationFocusChangedEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
wprintf(L"-Press any key to remove event handler and exit\n");
getchar();
wprintf(L"-Removing Event Handlers.\n");
hr = pAutomation->RemoveFocusChangedEventHandler((IUIAutomationFocusChangedEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
// Release resources and terminate.
cleanup:
if (pEHTemp != NULL)
pEHTemp->Release();
if (pAutomation != NULL)
pAutomation->Release();
CoUninitialize();
return ret;
}
Обработка событий Property-Changed
В следующем примере кода показано консольное приложение Windows, реализующее обработчик для событий изменения свойства.
// Defines an event handler for property-changed events, and listens for
// ToggleState property changes on the element specifies by the user.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>
class EventHandler:
public IUIAutomationPropertyChangedEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
//Constructor.
EventHandler(): _refCount(1), _eventCount(0)
{
}
//IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
else if (riid == __uuidof(IUIAutomationPropertyChangedEventHandler))
*ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationPropertyChangedEventHandler methods.
HRESULT STDMETHODCALLTYPE HandlePropertyChangedEvent(IUIAutomationElement* pSender, PROPERTYID propertyID, VARIANT newValue)
{
_eventCount++;
if (propertyID == UIA_ToggleToggleStatePropertyId)
wprintf(L">> Property ToggleState changed! ");
else
wprintf(L">> Property (%d) changed! ", propertyID);
if (newValue.vt == VT_I4)
wprintf(L"(0x%0.8x) ", newValue.lVal);
wprintf(L"(count: %d)\n", _eventCount);
return S_OK;
}
};
int main(int argc, char* argv[])
{
HRESULT hr;
int ret = 0;
IUIAutomationElement* pTargetElement = NULL;
EventHandler* pEHTemp = NULL;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
IUIAutomation* pAutomation = NULL;
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
if (FAILED(hr) || pAutomation==NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Use the mouse to point to the element you want to listen from.\n");
Sleep(3000);
// Make this application dots-per-inch (DPI) aware.
SetProcessDPIAware();
// Get mouse cursor position and get element from point.
POINT pt;
GetPhysicalCursorPos(&pt);
hr = pAutomation->ElementFromPoint(pt, &pTargetElement);
if (FAILED(hr) || pTargetElement==NULL)
{
ret = 1;
goto cleanup;
}
pEHTemp = new EventHandler();
if (pEHTemp == NULL)
{
ret = 1;
goto cleanup;
}
PROPERTYID pPIDProperties[] = { UIA_ToggleToggleStatePropertyId };
wprintf(L"-Adding Event Handler.\n");
hr = pAutomation->AddPropertyChangedEventHandlerNativeArray(pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationPropertyChangedEventHandler*) pEHTemp, pPIDProperties, sizeof(pPIDProperties) / sizeof(pPIDProperties[0]));
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
wprintf(L"-Press any key to remove event handler and exit\n");
getchar();
wprintf(L"-Removing Event Handler.\n");
hr = pAutomation->RemovePropertyChangedEventHandler(pTargetElement, (IUIAutomationPropertyChangedEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
// Release resources and terminate.
cleanup:
if (pEHTemp != NULL)
pEHTemp->Release();
if (pTargetElement != NULL)
pTargetElement->Release();
if (pAutomation != NULL)
pAutomation->Release();
CoUninitialize();
return ret;
}
Обработка событий Structure-Changed
В следующем примере кода используется консольное приложение Windows, реализующее обработчик для событий изменения структуры.
// Defines an event handler for structure-changed events, and
// listens for them on the element specifies by the user.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>
class EventHandler:
public IUIAutomationStructureChangedEventHandler
{
private:
LONG _refCount;
public:
int _eventCount;
// Constructor.
EventHandler(): _refCount(1), _eventCount(0)
{
}
// IUnknown methods.
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ret = InterlockedIncrement(&_refCount);
return ret;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ret = InterlockedDecrement(&_refCount);
if (ret == 0)
{
delete this;
return 0;
}
return ret;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown))
*ppInterface=static_cast<IUIAutomationStructureChangedEventHandler*>(this);
else if (riid == __uuidof(IUIAutomationStructureChangedEventHandler))
*ppInterface=static_cast<IUIAutomationStructureChangedEventHandler*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
this->AddRef();
return S_OK;
}
// IUIAutomationStructureChangedEventHandler methods
HRESULT STDMETHODCALLTYPE HandleStructureChangedEvent(IUIAutomationElement* pSender, StructureChangeType changeType, SAFEARRAY* pRuntimeID) {
_eventCount++;
switch (changeType)
{
case StructureChangeType_ChildAdded:
wprintf(L">> Structure Changed: ChildAdded! (count: %d)\n", _eventCount);
break;
case StructureChangeType_ChildRemoved:
wprintf(L">> Structure Changed: ChildRemoved! (count: %d)\n", _eventCount);
break;
case StructureChangeType_ChildrenInvalidated:
wprintf(L">> Structure Changed: ChildrenInvalidated! (count: %d)\n", _eventCount);
break;
case StructureChangeType_ChildrenBulkAdded:
wprintf(L">> Structure Changed: ChildrenBulkAdded! (count: %d)\n", _eventCount);
break;
case StructureChangeType_ChildrenBulkRemoved:
wprintf(L">> Structure Changed: ChildrenBulkRemoved! (count: %d)\n", _eventCount);
break;
case StructureChangeType_ChildrenReordered:
wprintf(L">> Structure Changed: ChildrenReordered! (count: %d)\n", _eventCount);
break;
}
return S_OK;
}
};
int main(int argc, char* argv[])
{
HRESULT hr;
int ret = 0;
IUIAutomationElement* pTargetElement = NULL;
EventHandler* pEHTemp = NULL;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
IUIAutomation* pAutomation=NULL;
hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
if (FAILED(hr) || pAutomation == NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Use the mouse to point to the element you want to listen from.\n");
Sleep(3000);
// Make this application dots-per-inch (DPI) aware.
SetProcessDPIAware();
// Get mouse cursor position and get element from point.
POINT pt;
GetPhysicalCursorPos(&pt);
hr = pAutomation->ElementFromPoint(pt, &pTargetElement);
if (FAILED(hr) || pTargetElement == NULL)
{
ret = 1;
goto cleanup;
}
pEHTemp = new EventHandler();
if (pEHTemp == NULL)
{
ret = 1;
goto cleanup;
}
wprintf(L"-Adding Event Handler.\n");
hr = pAutomation->AddStructureChangedEventHandler(pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationStructureChangedEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
wprintf(L"-Press any key to remove event handler and exit\n");
getchar();
wprintf(L"-Removing Event Handler.\n");
hr = pAutomation->RemoveStructureChangedEventHandler(pTargetElement, (IUIAutomationStructureChangedEventHandler*) pEHTemp);
if (FAILED(hr))
{
ret = 1;
goto cleanup;
}
// Release resources and terminate.
cleanup:
if (pEHTemp != NULL)
pEHTemp->Release();
if (pTargetElement != NULL)
pTargetElement->Release();
if (pAutomation != NULL)
pAutomation->Release();
CoUninitialize();
return ret;
}
Связанные темы
-
Основные понятия
-
Подписка на события модель автоматизации пользовательского интерфейса
-
Практические руководства для клиентов модель автоматизации пользовательского интерфейса