using System; using System.ComponentModel; using System.Drawing; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Decal.Adapter.Support; using Decal.Interop.Core; using Decal.Interop.Inject; namespace Decal.Adapter.Wrappers; [CLSCompliant(true)] public class ViewWrapper : MarshalByRefObject, IDisposable { private View myView; private ViewControls myControls; private bool isDisposed; [CLSCompliant(false)] [EditorBrowsable(EditorBrowsableState.Never)] public View Underlying => myView; public bool Activated { get { return myView.Activated; } set { myView.Activated = value; } } public int Alpha { get { return myView.Alpha; } set { myView.Alpha = value; } } public string Title { get { return myView.Title; } set { myView.Title = value; } } public bool Transparent { get { return myView.Transparent; } set { myView.Transparent = value; } } [CLSCompliant(false)] public IControl this[string controlName] { get { return ((IView)myView).get_Control(controlName); } set { ((IView)myView).set_Control(controlName, value); } } public ViewControls Controls => myControls; public Rectangle Position { get { return Util.toRectangle(myView.Position); } set { tagRECT pVal = Util.toTagRECT(value); myView.Position = ref pVal; } } internal ViewWrapper(View vw) { myView = vw; myControls = new ViewControls(this); } ~ViewWrapper() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!isDisposed) { } if (myView != null) { myControls.Dispose(); Marshal.ReleaseComObject(myView); myView = null; } isDisposed = true; } public void Activate() { myView.Activate(); } public void Alert() { myView.Alert(); } public void Deactivate() { myView.Deactivate(); } [CLSCompliant(false)] public int LoadControl(Layer parent, int id, object xmlSource) { return myView.LoadControl(parent, id, xmlSource); } public void LoadSchema(string xmlSchema) { myView.LoadSchema(xmlSchema); } public void SetIcon(int icon, object iconLibrary) { myView.SetIcon(icon, iconLibrary); } /// /// Reads the class's view attributes and loads the requested views /// /// handler to scan /// True when views are created, False otherwise internal static bool ScanViews(IViewHandler handler) { Type type = handler.GetType(); bool result = false; object[] customAttributes = type.GetCustomAttributes(typeof(ViewAttribute), inherit: false); foreach (object obj in customAttributes) { try { ViewAttribute viewAttribute = (ViewAttribute)obj; handler.LoadView(viewAttribute.ViewName, viewAttribute.Resource); result = true; } catch (Exception ex) { Util.WriteLine("ScanViews Exception: " + ex.Message); } } return result; } /// /// Reads the class for ControlEvents and hooks them up /// /// handler to scan internal static void ScanControls(IViewHandler handler) { MethodInfo[] methods = handler.GetType().GetMethods(handler.BindingFlags); foreach (MethodInfo methodInfo in methods) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(ControlEventAttribute), inherit: false); foreach (object obj in customAttributes) { try { ControlEventAttribute controlEventAttribute = (ControlEventAttribute)obj; IControlWrapper controlWrapper = handler.GetView(controlEventAttribute.ViewName).Controls[controlEventAttribute.Control]; EventInfo eventInfo = controlWrapper.GetType().GetEvent(controlEventAttribute.EventName); eventInfo.AddEventHandler(controlWrapper, Delegate.CreateDelegate(eventInfo.EventHandlerType, handler, methodInfo.Name)); } catch (Exception ex) { Util.WriteLine("ScanControls Exception: " + ex.Message); } } } } /// /// Reads the class for ControlReferences and adds them /// /// handler to scan internal static void ScanReferences(IViewHandler handler) { Type type = handler.GetType(); Type typeFromHandle = typeof(AccessedThroughPropertyAttribute); Type typeFromHandle2 = typeof(ControlReferenceAttribute); Type typeFromHandle3 = typeof(ControlReferenceArrayAttribute); FieldInfo[] fields = type.GetFields(handler.BindingFlags); foreach (FieldInfo fieldInfo in fields) { try { IControlWrapper controlWrapper = null; if (!fieldInfo.FieldType.IsArray && Attribute.IsDefined(fieldInfo, typeFromHandle2)) { ControlReferenceAttribute controlReferenceAttribute = (ControlReferenceAttribute)Attribute.GetCustomAttribute(fieldInfo, typeFromHandle2); controlWrapper = handler.GetView(controlReferenceAttribute.ViewName).Controls[controlReferenceAttribute.Control]; if (!(controlWrapper.GetType() != fieldInfo.FieldType)) { object value = Convert.ChangeType(controlWrapper, fieldInfo.FieldType); if (Attribute.IsDefined(fieldInfo, typeFromHandle)) { AccessedThroughPropertyAttribute accessedThroughPropertyAttribute = (AccessedThroughPropertyAttribute)Attribute.GetCustomAttribute(fieldInfo, typeFromHandle); type.GetProperty(accessedThroughPropertyAttribute.PropertyName, handler.BindingFlags).SetValue(handler, value, null); } else { fieldInfo.SetValue(handler, value); } } } else { if (!Attribute.IsDefined(fieldInfo, typeFromHandle3)) { continue; } ControlReferenceArrayAttribute controlReferenceArrayAttribute = (ControlReferenceArrayAttribute)Attribute.GetCustomAttribute(fieldInfo, typeFromHandle3); ViewWrapper view = handler.GetView(controlReferenceArrayAttribute.ViewName); Type elementType = fieldInfo.FieldType.GetElementType(); Array array = Array.CreateInstance(elementType, controlReferenceArrayAttribute.Controls.Count); for (int j = 0; j < controlReferenceArrayAttribute.Controls.Count; j++) { controlWrapper = view.Controls[controlReferenceArrayAttribute.Controls[j]]; if (elementType.IsAssignableFrom(controlWrapper.GetType())) { array.SetValue(controlWrapper, j); } } fieldInfo.SetValue(handler, array); continue; } } catch (Exception ex) { Util.WriteLine("ScanReferences Exception: " + ex.Message); } } } }