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)) { SWF.Control control = component as SWF.Control; IRawElementProviderSimple simpleProvider; IntPtr result; result = SWF.NativeWindow.WndProc (control.Handle, SWF.Msg.WM_GETOBJECT, IntPtr.Zero, new IntPtr (AutomationInteropProvider.RootObjectId)); if (result != IntPtr.Zero) { simpleProvider = AutomationInteropProvider .RetrieveAndDeleteProvider (result); provider = simpleProvider as IRawElementProviderFragment; if (provider == null) provider = new FragmentControlProviderWrapper (component, simpleProvider); } } 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) { FragmentControlProvider frag = (FragmentControlProvider) provider; 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; }
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)) { SWF.Control control = component as SWF.Control; IRawElementProviderSimple simpleProvider; IntPtr result; result = SWF.NativeWindow.WndProc(control.Handle, SWF.Msg.WM_GETOBJECT, IntPtr.Zero, new IntPtr(AutomationInteropProvider.RootObjectId)); if (result != IntPtr.Zero) { simpleProvider = AutomationInteropProvider .RetrieveAndDeleteProvider(result); provider = simpleProvider as IRawElementProviderFragment; if (provider == null) { provider = new FragmentControlProviderWrapper(component, simpleProvider); } } } 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) { FragmentControlProvider frag = (FragmentControlProvider)provider; 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); }