// Unmanaged DLL calls back on this to notify a UIAccess client of an event. internal void OnEvent(IntPtr argsAddr, object[,] requestedData, string treeStructure) { AutomationEventArgs e = UiaCoreApi.GetUiaEventArgs(argsAddr); if (e.EventId == AutomationElement.AutomationFocusChangedEvent) { uint eventTime = SafeNativeMethods.GetTickCount(); if (eventTime == 0) // 0 is used as a marker value, so bump up to 1 if we get it. { eventTime = 1; } // There's no FocusChangedEventArgs in core, but clients expect one, so substitute if needed... // (otherwise the cast in InvokeHandlers will fail...) e = new InternalAutomationFocusChangedEventArgs(0, 0, eventTime); } UiaCoreApi.UiaCacheResponse cacheResponse = new UiaCoreApi.UiaCacheResponse(requestedData, treeStructure, _eventListener.CacheRequest); // Invoke the listener's callback but not on this thread. Queuing this onto a worker thread allows // OnEvent to return (which allows the call on the server-side to complete) and avoids a deadlock // situation when the client accesses properties on the source element. ClientEventManager.CBQ.PostWorkItem(new CalloutQueueItem(_clientCallback, cacheResponse, e, _eventListener.CacheRequest)); }