public static void Register(CustomPatternSchemaBase schema) { // For events AutomationPeers goes other way and list of events it can raise through // AutomationPeer.RaiseAutomationEvent() is very strictly hardcoded with switch() // operator in the EventMap internal class. But it is possible to get IRawElementProviderSimple // from the protected AutomationPeer.ProviderFromPeer method and use it directly via // NativeMethods.UiaRaiseAutomationEvent. Basically it is the same AutomationPeer does, // so the only inconvenience would be non-standard method of raising. // Another piece required here is to replicate for AutomationPeer.ListenersExist(). Seems to // fully support custom events we would have to rewrite EventsMap class. Fortunately it is small :) // // TODO: Add support for raising custom UIA events RegisterPattern(schema); foreach (var property in schema.Properties) RegisterProperty(property); if (schema.StandaloneProperties != null) { foreach (var uiaPropertyInfoHelper in schema.StandaloneProperties) { var automationProperty = RegisterProperty(uiaPropertyInfoHelper); RegisterStandalonePropertyGetter(automationProperty); } } }
public static void Register(CustomPatternSchemaBase schema) { // For events AutomationPeers goes other way and list of events it can raise through // AutomationPeer.RaiseAutomationEvent() is very strictly hardcoded with switch() // operator in the EventMap internal class. But it is possible to get IRawElementProviderSimple // from the protected AutomationPeer.ProviderFromPeer method and use it directly via // NativeMethods.UiaRaiseAutomationEvent. Basically it is the same AutomationPeer does, // so the only inconvenience would be non-standard method of raising. // Another piece required here is to replicate for AutomationPeer.ListenersExist(). Seems to // fully support custom events we would have to rewrite EventsMap class. Fortunately it is small :) // // TODO: Add support for raising custom UIA events RegisterPattern(schema); foreach (var property in schema.Properties) { RegisterProperty(property); } if (schema.StandaloneProperties != null) { foreach (var uiaPropertyInfoHelper in schema.StandaloneProperties) { var automationProperty = RegisterProperty(uiaPropertyInfoHelper); RegisterStandalonePropertyGetter(automationProperty); } } }
public PatternClientInstanceInterceptor(CustomPatternSchemaBase schema, IUIAutomationPatternInstance patternInstance) { _patternInstance = patternInstance; _currentPropGetterNameToHelper = schema.Properties.ToDictionary(helper => string.Format("get_Current{0}", helper.Data.pProgrammaticName)); _cachedPropGetterNameToHelper = schema.Properties.ToDictionary(helper => string.Format("get_Cached{0}", helper.Data.pProgrammaticName)); // helpers are aware about provider methods, we have to map them from client-side pattern methods _methodInfoToHelper = new Dictionary<MethodInfo, UiaMethodInfoHelper>(); foreach (var methodInfoHelper in schema.Methods) { var providerInfo = methodInfoHelper.ProviderMethodInfo; if (providerInfo == null) continue; var patternMethod = ProviderPatternMatcher.GetMatchingPatternMethod(schema.PatternClientInterface, providerInfo); if (patternMethod != null) _methodInfoToHelper[patternMethod] = methodInfoHelper; } }
public PatternClientInstanceInterceptor(CustomPatternSchemaBase schema, IUIAutomationPatternInstance patternInstance) { _patternInstance = patternInstance; _currentPropGetterNameToHelper = schema.Properties.ToDictionary(helper => string.Format("get_Current{0}", helper.Data.pProgrammaticName)); _cachedPropGetterNameToHelper = schema.Properties.ToDictionary(helper => string.Format("get_Cached{0}", helper.Data.pProgrammaticName)); // helpers are aware about provider methods, we have to map them from client-side pattern methods _methodInfoToHelper = new Dictionary <MethodInfo, UiaMethodInfoHelper>(); foreach (var methodInfoHelper in schema.Methods) { var providerInfo = methodInfoHelper.ProviderMethodInfo; if (providerInfo == null) { continue; } var patternMethod = ProviderPatternMatcher.GetMatchingPatternMethod(schema.PatternClientInterface, providerInfo); if (patternMethod != null) { _methodInfoToHelper[patternMethod] = methodInfoHelper; } } }
private static void RegisterPattern(CustomPatternSchemaBase schema) { var automationPeerType = typeof(AutomationPeer); // The only purpose of this method is to construct and correctly execute these lines of code: // // var wrapper = new Wrapper(schema.PatternProviderInterface); // var wrapObject = new AutomationPeer.WrapObject(wrapper.WrapObjectReplacer); // AutomationPeer.s_patternInfo[schema.PatternId] // = new AutomationPeer.PatternInfo(schema.PatternId, // wrapObject, // (PatternInterface)schema.PatternId); // AutomationPattern.Register(schema.PatternGuid, schema.PatternName); // // The problem here is that AutomationPeer.WrapObject, AutomationPeer.s_patternInfo, AutomationPattern.Register // and AutomationPeer.PatternInfo are not public, so we need some hardcore reflection. // Now, to be very clear, casting patternId to PatternInterface is not totally correct, // but customly registered patterns get IDs near 50000 and max PatternInterface value is // something about 20, so they won't intersect ever. On the other hand, after several hours // studying AutomationPeer sources it seems unfeasible to get what we need in other way // because AutomationPeer wasn't written with extensibility in mind. var patternInfoHashtableField = automationPeerType.GetField("s_patternInfo", BindingFlags.NonPublic | BindingFlags.Static); // from AutomationPeer.cs: private delegate object WrapObject(AutomationPeer peer, object iface); var wrapObjectDelegateType = automationPeerType.GetNestedType("WrapObject", BindingFlags.NonPublic); var wrapper = new Wrapper(schema.PatternProviderInterface); var wrapObjectReplacerMethodInfo = ReflectionUtils.GetMethodInfo(() => wrapper.WrapObjectReplacer(null, null)); var wrapObject = Delegate.CreateDelegate(wrapObjectDelegateType, wrapper, wrapObjectReplacerMethodInfo); // from AutomationPeer.cs: //private class PatternInfo //{ // internal int Id; // internal AutomationPeer.WrapObject WrapObject; // internal PatternInterface PatternInterface; // internal PatternInfo(int id, AutomationPeer.WrapObject wrapObject, PatternInterface patternInterface) // { // this.Id = id; // this.WrapObject = wrapObject; // this.PatternInterface = patternInterface; // } //} var patternInfoType = automationPeerType.GetNestedType("PatternInfo", BindingFlags.NonPublic); var patternInfoTypeCtor = patternInfoType.GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, binder: null, types: new[] { typeof(int), wrapObjectDelegateType, typeof(PatternInterface) }, modifiers: null); var patternInfo = patternInfoTypeCtor.Invoke(new object[] { schema.PatternId, wrapObject, (PatternInterface)schema.PatternId }); var automationPatternType = typeof(AutomationPattern); var registerMethod = automationPatternType.GetMethod("Register", BindingFlags.NonPublic | BindingFlags.Static); using (Dispatcher.CurrentDispatcher.DisableProcessing()) { var patternInfoHashtable = (Hashtable)patternInfoHashtableField.GetValue(null); if (patternInfoHashtable.Contains(schema.PatternId)) { return; } patternInfoHashtable[schema.PatternId] = patternInfo; registerMethod.Invoke(null, new object[] { schema.PatternGuid, schema.PatternName }); } }
private static void RegisterPattern(CustomPatternSchemaBase schema) { var automationPeerType = typeof(AutomationPeer); // The only purpose of this method is to construct and correctly execute these lines of code: // // var wrapper = new Wrapper(schema.PatternProviderInterface); // var wrapObject = new AutomationPeer.WrapObject(wrapper.WrapObjectReplacer); // AutomationPeer.s_patternInfo[schema.PatternId] // = new AutomationPeer.PatternInfo(schema.PatternId, // wrapObject, // (PatternInterface)schema.PatternId); // AutomationPattern.Register(schema.PatternGuid, schema.PatternName); // // The problem here is that AutomationPeer.WrapObject, AutomationPeer.s_patternInfo, AutomationPattern.Register // and AutomationPeer.PatternInfo are not public, so we need some hardcore reflection. // Now, to be very clear, casting patternId to PatternInterface is not totally correct, // but customly registered patterns get IDs near 50000 and max PatternInterface value is // something about 20, so they won't intersect ever. On the other hand, after several hours // studying AutomationPeer sources it seems unfeasible to get what we need in other way // because AutomationPeer wasn't written with extensibility in mind. var patternInfoHashtableField = automationPeerType.GetField("s_patternInfo", BindingFlags.NonPublic | BindingFlags.Static); // from AutomationPeer.cs: private delegate object WrapObject(AutomationPeer peer, object iface); var wrapObjectDelegateType = automationPeerType.GetNestedType("WrapObject", BindingFlags.NonPublic); var wrapper = new Wrapper(schema.PatternProviderInterface); var wrapObjectReplacerMethodInfo = ReflectionUtils.GetMethodInfo(() => wrapper.WrapObjectReplacer(null, null)); var wrapObject = Delegate.CreateDelegate(wrapObjectDelegateType, wrapper, wrapObjectReplacerMethodInfo); // from AutomationPeer.cs: //private class PatternInfo //{ // internal int Id; // internal AutomationPeer.WrapObject WrapObject; // internal PatternInterface PatternInterface; // internal PatternInfo(int id, AutomationPeer.WrapObject wrapObject, PatternInterface patternInterface) // { // this.Id = id; // this.WrapObject = wrapObject; // this.PatternInterface = patternInterface; // } //} var patternInfoType = automationPeerType.GetNestedType("PatternInfo", BindingFlags.NonPublic); var patternInfoTypeCtor = patternInfoType.GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, binder: null, types: new[] {typeof(int), wrapObjectDelegateType, typeof(PatternInterface)}, modifiers: null); var patternInfo = patternInfoTypeCtor.Invoke(new object[] {schema.PatternId, wrapObject, (PatternInterface)schema.PatternId}); var automationPatternType = typeof(AutomationPattern); var registerMethod = automationPatternType.GetMethod("Register", BindingFlags.NonPublic | BindingFlags.Static); using (Dispatcher.CurrentDispatcher.DisableProcessing()) { var patternInfoHashtable = (Hashtable)patternInfoHashtableField.GetValue(null); if (patternInfoHashtable.Contains(schema.PatternId)) return; patternInfoHashtable[schema.PatternId] = patternInfo; registerMethod.Invoke(null, new object[] {schema.PatternGuid, schema.PatternName}); } }
public AttributeDrivenPatternHandler(CustomPatternSchemaBase schema) { _schema = schema; }
public AttributeDrivenPatternHandler(CustomPatternSchemaBase schema) { _schema = schema; }