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); }