// We need to treat MSAA's FOCUS winevents differently depending on the OBJID - // OBJID_CLIENT gets routed to the proxies; _MENU and _SYSMENU get speical treatment. private AutomationElement GetFocusedElementFromWinEvent(IntPtr hwnd, int idObject, int idChild) { try { IRawElementProviderSimple provider = null; // These are the only object types that oleacc proxies allow to take focus. // (Native IAccessibles can send focus for other custom OBJID valus, but those are no use // to us.) // Try and get providers for them ourself - if we don't get anything, then // defer to core to get the element for the HWND itself. if (idObject == UnsafeNativeMethods.OBJID_CLIENT) { // regular focus - pass it off to a proxy... provider = ProxyManager.ProxyProviderFromHwnd(NativeMethods.HWND.Cast(hwnd), idChild, UnsafeNativeMethods.OBJID_CLIENT); } else if (idObject == UnsafeNativeMethods.OBJID_MENU) { // menubar focus - see if there's a menubar pseudo-proxy registered... ClientSideProviderFactoryCallback factory = ProxyManager.NonClientMenuBarProxyFactory; if (factory != null) { provider = factory(hwnd, idChild, idObject); } } else if (idObject == UnsafeNativeMethods.OBJID_SYSMENU) { // system menu box focus - see if there's a sysmenu pseudo-proxy registered... ClientSideProviderFactoryCallback factory = ProxyManager.NonClientSysMenuProxyFactory; if (factory != null) { provider = factory(hwnd, idChild, idObject); } } else if (idObject <= 0) { return(null); } else { // This covers OBJID_CLIENT and custom OBJID cases. // Pass it to the proxy manager: most proxies will just handle OBJID_CLIENT, // but the MSAA proxy can potentally handle other OBJID values. provider = ProxyManager.ProxyProviderFromHwnd(NativeMethods.HWND.Cast(hwnd), idChild, idObject); } if (provider != null) { // Ask the fragment root if any of its children really have the focus IRawElementProviderFragmentRoot fragment = provider as IRawElementProviderFragmentRoot; if (fragment != null) { // if we get back something that is different than what we started with and its not null // use that instead. This is here to get the subset link in the listview but could be usefull // for listview subitems as well. IRawElementProviderSimple realFocus = fragment.GetFocus(); if (realFocus != null && !Object.ReferenceEquals(realFocus, provider)) { provider = realFocus; } } SafeNodeHandle hnode = UiaCoreApi.UiaNodeFromProvider(provider); return(AutomationElement.Wrap(hnode)); } else { // Didn't find a proxy to handle this hwnd - pass off to core... return(AutomationElement.FromHandle(hwnd)); } } catch (Exception e) { if (Misc.IsCriticalException(e)) { throw; } return(null); } }