Beispiel #1
0
        public static IRawElementProviderFragment GetProvider(Component component,
                                                              bool initialize,
                                                              bool forceInitializeChildren)
        {
            if (component == null)
            {
                //FIXME: we should throw new ArgumentNullException ("component");
                return(null);
            }

            // First check if we've seen this component before
            IRawElementProviderFragment provider = FindProvider(component);

            if (provider != null)
            {
                return(provider);
            }

            // Send a WndProc message to see if the control
            // implements it's own provider.
            if (component is SWF.Control
                // Sending WndProc to a form is broken for some reason
                && !(component is SWF.Form))
            {
                var control = (SWF.Control)component;

                IntPtr result = SWF.NativeWindow.WndProc(
                    control.Handle,
                    SWF.Msg.WM_GETOBJECT,
                    IntPtr.Zero,
                    new IntPtr(AutomationInteropProvider.RootObjectId));

                if (result != IntPtr.Zero)
                {
                    IRawElementProviderSimple iSimpleProvider =
                        AutomationInteropProvider.RetrieveAndDeleteProvider(result);
                    provider = (iSimpleProvider as FragmentControlProvider) ?? GetWrapper(component, iSimpleProvider);
                }
            }
            else if (component is UserCustomComponent control)
            {
                provider = control.Provider;
            }

            ComponentProviderMapperHandler handler = null;
            Type providerType = null;

            if (provider == null)
            {
                Type typeIter = component.GetType();

                // Chain up the type hierarchy until we find
                // either a type or handler for mapping, or we
                // hit Control or Component.
                do
                {
                    // First see if there's a mapping handler
                    if (componentProviderMappers.TryGetValue(typeIter,
                                                             out handler))
                    {
                        break;
                    }

                    // Next, see if we have a type mapping
                    if (providerComponentMap.TryGetValue(typeIter,
                                                         out providerType))
                    {
                        break;
                    }

                    typeIter = typeIter.BaseType;
                } while (typeIter != null &&
                         typeIter != typeof(System.ComponentModel.Component) &&
                         typeIter != typeof(SWF.Control));
            }

            if (handler != null)
            {
                provider = handler(component);
            }

            // Create the provider if we found a mapping type
            if (provider == null)
            {
                // We meet a unknown custom control type,
                // then we count it as a Pane
                if (providerType == null)
                {
                    var dialog = component as SWF.CommonDialog;
                    if (dialog != null)
                    {
                        return(GetProvider(dialog.form, initialize, forceInitializeChildren));
                    }
                    providerType = typeof(PaneProvider);
                }
                try {
                    provider = (FragmentControlProvider)
                               Activator.CreateInstance(providerType,
                                                        new object [] { component });
                } catch (MissingMethodException) {
                    Log.Error(
                        "Provider {0} does not have a valid single parameter constructor to handle {1}.",
                        providerType, component.GetType()
                        );
                    return(null);
                }
            }

            if (provider != null)
            {
                // TODO: Abstract this out?
                if (component is SWF.Form)
                {
                    formProviders.Add((IRawElementProviderFragmentRoot)provider);
                }

                // TODO: Make tracking in dictionary optional
                componentProviders [component] = provider;
                if (provider is FragmentControlProvider frag)
                {
                    if (initialize)
                    {
                        frag.Initialize();
                    }
                    if (forceInitializeChildren)
                    {
                        frag.InitializeChildControlStructure();
                    }
                }
            }
            else
            {
                //FIXME: let's not throw while we are developing, a big WARNING will suffice
                //throw new NotImplementedException ("Provider not implemented for control " + component.GetType().Name);
                Log.Warn("Provider not implemented for component " + component.GetType());
                return(null);
            }

            return(provider);
        }