// OnWindowHideOrClose - Called by the WindowHideOrCloseTracker class when UI is hidden or destroyed private static void OnWindowHideOrClose(IntPtr hwnd, AutomationElement rawEl, int [] runtimeId) { bool doWindowClosedEvent = false; bool doStructureChangedEvent = false; lock ( _classLock ) { if (_listeners != null) { // if an hwnd is hidden or closed remove event listeners for the window's provider for (int i = 0; i < _listeners.Count; i++) { EventListenerClientSide ec = (EventListenerClientSide)_listeners[i]; EventListener l = ec.EventListener; if (l.EventId == WindowPattern.WindowClosedEvent) { doWindowClosedEvent = true; } if (l.EventId == AutomationElement.StructureChangedEvent) { doStructureChangedEvent = true; } // Only advise UI contexts if the provider still exists // (but keep looking to see if need to do a WindowClosedEvent) if (rawEl == null) { continue; } // Only advise UI contexts if the provider might raise that event. if (!ShouldAdviseProviders(l.EventId)) { continue; } // Only advise UI contexts if the element is w/in scope of the reference element if (!ec.WithinScope(rawEl)) { continue; } // Notify the server-side that this event is no longer interesting UiaCoreApi.UiaEventRemoveWindow(ec.EventHandle, hwnd); } } } // Piggy-back on the listener for Windows hiding or closing to raise WindowClosed and StructureChanged events. // When the hwnd behind rawEl is being destroyed, it can't be determined that rawEl once had the // WindowPattern interface. Therefore raise an event for any window close. if (doWindowClosedEvent) { // When the hwnd is just hidden, rawEl will not be null, so can test if this would support WindowPattern // and throw this event away if the window doesn't support that CP if (rawEl != null && !HwndProxyElementProvider.IsWindowPatternWindow(NativeMethods.HWND.Cast(hwnd))) { return; } // Go ahead and raise a client-side only WindowClosedEvent (if anyone is listening) WindowClosedEventArgs e = new WindowClosedEventArgs(runtimeId); RaiseEventInThisClientOnly(WindowPattern.WindowClosedEvent, runtimeId, e); } if (doStructureChangedEvent) { // Raise an event for structure changed. This element has essentially gone away so there isn't an // opportunity to do filtering here. So, just like WindowClosed, this event will be very noisy. StructureChangedEventArgs e = new StructureChangedEventArgs(StructureChangeType.ChildRemoved, runtimeId); RaiseEventInThisClientOnly(AutomationElement.StructureChangedEvent, runtimeId, e); } }