static void CALLBACK logEventProc(HWINEVENTHOOK, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD, DWORD) { // Get the accessible object for this event. COMPtr<IAccessible> parentObject; VARIANT vChild; VariantInit(&vChild); HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &parentObject, &vChild); ASSERT(SUCCEEDED(hr)); // Get the name of the focused element, and log it to stdout. BSTR nameBSTR; hr = parentObject->get_accName(vChild, &nameBSTR); ASSERT(SUCCEEDED(hr)); wstring name(nameBSTR, ::SysStringLen(nameBSTR)); SysFreeString(nameBSTR); switch (event) { case EVENT_OBJECT_FOCUS: printf("Received focus event for object '%S'.\n", name.c_str()); break; case EVENT_OBJECT_SELECTION: printf("Received selection event for object '%S'.\n", name.c_str()); break; case EVENT_OBJECT_VALUECHANGE: { BSTR valueBSTR; hr = parentObject->get_accValue(vChild, &valueBSTR); ASSERT(SUCCEEDED(hr)); wstring value(valueBSTR, ::SysStringLen(valueBSTR)); SysFreeString(valueBSTR); printf("Received value change event for object '%S', value '%S'.\n", name.c_str(), value.c_str()); break; } case EVENT_SYSTEM_SCROLLINGSTART: printf("Received scrolling start event for object '%S'.\n", name.c_str()); break; default: printf("Received unknown event for object '%S'.\n", name.c_str()); break; } VariantClear(&vChild); }