// 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);
            }
        }
Пример #2
0
        //



        protected override bool ReleaseHandle()
        {
            return(Misc.CloseHandle(handle));
        }
Пример #3
0
        // Given an entry from one of the hash-tables or lists, check if it matches the image/classname, and if so, call the
        // factory method to create the proxy.
        // (Because full classname matching is done via hash-table lookup, this only needs to do string comparisons
        // for partial classname matches.)
        static private IRawElementProviderSimple GetProxyFromEntry(ProxyScoping findType, object entry, ref string imageName, NativeMethods.HWND hwnd, int idChild, int idObject, string classNameForPartialMatch)
        {
            // First, determine if the entry matches, and if so, extract the factory callback...
            ClientSideProviderFactoryCallback factoryCallback = null;

            // The entry may be a ClientSideProviderFactoryCallback or ClientSideProviderDescription...
            if (findType == ProxyScoping.ImageOnlyHandlers || findType == ProxyScoping.FallbackHandlers)
            {
                // Handle the fallback and image cases specially. The array for these is an array
                // of ClientSideProviderFactoryCallbacks, not ClientSideProviderDescription.
                factoryCallback = (ClientSideProviderFactoryCallback)entry;
            }
            else
            {
                // Other cases use ClientSideProviderDescription...
                ClientSideProviderDescription pi = (ClientSideProviderDescription)entry;

                // Get the image name if necessary...
#pragma warning suppress 6507 // Null and Empty string mean different things here.
                if (imageName == null && pi.ImageName != null)
                {
                    imageName = GetImageName(hwnd);
                }

                if (pi.ImageName == null || pi.ImageName == imageName)
                {
                    // Check if we have a match for this entry...
                    switch (findType)
                    {
                    case ProxyScoping.ExactMatchApparentClassName:
                        factoryCallback = pi.ClientSideProviderFactoryCallback;
                        break;

                    case ProxyScoping.ExactMatchRealClassName:
                        if ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0)
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    case ProxyScoping.PartialMatchApparentClassName:
                        if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0)
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    case ProxyScoping.PartialMatchRealClassName:
                        if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0 &&
                            ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0))
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    default:
                        Debug.Assert(false, "unexpected switch() case:");
                        break;
                    }
                }
            }

            // Second part: did we get a match? If so, use the factory callback to obtain an instance...
            if (factoryCallback == null)
            {
                return(null);
            }

            // if we get an exception creating a proxy just don't create the proxy and let the UIAutomation default proxy be used
            // This will still allow the tree to be navigated  and some properties to be made availible.
            //

            try
            {
                return(factoryCallback(hwnd, idChild, idObject));
            }
            catch (Exception e)
            {
                if (Misc.IsCriticalException(e))
                {
                    throw;
                }

                return(null);
            }
        }