AxHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / AxHost.cs / 2 / AxHost.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Windows.Forms {
    using Microsoft.Win32; 
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized; 
    using System.ComponentModel;
    using System.ComponentModel.Design; 
    using System.Configuration.Assemblies; 
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Drawing.Design;
    using System.Globalization; 
    using System.IO;
    using System.Reflection; 
    using System.Runtime.InteropServices; 
    using System.Runtime.Remoting;
    using System.Runtime.Serialization.Formatters.Binary; 
    using System.Runtime.Serialization;
    using System.Security;
    using System.Security.Permissions;
    using System.Threading; 
    using System.Windows.Forms.ComponentModel;
    using System.Windows.Forms.ComponentModel.Com2Interop; 
    using System.Windows.Forms.Design; 

 
    /// 
    /// 
    ///    
    /// 
    ///       Wraps ActiveX controls and exposes them as
    ///       fully featured windows forms controls. 
    ///     
    /// 
    [ 
    ComVisible(true),
    ClassInterface(ClassInterfaceType.AutoDispatch),
    ToolboxItem(false),
    DesignTimeVisible(false), 
    DefaultEvent("Enter"),
    Designer("System.Windows.Forms.Design.AxHostDesigner, " + AssemblyRef.SystemDesign), 
    PermissionSet(SecurityAction.LinkDemand, Name="FullTrust"), 
    PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")
    ] 
    public abstract class AxHost : Control, ISupportInitialize, ICustomTypeDescriptor {

        private static TraceSwitch AxHTraceSwitch     = new TraceSwitch("AxHTrace", "ActiveX handle tracing");
        private static TraceSwitch AxPropTraceSwitch  = new TraceSwitch("AxPropTrace", "ActiveX property tracing"); 
        private static TraceSwitch AxHostSwitch       = new TraceSwitch("AxHost", "ActiveX host creation");
        private static BooleanSwitch AxIgnoreTMSwitch = new BooleanSwitch("AxIgnoreTM", "ActiveX switch to ignore thread models"); 
        private static BooleanSwitch AxAlwaysSaveSwitch = new BooleanSwitch("AxAlwaysSave", "ActiveX to save all controls regardless of their IsDirty function return value"); 

        ///  
        ///     Flags which may be passed to the AxHost constructor
        /// 
        [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
        internal class AxFlags { 
            /// 
            ///     Indicates that the context menu for the control should not contain an 
            ///     "Edit" verb unless the activeX controls itself decides to proffer it. 
            ///     By default, all wrapped activeX controls will contain an edit verb.
            ///  
            internal const int PreventEditMode  = 0x1;

            /// 
            ///     Indicated that the context menu for the control should contain 
            ///     a "Properties..." verb which may be used to show the property
            ///     pages for the control.  Note that even if this flag is 
            ///     specified, the verb will not appear unless the control 
            ///     proffers a set of property pages.
            ///     [Since most activeX controls alreay have their own properties verb 
            ///     on the context menu, the default is not to include one specified by
            ///     this flag.]
            /// 
            internal const int IncludePropertiesVerb = 0x2; 

            ///  
            ///  
            /// 
            internal const int IgnoreThreadModel     = 0x10000000; 
        }

        private static COMException E_NOTIMPL = new COMException(SR.GetString(SR.AXNotImplemented), unchecked((int)0x80000001));
        private static COMException E_INVALIDARG = new COMException(SR.GetString(SR.AXInvalidArgument), unchecked((int)0x80070057)); 
        private static COMException E_FAIL   = new COMException(SR.GetString(SR.AXUnknownError), unchecked((int)0x80004005));
        private static COMException E_NOINTERFACE = new COMException(SR.GetString(SR.AxInterfaceNotSupported), unchecked((int)0x80004002)); 
 
        private const int INPROC_SERVER = 1;
        private const int OC_PASSIVE = 0; 
        private const int OC_LOADED = 1;  // handler, but no server   [ocx created]
        private const int OC_RUNNING = 2; // server running, invisible [iqa & depersistance]
        private const int OC_INPLACE = 4; // server in-place active [inplace]
        private const int OC_UIACTIVE = 8;// server is UI active [uiactive] 
        private const int OC_OPEN = 16;    // server is being open edited [not used]
 
        private const int EDITM_NONE = 0;   // object not being edited 
        private const int EDITM_OBJECT = 1; // object provided an edit verb and we invoked it
        private const int EDITM_HOST = 2;   // we invoked our own edit verb 

        private const int STG_UNKNOWN = -1;
        private const int STG_STREAM = 0;
        private const int STG_STREAMINIT = 1; 
        private const int STG_STORAGE = 2;
 
        private const int OLEIVERB_SHOW = -1; 
        private const int OLEIVERB_HIDE = -3;
        private const int OLEIVERB_UIACTIVATE = -4; 
        private const int OLEIVERB_INPLACEACTIVATE =-5;
        private const int OLEIVERB_PROPERTIES = -7;
        private const int OLEIVERB_PRIMARY = 0;
 
        private readonly int REGMSG_MSG = SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion + "_subclassCheck");
        private const int REGMSG_RETVAL = 123; 
 
        private static int logPixelsX = -1;
        private static int logPixelsY = -1; 

        private static Guid   icf2_Guid                = typeof(UnsafeNativeMethods.IClassFactory2).GUID;
        private static Guid   ifont_Guid               = typeof(UnsafeNativeMethods.IFont).GUID;
        private static Guid   ifontDisp_Guid           = typeof(SafeNativeMethods.IFontDisp).GUID; 
        private static Guid   ipicture_Guid            = typeof(UnsafeNativeMethods.IPicture).GUID;
        private static Guid   ipictureDisp_Guid        = typeof(UnsafeNativeMethods.IPictureDisp).GUID; 
        private static Guid   ivbformat_Guid           = typeof(UnsafeNativeMethods.IVBFormat).GUID; 
        private static Guid   ioleobject_Guid          = typeof(UnsafeNativeMethods.IOleObject).GUID;
        private static Guid   dataSource_Guid          = new Guid("{7C0FFAB3-CD84-11D0-949A-00A0C91110ED}"); 
        private static Guid   windowsMediaPlayer_Clsid = new Guid("{22d6f312-b0f6-11d0-94ab-0080c74c7e95}");
        private static Guid   comctlImageCombo_Clsid   = new Guid("{a98a24c0-b06f-3684-8c12-c52ae341e0bc}");
        private static Guid   maskEdit_Clsid           = new Guid("{c932ba85-4374-101b-a56c-00aa003668dc}");
 
        // Static state for perf optimization
        // 
        private static Hashtable fontTable; 

        // BitVector32 masks for various internal state flags. 
        //
        private static readonly int     ocxStateSet = BitVector32.CreateMask();
        private static readonly int     editorRefresh = BitVector32.CreateMask(ocxStateSet);
        private static readonly int     listeningToIdle = BitVector32.CreateMask(editorRefresh); 
        private static readonly int     refreshProperties = BitVector32.CreateMask(listeningToIdle);
 
        private static readonly int     checkedIppb = BitVector32.CreateMask(refreshProperties); 
        private static readonly int     checkedCP = BitVector32.CreateMask(checkedIppb);
        private static readonly int     fNeedOwnWindow = BitVector32.CreateMask(checkedCP); 
        private static readonly int     fOwnWindow = BitVector32.CreateMask(fNeedOwnWindow);

        private static readonly int     fSimpleFrame = BitVector32.CreateMask(fOwnWindow);
        private static readonly int     fFakingWindow = BitVector32.CreateMask(fSimpleFrame); 
        private static readonly int     rejectSelection = BitVector32.CreateMask(fFakingWindow);
        private static readonly int     ownDisposing = BitVector32.CreateMask(rejectSelection); 
 
        private static readonly int     sinkAttached = BitVector32.CreateMask(ownDisposing);
        private static readonly int     disposed = BitVector32.CreateMask(sinkAttached); 
        private static readonly int     manualUpdate = BitVector32.CreateMask(disposed);
        private static readonly int     addedSelectionHandler = BitVector32.CreateMask(manualUpdate);

        private static readonly int     valueChanged = BitVector32.CreateMask(addedSelectionHandler); 
        private static readonly int     handlePosRectChanged = BitVector32.CreateMask(valueChanged);
        private static readonly int     siteProcessedInputKey = BitVector32.CreateMask(handlePosRectChanged); 
        private static readonly int     needLicenseKey = BitVector32.CreateMask(siteProcessedInputKey); 

        private static readonly int     inTransition = BitVector32.CreateMask(needLicenseKey); 
        private static readonly int     processingKeyUp = BitVector32.CreateMask(inTransition);
        private static readonly int     assignUniqueID = BitVector32.CreateMask(processingKeyUp);
        private static readonly int     renameEventHooked  = BitVector32.CreateMask(assignUniqueID);
 

        private BitVector32 axState = new BitVector32(); 
 
        private int storageType = STG_UNKNOWN;
        private int ocState = OC_PASSIVE; 
        private int miscStatusBits;
        private int freezeCount = 0;
        private int flags = 0;
        private int selectionStyle = 0; 
        private int editMode = EDITM_NONE;
        private int noComponentChange = 0; 
 
        private IntPtr wndprocAddr = IntPtr.Zero;
 
        private Guid   clsid;
        private string text = "";
        private string licenseKey = null;
 
        private readonly OleInterfaces oleSite;
        private AxComponentEditor editor; 
        private AxContainer container; 
        private ContainerControl containingControl;
        private ContainerControl newParent; 
        private AxContainer axContainer;
        private State ocxState;
        private IntPtr hwndFocus = IntPtr.Zero;
 
        // CustomTypeDescriptor related state
        // 
        private Hashtable properties = null; 
        private Hashtable propertyInfos = null;
        private PropertyDescriptorCollection propsStash = null; 
        private Attribute[] attribsStash = null;

        // interface pointers to the ocx
        // 
        private Object instance;
        private UnsafeNativeMethods.IOleInPlaceObject iOleInPlaceObject; 
        private UnsafeNativeMethods.IOleObject iOleObject; 
        private UnsafeNativeMethods.IOleControl iOleControl;
        private UnsafeNativeMethods.IOleInPlaceActiveObject iOleInPlaceActiveObject; 
        private UnsafeNativeMethods.IOleInPlaceActiveObject iOleInPlaceActiveObjectExternal;
        private NativeMethods.IPerPropertyBrowsing iPerPropertyBrowsing;
        private NativeMethods.ICategorizeProperties iCategorizeProperties;
        private UnsafeNativeMethods.IPersistPropertyBag iPersistPropBag; 
        private UnsafeNativeMethods.IPersistStream iPersistStream;
        private UnsafeNativeMethods.IPersistStreamInit iPersistStreamInit; 
        private UnsafeNativeMethods.IPersistStorage iPersistStorage; 

        private AboutBoxDelegate aboutBoxDelegate = null; 
        private EventHandler selectionChangeHandler;

        private bool isMaskEdit;
        private bool ignoreDialogKeys; 

        private EventHandler onContainerVisibleChanged; 
 
        // These should be in the order given by the PROPCAT_X values
        // Also, note that they are not to be localized... 

        private static CategoryAttribute[] categoryNames = new CategoryAttribute [] {
            null,
            new WinCategoryAttribute("Default"), 
            new WinCategoryAttribute("Default"),
            new WinCategoryAttribute("Font"), 
            new WinCategoryAttribute("Layout"), 
            new WinCategoryAttribute("Appearance"),
            new WinCategoryAttribute("Behavior"), 
            new WinCategoryAttribute("Data"),
            new WinCategoryAttribute("List"),
            new WinCategoryAttribute("Text"),
            new WinCategoryAttribute("Scale"), 
            new WinCategoryAttribute("DDE")
        }; 
 
        private Hashtable objectDefinedCategoryNames = null; // Integer -> String
 
#if DEBUG
        static AxHost() {
            Debug.Assert((int)DockStyle.None == (int)NativeMethods.ActiveX.ALIGN_NO_CHANGE,"align value mismatch");
            Debug.Assert((int)DockStyle.Top == (int)NativeMethods.ActiveX.ALIGN_TOP,"align value mismatch"); 
            Debug.Assert((int)DockStyle.Bottom == (int)NativeMethods.ActiveX.ALIGN_BOTTOM,"align value mismatch");
            Debug.Assert((int)DockStyle.Left == (int)NativeMethods.ActiveX.ALIGN_LEFT,"align value mismatch"); 
            Debug.Assert((int)DockStyle.Right == (int)NativeMethods.ActiveX.ALIGN_RIGHT,"align value mismatch"); 
            Debug.Assert((int)MouseButtons.Left == 0x00100000, "mb.left mismatch");
            Debug.Assert((int)MouseButtons.Right == 0x00200000, "mb.right mismatch"); 
            Debug.Assert((int)MouseButtons.Middle == 0x00400000, "mb.middle mismatch");
            Debug.Assert((int)Keys.Shift == 0x00010000, "key.shift mismatch");
            Debug.Assert((int)Keys.Control == 0x00020000, "key.control mismatch");
            Debug.Assert((int)Keys.Alt == 0x00040000, "key.alt mismatch"); 
        }
#endif 
 
        /// 
        ///  
        ///     Creates a new instance of a control which wraps an activeX control given by the
        ///     clsid parameter and flags of 0.
        /// 
        protected AxHost(string clsid) : this(clsid, 0) { 
        }
 
        ///  
        /// 
        ///    Creates a new instance of a control which wraps an activeX control given by the 
        ///       clsid and flags parameters.
        /// 
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected AxHost(string clsid, int flags) : base() { 
            if (Application.OleRequired() != ApartmentState.STA) {
                throw new ThreadStateException(SR.GetString(SR.AXMTAThread, clsid)); 
            } 

            this.oleSite = new OleInterfaces(this); 
            this.selectionChangeHandler = new EventHandler(this.OnNewSelection);
            this.clsid = new Guid(clsid);
            this.flags = flags;
 
            this.axState[assignUniqueID] = !this.GetType().GUID.Equals(comctlImageCombo_Clsid);
            this.axState[needLicenseKey] = true; 
            this.axState[rejectSelection] = true; 

            isMaskEdit = this.clsid.Equals(AxHost.maskEdit_Clsid); 
            this.onContainerVisibleChanged = new EventHandler(this.OnContainerVisibleChanged);
        }

        private bool CanUIActivate { 
            get {
                return IsUserMode() || editMode != EDITM_NONE; 
            } 
        }
 
        /// 
        /// 
        ///     Returns the CreateParams used to create the handle for this control.
        ///  
        protected override CreateParams CreateParams {
            get { 
                CreateParams cp = base.CreateParams; 
                if (axState[fOwnWindow] && IsUserMode()) {
                    cp.Style = cp.Style & (~NativeMethods.WS_VISIBLE); 
                }
                return cp;
            }
        } 

        private bool GetAxState(int mask) { 
            return this.axState[mask]; 
        }
 
        private void SetAxState(int mask, bool value) {
            this.axState[mask] = value;
        }
 
        /// 
        ///  
        ///     AxHost will call this when it is ready to create the underlying ActiveX object. 
        ///     Wrappers will override this and cast the pointer obtained by calling getOcx() to
        ///     their own interfaces.  getOcx() should not usually be called before this function. 
        ///     Note: calling begin will result in a call to this function.
        /// 
        protected virtual void AttachInterfaces() {
        } 

        private void RealizeStyles() { 
            SetStyle(ControlStyles.UserPaint, false); 
            int bits = 0;
            int hr = GetOleObject().GetMiscStatus(NativeMethods.ActiveX.DVASPECT_CONTENT, out bits); 
            if (!NativeMethods.Failed(hr)) {
                miscStatusBits = bits;
                ParseMiscBits(miscStatusBits);
            } 
        }
 
        // Control overrides: 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public override Color BackColor {
            get { 
                return base.BackColor; 
            }
 
            set {
                base.BackColor = value;
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage {
            get { 
                return base.BackgroundImage;
            } 
 
            set {
                base.BackgroundImage = value; 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public override ImageLayout BackgroundImageLayout {
            get {
                return base.BackgroundImageLayout;
            } 

            set { 
                base.BackgroundImageLayout = value; 
            }
        } 

        /// 
        ///     Hide ImeMode: it doesn't make sense for this control
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        new public ImeMode ImeMode 
        {
            get 
            {
                return base.ImeMode;
            }
            set 
            {
                base.ImeMode = value; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler MouseClick { 
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseClick"));
            } 
            remove {
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler MouseDoubleClick {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseDoubleClick"));
            } 
            remove {
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public override Cursor Cursor {
            get { 
                return base.Cursor; 
            }
 
            set {
                base.Cursor = value;
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override ContextMenu ContextMenu {
            get {
                return base.ContextMenu; 
            }
 
            set { 
                base.ContextMenu = value;
            } 
        }

        /// 
        ///  
        ///     Deriving classes can override this to configure a default size for their control.
        ///     This is more efficient than setting the size in the control's constructor. 
        ///  
        protected override Size DefaultSize {
            get { 
                return new Size(75, 23);
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public virtual new bool Enabled {
            get {
                return base.Enabled;
            } 

            set { 
                base.Enabled = value; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public override Font Font { 
            get {
                return base.Font; 
            }

            set {
                base.Font = value; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Color ForeColor { 
            get {
                return base.ForeColor; 
            } 

            set { 
                base.ForeColor = value;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [ 
            Browsable(false),
            EditorBrowsable(EditorBrowsableState.Never),
            Localizable(true)
        ] 
        public new virtual bool RightToLeft {
            get { 
                RightToLeft rtol = base.RightToLeft; 
                return rtol == System.Windows.Forms.RightToLeft.Yes;
            } 

            set {
                base.RightToLeft = (value) ? System.Windows.Forms.RightToLeft.Yes : System.Windows.Forms.RightToLeft.No;
            } 
        }
 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override string Text { 
            get {
                return text; 
            } 

            set { 
                text = value;
            }
        }
 
        internal override bool CanAccessProperties {
            get { 
                int ocState = GetOcState(); 
                return(axState[fOwnWindow] &&
                       (ocState > OC_RUNNING || (IsUserMode() && ocState >= OC_RUNNING)) || 
                       ocState >= OC_INPLACE);
            }
        }
 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected bool PropsValid() { 
            return CanAccessProperties;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        public void BeginInit() { 
        }
 
        /// 
        /// 
        ///     Signals the object that loading of all peer components and property
        ///     sets are complete. 
        ///     It should be possible to invoke any property get or set after calling this method.
        ///     Note that a sideeffect of this method is the creation of the parent control's 
        ///     handle, therefore, this control must be parented before begin is called 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        public void EndInit() {
            if (ParentInternal != null) {
                ParentInternal.CreateControl(true);
 
                ContainerControl f = ContainingControl;
                if (f != null) { 
                    f.VisibleChanged += this.onContainerVisibleChanged; 
                }
            } 
        }

        private void OnContainerVisibleChanged(object sender, EventArgs e) {
            ContainerControl f = ContainingControl; 
            if (f != null) {
                if (f.Visible && Visible && !axState[fOwnWindow]) { 
                    MakeVisibleWithShow(); 
                }
                else if (!f.Visible && Visible && IsHandleCreated && GetOcState() >= OC_INPLACE) { 
                    HideAxControl();
                }
                else if (f.Visible && !GetState(STATE_VISIBLE) && IsHandleCreated && GetOcState() >= OC_INPLACE) {
                    HideAxControl(); 
                }
            } 
        } 

        // 
        /// 
        /// 
        ///      Determines if the control is in edit mode.
        ///  
        [   Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public bool EditMode {
            get { 
                return editMode != EDITM_NONE;
            }
        }
 
        /// 
        ///  
        ///      Determines if this control has an about box. 
        /// 
        [   Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), 
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool HasAboutBox {
            get { 
                return aboutBoxDelegate != null;
            } 
        } 

        private int NoComponentChangeEvents { 
            get {
                return noComponentChange;
            }
 
            set {
                noComponentChange = value; 
            } 
        }
 
        //
        /// 
        /// 
        ///      Shows the about box for this control. 
        /// 
        public void ShowAboutBox() { 
            if (aboutBoxDelegate != null) { 
                aboutBoxDelegate();
            } 
        }

        //
        ///  
        ///      Retrieves the OCX control flags.
        ///  
#if false 
        // FxCop: Currently not used
        [   Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), 
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        private int OcxFlags {
            get { 
                return flags;
            } 
        } 
#endif
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackColorChanged { 
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "BackColorChanged"));
            } 
            remove {
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler BackgroundImageChanged {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "BackgroundImageChanged"));
            } 
            remove {
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler BackgroundImageLayoutChanged {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "BackgroundImageLayoutChanged")); 
            }
            remove { 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BindingContextChanged { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "BindingContextChanged"));
            }
            remove { 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler ContextMenuChanged { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "ContextMenuChanged")); 
            } 
            remove {
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler CursorChanged {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "CursorChanged"));
            }
            remove {
            } 
        }
 
        ///  
        /// 
        ///    Occurs when the control is enabled. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler EnabledChanged {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "EnabledChanged"));
            } 
            remove { 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler FontChanged { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "FontChanged")); 
            }
            remove {
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler ForeColorChanged {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "ForeColorChanged")); 
            }
            remove { 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler RightToLeftChanged { 
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "RightToLeftChanged"));
            } 
            remove {
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler TextChanged {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "TextChanged"));
            } 
            remove {
            } 
        } 

        ///  
        /// 
        ///    Occurs when the control is clicked.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler Click {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "Click")); 
            }
            remove { 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event DragEventHandler DragDrop { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "DragDrop"));
            }
            remove { 
            }
        } 
 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event DragEventHandler DragEnter {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "DragEnter")); 
            }
            remove { 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event DragEventHandler DragOver { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "DragOver"));
            }
            remove { 
            }
        } 
 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler DragLeave {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "DragLeave")); 
            }
            remove { 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event GiveFeedbackEventHandler GiveFeedback { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "GiveFeedback"));
            }
            remove { 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event HelpEventHandler HelpRequested { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "HelpRequested")); 
            } 
            remove {
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event PaintEventHandler Paint {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "Paint"));
            }
            remove {
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event QueryContinueDragEventHandler QueryContinueDrag {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "QueryContinueDrag"));
            } 
            remove { 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "QueryAccessibilityHelp")); 
            }
            remove {
            }
        } 

        ///  
        ///  
        ///    Occurs when the control is double clicked.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler DoubleClick {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "DoubleClick")); 
            }
            remove { 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler ImeModeChanged { 
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "ImeModeChanged"));
            } 
            remove {
            }
        }
 

        ///  
        ///  
        ///    Occurs when a key is pressed down while the control has focus.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event KeyEventHandler KeyDown {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "KeyDown")); 
            }
            remove { 
            } 
        }
 

        /// 
        /// 
        ///     Occurs when a key is pressed while the control has focus. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event KeyPressEventHandler KeyPress { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "KeyPress")); 
            }
            remove {
            }
        } 

 
        ///  
        /// 
        ///     Occurs when a key is released while the control has focus. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event KeyEventHandler KeyUp {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "KeyUp"));
            } 
            remove { 
            }
        } 


        /// 
        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event LayoutEventHandler Layout { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "Layout")); 
            }
            remove {
            }
        } 

        ///  
        ///  
        ///    Occurs when the mouse pointer is over the control and a mouse button is
        ///       pressed. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event MouseEventHandler MouseDown {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseDown"));
            } 
            remove { 
            }
        } 

        /// 
        /// 
        ///     Occurs when the mouse pointer enters the AxHost. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler MouseEnter { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseEnter")); 
            }
            remove {
            }
        } 

        ///  
        ///  
        ///     Occurs when the mouse pointer leaves the AxHost.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler MouseLeave {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseLeave")); 
            }
            remove { 
            } 
        }
 
        /// 
        /// 
        ///     Occurs when the mouse pointer hovers over the contro.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler MouseHover { 
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseHover"));
            } 
            remove {
            }
        }
 
        /// 
        ///  
        ///     Occurs when the mouse pointer is moved over the AxHost. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event MouseEventHandler MouseMove {
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseMove"));
            } 
            remove {
            } 
        } 

        ///  
        /// 
        ///    Occurs when the mouse pointer is over the control and a mouse button is released.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event MouseEventHandler MouseUp {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseUp")); 
            }
            remove { 
            }
        }

        ///  
        /// 
        ///     Occurs when the mouse wheel moves while the control has focus. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event MouseEventHandler MouseWheel { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "MouseWheel"));
            }
            remove { 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event UICuesEventHandler ChangeUICues { 
            add {
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "ChangeUICues")); 
            } 
            remove {
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler StyleChanged {
            add { 
                throw new NotSupportedException(SR.GetString(SR.AXAddInvalidEvent, "StyleChanged"));
            }
            remove {
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void OnFontChanged(EventArgs e) {
            base.OnFontChanged(e);
            AmbientChanged(NativeMethods.ActiveX.DISPID_AMBIENT_FONT); 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void OnForeColorChanged(EventArgs e) {
            base.OnForeColorChanged(e);
            AmbientChanged(NativeMethods.ActiveX.DISPID_AMBIENT_FORECOLOR); 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void OnBackColorChanged(EventArgs e) {
            base.OnBackColorChanged(e);
            AmbientChanged(NativeMethods.ActiveX.DISPID_AMBIENT_BACKCOLOR); 
        }
 
        private void AmbientChanged(int dispid) { 
            if (GetOcx() != null) {
                try { 
                    Invalidate();
                    GetOleControl().OnAmbientPropertyChange(dispid);
                }
                catch (Exception t) { 
                    Debug.Fail(t.ToString());
                } 
            } 
        }
 
        private bool OwnWindow() {
            return axState[fOwnWindow] || axState[fFakingWindow];
        }
 
        private IntPtr GetHandleNoCreate() {
            if (IsHandleCreated) return Handle; 
            return IntPtr.Zero; 
        }
 
        private ISelectionService GetSelectionService() {
            return GetSelectionService(this);
        }
 
        private static ISelectionService GetSelectionService(Control ctl) {
            ISite site = ctl.Site; 
            if (site != null) { 
                Object o = site.GetService(typeof(ISelectionService));
                Debug.Assert(o == null || o is ISelectionService, "service must implement ISelectionService"); 
                //Note: if o is null, we want to return null anyway.  Happy day.
                return o as ISelectionService;
            }
            return null; 
        }
 
        private void AddSelectionHandler() { 
            if (axState[addedSelectionHandler]) return;
            ISelectionService iss = GetSelectionService(); 
            if (iss != null) {
                iss.SelectionChanging += selectionChangeHandler;
            }
            axState[addedSelectionHandler] = true; 
        }
 
        private void OnComponentRename(object sender, ComponentRenameEventArgs e) 
        {
            // When we're notified of a rename, see if this is the componnent that is being 
            // renamed.
            //
            if (e.Component == this)
            { 
                // if it is, call DISPID_AMBIENT_DISPLAYNAME directly on the
                // control itself. 
                // 
                UnsafeNativeMethods.IOleControl oleCtl = this.GetOcx() as UnsafeNativeMethods.IOleControl;
                if (oleCtl != null) 
                {
                    oleCtl.OnAmbientPropertyChange(NativeMethods.ActiveX.DISPID_AMBIENT_DISPLAYNAME);
                }
            } 
        }
 
 
        private bool RemoveSelectionHandler() {
            if (!axState[addedSelectionHandler]) return false; 
            ISelectionService iss = GetSelectionService();
            if (iss != null) {
                iss.SelectionChanging -= selectionChangeHandler;
            } 
            axState[addedSelectionHandler] = false;
            return true; 
        } 

        private void SyncRenameNotification(bool hook) { 
            if (DesignMode && hook != axState[renameEventHooked])
            {
                // if we're in design mode, listen to the following events from the component change service
                // 
                IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
 
                if (changeService != null) 
                {
                    if (hook) { 
                        changeService.ComponentRename += new ComponentRenameEventHandler(OnComponentRename);
                    }
                    else {
                        changeService.ComponentRename -= new ComponentRenameEventHandler(OnComponentRename); 
                    }
                    axState[renameEventHooked] = hook; 
                } 
            }
        } 

        /// 
        /// 
        ///     Sets the site of this component. A non-null value indicates that the 
        ///     component has been added to a container, and a null value indicates that
        ///     the component is being removed from a container. 
        ///  
        public override ISite Site {
            set { 
                // If we are disposed then just return.
                if (axState[disposed])
                {
                    return; 
                }
                bool reAddHandler = RemoveSelectionHandler(); 
                bool olduMode = IsUserMode(); 

                // clear the old hook 
                //
                SyncRenameNotification(false);

                base.Site = value; 
                bool newuMode = IsUserMode();
                if (!newuMode) GetOcxCreate(); 
                if (reAddHandler) AddSelectionHandler(); 

                SyncRenameNotification(value != null); 

                // For inherited forms we create the OCX first in User mode
                // and then we get sited. At that time, we have to re-activate
                // the OCX by transitioning down to and up to the current state. 
                //
                if (value != null && !newuMode && olduMode != newuMode && GetOcState() > OC_LOADED) { 
                    TransitionDownTo(OC_LOADED); 
                    TransitionUpTo(OC_INPLACE);
                    ContainerControl f = ContainingControl; 
                    if (f != null && f.Visible && Visible)
                        MakeVisibleWithShow();
                }
 
                if (olduMode != newuMode && !IsHandleCreated && !axState[disposed]) {
                    if (GetOcx() != null) { 
                        RealizeStyles(); 
                    }
                } 
                if (!newuMode) {
                    //SetupClass_Info(this);
                }
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected override void OnLostFocus(EventArgs e) {
            // ASURT 93669 
            // Office WebControl and MS DDS control create a child window that gains
            // focus in order to handle keyboard input. Since, UIDeactivate() could 
            // destroy that window, these controls will crash trying to process WM_CHAR. 
            // We now check to see if we are losing focus to a child, and if so, not call
            // UIDeactivate(). 
            //

            bool uiDeactivate = (GetHandleNoCreate() != hwndFocus);
 
            if (uiDeactivate && IsHandleCreated) {
                uiDeactivate = !UnsafeNativeMethods.IsChild(new HandleRef(this, GetHandleNoCreate()), new HandleRef(null, hwndFocus)); 
            } 

            base.OnLostFocus(e); 
            if (uiDeactivate) {
                UiDeactivate();
            }
 
        }
 
        private void OnNewSelection(Object sender, EventArgs e) { 
            if (IsUserMode()) return;
            ISelectionService iss = GetSelectionService(); 
            // What we care about:
            // if we are uiactive and we lose selection, then we need to uideactivate ourselves...
            if (iss != null) {
                if (GetOcState() >= OC_UIACTIVE && !iss.GetComponentSelected(this)) { 
                    // need to deactivate...
                    int hr = UiDeactivate(); 
                    if (NativeMethods.Failed(hr)) { 
                        // not much we can do here...
                        Debug.Fail("Failed to UiDeactivate: " + hr.ToString(CultureInfo.InvariantCulture)); 
                    }
                }
                if (!iss.GetComponentSelected(this)) {
                    if (editMode != EDITM_NONE) { 
                        GetParentContainer().OnExitEditMode(this);
                        editMode = EDITM_NONE; 
                    } 
                    // need to exit edit mode...
                    SetSelectionStyle(1); 
                    RemoveSelectionHandler();
                }
                else {
                    // The AX Host designer will offer an extender property called "SelectionStyle" 
                    //
                    PropertyDescriptor prop = TypeDescriptor.GetProperties(this)["SelectionStyle"]; 
 
                    if (prop != null && prop.PropertyType == typeof(int)) {
                        int curSelectionStyle = (int)prop.GetValue(this); 
                        if (curSelectionStyle != this.selectionStyle) {
                            prop.SetValue(this, selectionStyle);
                        }
                    } 
                }
            } 
        } 

        //DrawToBitmap doesn't work for this control, so we should hide it.  We'll 
        //still call base so that this has a chance to work if it can.
        [EditorBrowsable(EditorBrowsableState.Never)]
        new public void DrawToBitmap(Bitmap bitmap, Rectangle targetBounds)
        { 
            base.DrawToBitmap(bitmap, targetBounds);
        } 
 
        /// 
        ///  
        ///     Creates a handle for this control. This method is called by the .NET framework, this should
        ///     not be called.
        /// 
        protected override void CreateHandle() { 
            if (!IsHandleCreated) {
 
                TransitionUpTo(OC_RUNNING); 
                if (!axState[fOwnWindow]) {
                    if (axState[fNeedOwnWindow]) { 
                        Debug.Assert(!Visible, "if we were visible we would not be needing a fake window...");
                        axState[fNeedOwnWindow] = false;
                        axState[fFakingWindow] = true;
                        base.CreateHandle(); 
                        // note that we do not need to attach the handle because the work usually done in there
                        // will be done in Control's wndProc on WM_CREATE... 
                    } 
                    else {
                        TransitionUpTo(OC_INPLACE); 
                        // it is possible that we were hidden while in place activating, in which case we don't
                        // really have a handle now because the act of hiding could have destroyed it
                        // so, just call ourselves again recursively, and if we dont't have a handle, we will
                        // just take the "axState[fNeedOwnWindow]" path above... 
                        if (axState[fNeedOwnWindow]) {
                            Debug.Assert(!IsHandleCreated, "if we need a fake window, we can't have a real one"); 
                            CreateHandle(); 
                            return;
                        } 
                    }
                }
                else {
                    SetState(STATE_VISIBLE, false); 
                    base.CreateHandle();
                } 
                GetParentContainer().ControlCreated(this); 
            }
        } 

        private NativeMethods.COMRECT GetClipRect(NativeMethods.COMRECT clipRect) {
            if (clipRect != null) {
                FillInRect(clipRect, new Rectangle(0, 0, 32000, 32000)); 
            }
            return clipRect; 
        } 

        private static int SetupLogPixels(bool force) { 
            if (logPixelsX == -1 || force) {
                IntPtr hDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
                if (hDC == IntPtr.Zero)
                    return NativeMethods.E_FAIL; 
                logPixelsX = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, hDC), NativeMethods.LOGPIXELSX);
                logPixelsY = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, hDC), NativeMethods.LOGPIXELSY); 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "log pixels are: "+logPixelsX.ToString(CultureInfo.InvariantCulture)+" "+logPixelsY.ToString(CultureInfo.InvariantCulture)); 
                UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, hDC));
            } 

            return NativeMethods.S_OK;
        }
 
        private void HiMetric2Pixel(NativeMethods.tagSIZEL sz, NativeMethods.tagSIZEL szout) {
            NativeMethods._POINTL phm = new NativeMethods._POINTL(); 
            phm.x = sz.cx; 
            phm.y = sz.cy;
            NativeMethods.tagPOINTF pcont = new NativeMethods.tagPOINTF(); 
            ((UnsafeNativeMethods.IOleControlSite)oleSite).TransformCoords(phm, pcont, NativeMethods.ActiveX.XFORMCOORDS_SIZE | NativeMethods.ActiveX.XFORMCOORDS_HIMETRICTOCONTAINER);
            szout.cx = (int)pcont.x;
            szout.cy = (int)pcont.y;
        } 

        private void Pixel2hiMetric(NativeMethods.tagSIZEL sz, NativeMethods.tagSIZEL szout) { 
            NativeMethods.tagPOINTF pcont = new NativeMethods.tagPOINTF(); 
            pcont.x = (float) sz.cx;
            pcont.y = (float) sz.cy; 
            NativeMethods._POINTL phm = new NativeMethods._POINTL();
            ((UnsafeNativeMethods.IOleControlSite)oleSite).TransformCoords(phm, pcont, NativeMethods.ActiveX.XFORMCOORDS_SIZE | NativeMethods.ActiveX.XFORMCOORDS_CONTAINERTOHIMETRIC);
            szout.cx = phm.x;
            szout.cy = phm.y; 
        }
 
        private static int Pixel2Twip(int v, bool xDirection) { 
            SetupLogPixels(false);
            int logP = xDirection ? logPixelsX : logPixelsY; 
            return(int) ((((double)v) / logP) * 72.0 * 20.0);
        }

        private static int Twip2Pixel(double v, bool xDirection) { 
            SetupLogPixels(false);
            int logP = xDirection ? logPixelsX : logPixelsY; 
            return(int) (((v / 20.0) / 72.0) * logP); 
        }
 
        private static int Twip2Pixel(int v, bool xDirection) {
            SetupLogPixels(false);
            int logP = xDirection ? logPixelsX : logPixelsY;
            return(int) (((((double) v) / 20.0) / 72.0) * logP); 
        }
 
 
        private Size SetExtent(int width, int height) {
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "setting extent to "+width.ToString(CultureInfo.InvariantCulture)+" "+height.ToString(CultureInfo.InvariantCulture)); 
            NativeMethods.tagSIZEL sz = new NativeMethods.tagSIZEL();
            sz.cx = width;
            sz.cy = height;
            bool resetExtents = !IsUserMode(); 
            try {
                Pixel2hiMetric(sz, sz); 
                GetOleObject().SetExtent(NativeMethods.ActiveX.DVASPECT_CONTENT, sz); 
            }
            catch (COMException) { 
                resetExtents = true;
            }
            if (resetExtents) {
                GetOleObject().GetExtent(NativeMethods.ActiveX.DVASPECT_CONTENT, sz); 
                try {
                    GetOleObject().SetExtent(NativeMethods.ActiveX.DVASPECT_CONTENT, sz); 
                } 
                catch (COMException e) {
                    Debug.Fail(e.ToString()); 
                }
            }
            return GetExtent();
        } 

 
        private Size GetExtent() { 
            NativeMethods.tagSIZEL sz = new NativeMethods.tagSIZEL();
            GetOleObject().GetExtent(NativeMethods.ActiveX.DVASPECT_CONTENT, sz); 
            HiMetric2Pixel(sz, sz);
            return new Size(sz.cx, sz.cy);
        }
 
        /// 
        ///  
        ///     ActiveX controls scale themselves, so GetScaledBounds simply returns their 
        ///     original unscaled bounds.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected override Rectangle GetScaledBounds(Rectangle bounds, SizeF factor, BoundsSpecified specified) {
            return bounds;
        } 

        private void SetObjectRects(Rectangle bounds) { 
            if (GetOcState() < OC_INPLACE) return; 
            GetInPlaceObject().SetObjectRects(FillInRect(new NativeMethods.COMRECT(), bounds), GetClipRect(new NativeMethods.COMRECT()));
        } 

        /// 
        /// 
        ///     Performs the work of setting the bounds of this control. 
        ///     User code should usually not call this function.
        ///  
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) { 
            // We have already been in this Code so please avoid re-entering this CODE PATH or else the
            // IOleObject will "give a Catastrophic error" in SetObjectRects( ). 
            // Please refer : VsWhidbey 341212.

            if (GetAxState(AxHost.handlePosRectChanged))
                return; 

            axState[handlePosRectChanged] = true; 
 
            // Provide control with an opportunity to apply self imposed constraints on its size.
            Size adjustedSize = ApplySizeConstraints(width, height); 
            width = adjustedSize.Width;
            height = adjustedSize.Height;

            try { 
                if (axState[fFakingWindow]) {
                    base.SetBoundsCore(x, y, width, height, specified); 
                    return; 
                }
                Rectangle oldBounds = Bounds; 

                if (oldBounds.X == x && oldBounds.Y == y && oldBounds.Width == width &&
                    oldBounds.Height == height) {
                    return; 
                }
                if (!IsHandleCreated) { 
                    UpdateBounds(x, y, width, height); 
                    return;
                } 

                if (GetOcState() > OC_RUNNING) {
                    CheckSubclassing();
                    if (width != oldBounds.Width || height != oldBounds.Height) { 
                        Size p = SetExtent(width, height);
                        width = p.Width; 
                        height = p.Height; 
                    }
                } 
                if (axState[manualUpdate]) {
                    SetObjectRects(new Rectangle(x, y, width, height));
                    CheckSubclassing();
                    UpdateBounds(); 
                }
                else { 
                    SetObjectRects(new Rectangle(x, y, width, height)); 
                    base.SetBoundsCore(x, y, width, height, specified);
                    Invalidate(); 
                }
            }
            finally {
                axState[handlePosRectChanged] = false; 
            }
        } 
 

        private bool CheckSubclassing() { 
            if (!IsHandleCreated || wndprocAddr == IntPtr.Zero) return true;
            IntPtr handle = Handle;
            IntPtr currentWndproc = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, handle), NativeMethods.GWL_WNDPROC);
            if (currentWndproc == wndprocAddr) return true; 
            if ((int)SendMessage(REGMSG_MSG, 0, 0) == REGMSG_RETVAL) {
                wndprocAddr = currentWndproc; 
                return true; 
            }
            // yikes, we were resubclassed... 
            Debug.WriteLineIf(AxHostSwitch.TraceVerbose, "The horrible control subclassed itself w/o calling the old wndproc...");
            // we need to resubclass outselves now...
            Debug.Assert(!OwnWindow(), "why are we here if we own our window?");
            this.WindowReleaseHandle(); 
            UnsafeNativeMethods.SetWindowLong(new HandleRef(this, handle), NativeMethods.GWL_WNDPROC, new HandleRef(this, currentWndproc));
            this.WindowAssignHandle(handle, axState[assignUniqueID]); 
            InformOfNewHandle(); 
            axState[manualUpdate] = true;
            return false; 
        }

        /// 
        ///  
        ///     Destroys the handle associated with this control.
        ///     User code should in general not call this function. 
        ///  
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
        // security review: this is a breaking change, but should it be fixed? 
        protected override void DestroyHandle() {
            if (axState[fOwnWindow]) {
                base.DestroyHandle();
            } 
            else {
                if (IsHandleCreated) { 
                    TransitionDownTo(OC_RUNNING); 
                }
            } 
        }

#if false
        // FxCop: Currently not used 
        private void TransitionTo(int state) {
            if (state > GetOcState()) { 
                TransitionUpTo(state); 
            }
            else if (state < GetOcState()) { 
                TransitionDownTo(state);
            }
        }
#endif 

        private void TransitionDownTo(int state) { 
            if (axState[inTransition]) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Recursively entering TransitionDownTo...");
                return; 
            }

            try {
                axState[inTransition] = true; 

                while (state < GetOcState()) { 
                    switch (GetOcState()) { 
                        case OC_OPEN:
                            Debug.Fail("how did we ever get into the open state?"); 
                            SetOcState(OC_UIACTIVE);
                            break;
                        case OC_UIACTIVE:
                            int hr = UiDeactivate(); 
                            Debug.Assert(NativeMethods.Succeeded(hr), "Failed in UiDeactivate: " + hr.ToString(CultureInfo.InvariantCulture));
                            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose && GetOcState() == OC_INPLACE, "failed transition"); 
                            SetOcState(OC_INPLACE); 
                            break;
                        case OC_INPLACE: 
                            if (axState[fFakingWindow]) {
                                DestroyFakeWindow();
                                SetOcState(OC_RUNNING);
                            } 
                            else {
                                InPlaceDeactivate(); 
                            } 
                            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose && GetOcState() == OC_RUNNING, "failed transition");
                            SetOcState(OC_RUNNING); 
                            break;
                        case OC_RUNNING:
                            StopEvents();
                            DisposeAxControl(); 
                            Debug.Assert(GetOcState() == OC_LOADED," failed transition");
                            SetOcState(OC_LOADED); 
                            break; 
                        case OC_LOADED:
                            ReleaseAxControl(); 
                            Debug.Assert(GetOcState() == OC_PASSIVE," failed transition");
                            SetOcState(OC_PASSIVE);
                            break;
                        default: 
                            Debug.Fail("bad state");
                            SetOcState(GetOcState() - 1); 
                            break; 
                    }
                } 
            }
            finally {
                axState[inTransition] = false;
            } 
        }
 
        private void TransitionUpTo(int state) { 
            if (axState[inTransition]) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Recursively entering TransitionUpTo..."); 
                return;
            }

            try { 
                axState[inTransition] = true;
 
                while (state > GetOcState()) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Transitioning up from: " + GetOcState().ToString(CultureInfo.InvariantCulture) + " to: " + state.ToString(CultureInfo.InvariantCulture));
                    switch (GetOcState()) { 
                        case OC_PASSIVE:
                            axState[disposed] = false;
                            GetOcxCreate();
                            Debug.Assert(GetOcState() == OC_LOADED, " failed transition"); 
                            SetOcState(OC_LOADED);
                            break; 
                        case OC_LOADED: 
                            ActivateAxControl();
                            Debug.Assert(GetOcState() == OC_RUNNING, " failed transition"); 
                            SetOcState(OC_RUNNING);
                            if (IsUserMode()) {
                                // start the events flowing!
                                //createSink(); 
                                StartEvents();
                            } 
                            break; 
                        case OC_RUNNING:
                            axState[ownDisposing] = false; 
                            Debug.Assert(!axState[fOwnWindow], "If we are invis at runtime, we should never be going beynd OC_RUNNING");
                            if (!axState[fOwnWindow]) {
                                InPlaceActivate();
 
                                if (!Visible && ContainingControl != null && ContainingControl.Visible) {
                                    HideAxControl(); 
                                } 
                                else {
                                    // if we do this in both codepaths, then we will force handle creation of the fake window 
                                    // even if we don't need it...
                                    // This optimization will break, however, if:
                                    // a) the hWnd goes away on a OLEIVERB_HIDE and
                                    // b) this is a simple frame control 
                                    // However, if you satisfy both of these conditions then you must be REALLY
                                    // brain dead and you don't deserve to work anyway... 
                                    CreateControl(true); 
                                    // if our default size is wrong for the control, let's resize ourselves...
                                    // Note: some controls haven't updated their extents at this time 
                                    // (even though they got it from the DoVerb call and
                                    // also from GetWindowContext) so we don't poke in a new value.
                                    // The reason to do this at design time is that that's the only way we
                                    // can find out if the control has a default which we have to obey. 
                                    if (!IsUserMode() && !axState[ocxStateSet]) {
                                        Size p = GetExtent(); 
                                        Rectangle b = Bounds; 

                                        if ((b.Size.Equals(DefaultSize)) && (!b.Size.Equals(p))) { 
                                            b.Width = p.Width;
                                            b.Height = p.Height;
                                            Bounds = b;
                                        } 
                                    }
                                } 
                            } 

                            //Debug.Assert(GetOcState() == OC_INPLACE, " failed transition"); 
                            if (GetOcState() < OC_INPLACE) {
                                SetOcState(OC_INPLACE);
                            }
                            OnInPlaceActive(); 
                            break;
                        case OC_INPLACE: 
                            DoVerb(OLEIVERB_SHOW); 
                            Debug.Assert(GetOcState() == OC_UIACTIVE, " failed transition");
                            SetOcState(OC_UIACTIVE); 
                            break;
                        default:
                            Debug.Fail("bad state");
                            SetOcState(GetOcState() + 1); 
                            break;
                    } 
                } 
            }
            finally { 
                axState[inTransition] = false;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        ///  
        protected virtual void OnInPlaceActive() {
        }

        private void InPlaceActivate() { 
            try {
                DoVerb(OLEIVERB_INPLACEACTIVATE); 
            } 
            catch (Exception t) {
                Debug.Fail(t.ToString()); 
                throw new TargetInvocationException(SR.GetString(SR.AXNohWnd,GetType().Name), t);
            }
            EnsureWindowPresent();
        } 

 
        private void InPlaceDeactivate() { 
            axState[ownDisposing] = true;
            ContainerControl f = ContainingControl; 
            if (f != null) {
                if (f.ActiveControl == this) {
                    f.ActiveControl = null;
                } 
            }
 
            try { 
                GetInPlaceObject().InPlaceDeactivate();
            } 
            catch(Exception e) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception calling InPlaceDeactivate: "+ e.ToString());
            }
        } 

        private void UiActivate() { 
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "calling uiActivate for "+this.ToString()); 
            Debug.Assert(GetOcState() >= OC_INPLACE, "we have to be in place in order to ui activate...");
            Debug.Assert(CanUIActivate, "we have to be able to uiactivate"); 
            if (CanUIActivate) {
                DoVerb(OLEIVERB_UIACTIVATE);
            }
        } 

        private void DestroyFakeWindow() { 
            Debug.Assert(axState[fFakingWindow], "have to be faking it in order to destroy it..."); 

            // ASURT 70740: The problem seems to be that when we try to destroy the fake window, 
            // we recurse in and transition the control down to OC_RUNNING. This causes the control's
            // new window to get destroyed also, and the control never shows up.
            // We now prevent this by changing our state about the fakeWindow _before_ we actually
            // destroy the window. 
            //
            axState[fFakingWindow] = false; 
            base.DestroyHandle(); 
        }
 
        private void EnsureWindowPresent() {
            // if the ctl didn't call showobject, we need to do it for it...
            if (!IsHandleCreated) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Naughty control didn't call showObject..."); 
                try {
                    ((UnsafeNativeMethods.IOleClientSite)oleSite).ShowObject(); 
                } 
                catch {
                    // The exception, if any was already dumped in ShowObject 
                }
            }
            if (IsHandleCreated) return;
 
            if (ParentInternal != null) {    // ==> we are in a valid state
                Debug.Fail("extremely naughty ctl is refusing to give us an hWnd... giving up..."); 
                throw new InvalidOperationException(SR.GetString(SR.AXNohWnd,GetType().Name)); 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void SetVisibleCore(bool value) { 
            if (GetState(STATE_VISIBLE) != value) { 
                bool oldVisible = Visible;
                if ((IsHandleCreated || value) && ParentInternal != null && ParentInternal.Created) { 
                    if (!axState[fOwnWindow]) {
                        TransitionUpTo(OC_RUNNING);
                        if (value) {
                            if (axState[fFakingWindow]) { 
                                // first we need to destroy the fake window...
                                DestroyFakeWindow(); 
                            } 
                            // We want to avoid using SHOW since that may uiactivate us, and we don't
                            // want that... 
                            if (!IsHandleCreated) {
                                // So, if we don't have a handle, we just try to create it and hope that this will make
                                // us appear...
                                try { 
                                    SetExtent(Width, Height);
                                    InPlaceActivate(); 
                                    CreateControl(true); 
                                }
                                catch { 
                                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Could not make ctl visible by using INPLACE. Will try SHOW");
                                    MakeVisibleWithShow();
                                }
                            } 
                            else {
                                // if, otoh, we had a handle to begin with, we need to use show since INPLACE is just 
                                // a noop... 
                                MakeVisibleWithShow();
                            } 
                        }
                        else {
                            Debug.Assert(!axState[fFakingWindow], "if we were visible, we could not have had a fake window...");
                            HideAxControl(); 
                        }
                    } 
                } 
                if (!value) {
                    axState[fNeedOwnWindow] = false; 
                }
                if (!axState[fOwnWindow]) {
                    SetState(STATE_VISIBLE, value);
                    if (Visible != oldVisible) 
                        OnVisibleChanged(EventArgs.Empty);
                } 
            } 
        }
 
        private void MakeVisibleWithShow() {
            ContainerControl f = ContainingControl;
            Control ctl = f == null ? null : f.ActiveControl;
            try { 
                DoVerb(OLEIVERB_SHOW);
            } 
            catch (Exception t) { 
                Debug.Fail(t.ToString());
                throw new TargetInvocationException(SR.GetString(SR.AXNohWnd,GetType().Name), t); 
            }

            EnsureWindowPresent();
            CreateControl(true); 
            if (f != null && f.ActiveControl != ctl) {
                f.ActiveControl = ctl; 
            } 
        }
 
        private void HideAxControl() {
            Debug.Assert(!axState[fOwnWindow], "can't own our window when hiding");
            Debug.Assert(IsHandleCreated, "gotta have a window to hide");
            Debug.Assert(GetOcState() >= OC_INPLACE, "have to be in place in order to hide."); 

            DoVerb(OLEIVERB_HIDE); 
            if (GetOcState() < OC_INPLACE) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Naughty control inplace deactivated on a hide verb...");
                Debug.Assert(!IsHandleCreated, "if we are inplace deactivated we should not have a window."); 
                // all we do here is set a flag saying that we need the window to be created if
                // create handle is ever called...
                axState[fNeedOwnWindow] = true;
 
                // also, set the state to our "pretend oc_inplace state"
                // 
                SetOcState(OC_INPLACE); 
            }
        } 

        /// 
        /// 
        ///     Determines if charCode is an input character that the control 
        ///     wants. This method is called during window message pre-processing to
        ///     determine whether the given input character should be pre-processed or 
        ///     sent directly to the control. If isInputChar returns true, the 
        ///     given character is sent directly to the control. If isInputChar
        ///     returns false, the character is pre-processed and only sent to the 
        ///     control if it is not consumed by the pre-processing phase. The
        ///     pre-processing of a character includes checking whether the character
        ///     is a mnemonic of another control.
        ///  
        [UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool IsInputChar(char charCode) { 
            return true; 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Security", "CA2114:MethodSecurityShouldBeASupersetOfType")]
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] 
        protected override bool ProcessDialogKey(Keys keyData) 
        {
            return ignoreDialogKeys ? false : base.ProcessDialogKey(keyData); 
        }

        /// 
        ///  
        ///     This method is called by the application's message loop to pre-process
        ///     input messages before they are dispatched. Possible values for the 
        ///     msg.message field are WM_KEYDOWN, WM_SYSKEYDOWN, WM_CHAR, and WM_SYSCHAR. 
        ///     If this method processes the message it must return true, in which case
        ///     the message loop will not dispatch the message. 
        ///     This method should not be called directly by the user.
        ///
        ///     The keyboard processing of input keys to AxHost controls go in 3 steps inside AxHost.PreProcessMessage()
        /// 
        ///    (1) Call the OCX's TranslateAccelarator. This may or may not call back into us using IOleControlSite::TranslateAccelarator()
        /// 
        ///    (2) If the control completely processed this without calling us back: 
        ///         -- If this returns S_OK, then it means that the control already processed this message and we return true,
        ///            forcing us to not do any more processing or dispatch the message. 
        ///         -- If this returns S_FALSE, then it means that the control wants us to dispatch the message without doing any processing on our side.
        ///
        ///    (3) If the control completely processed this by calling us back:
        ///         -- If this returns S_OK, then it means that the control processed this message and we return true, 
        ///            forcing us to not do any more processing or dispatch the message.
        ///         -- If this returns S_FALSE, then it means that the control did not process this message, 
        ///            but we did, and so we should route it through our PreProcessMessage(). 
        /// 
        public override bool PreProcessMessage(ref Message msg) { 
            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "AxHost.PreProcessMessage " + msg.ToString());

            if (IsUserMode()) {
                if (axState[siteProcessedInputKey]) { 
                    // In this case, the control called the us back through the IControlSite
                    // and giving us a chance to see if we want to process it. We in turn 
                    // call the base implementation which normally would call the control's 
                    // IsInputKey() or IsInputChar(). So, we short-circuit those to return false
                    // and only return true, if the container-chain wanted to process the keystroke 
                    // (e.g. tab, accelarators etc.)
                    //
                    return base.PreProcessMessage(ref msg);
                } 

                NativeMethods.MSG win32Message = new NativeMethods.MSG(); 
                win32Message.message = msg.Msg; 
                win32Message.wParam = msg.WParam;
                win32Message.lParam = msg.LParam; 
                win32Message.hwnd = msg.HWnd;

                axState[siteProcessedInputKey] = false;
                try { 
                    UnsafeNativeMethods.IOleInPlaceActiveObject activeObj = GetInPlaceActiveObject();
                    if (activeObj != null) 
                    { 
                        int hr = activeObj.TranslateAccelerator(ref win32Message);
 
                        msg.Msg = win32Message.message;
                        msg.WParam = win32Message.wParam;
                        msg.LParam = win32Message.lParam;
                        msg.HWnd = win32Message.hwnd; 

                        if (hr == NativeMethods.S_OK) { 
                            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "\t Message translated by control to " + msg); 
                            return true;
                        } 
                        else if (hr == NativeMethods.S_FALSE) {
                            bool ret = false;

                            ignoreDialogKeys = true; 
                            try {
                                ret = base.PreProcessMessage(ref msg); 
                            } 
                            finally {
                                ignoreDialogKeys = false; 
                            }
                            return ret;
                        }
                        else if (axState[siteProcessedInputKey]) { 
                            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "\t Message processed by site. Calling base.PreProcessMessage() " + msg);
                            return base.PreProcessMessage (ref msg); 
                        } 
                        else {
                            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "\t Message not processed by site. Returning false. " + msg); 
                            return false;
                        }
                    }
                } 
                finally {
                    axState[siteProcessedInputKey] = false; 
                } 
            }
 
            return false;
        }

        ///  
        /// 
        ///     Process a mnemonic character. 
        ///     This is done by manufacturing a WM_SYSKEYDOWN message and passing it 
        ///     to the ActiveX control.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2114:MethodSecurityShouldBeASupersetOfType")]
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected internal override bool ProcessMnemonic(char charCode) {
            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "In AxHost.ProcessMnemonic: " + (int)charCode); 
            if (CanSelect) {
                try { 
                    NativeMethods.tagCONTROLINFO ctlInfo = new NativeMethods.tagCONTROLINFO(); 
                    int hr = GetOleControl().GetControlInfo(ctlInfo);
                    if (NativeMethods.Failed(hr)) { 
                        return false;
                    }
                    NativeMethods.MSG msg = new NativeMethods.MSG();
                    // Sadly, we don't have a message so we must fake one ourselves... 
                    // A bit of ugliness here (a bit?  more like a bucket...)
                    // The message we are faking is a WM_SYSKEYDOWN w/ the right alt key setting... 
                    msg.hwnd = (ContainingControl == null) ? IntPtr.Zero : ContainingControl.Handle; 
                    msg.message = NativeMethods.WM_SYSKEYDOWN;
                    msg.wParam = (IntPtr) Char.ToUpper(charCode, CultureInfo.CurrentCulture); 
                    msg.lParam = (IntPtr) 0x20180001;
                    msg.time = SafeNativeMethods.GetTickCount();
                    NativeMethods.POINT p = new NativeMethods.POINT();
                    UnsafeNativeMethods.GetCursorPos(p); 
                    msg.pt_x = p.x;
                    msg.pt_y = p.y; 
                    if (SafeNativeMethods.IsAccelerator(new HandleRef(ctlInfo, ctlInfo.hAccel), ctlInfo.cAccel, ref msg, null)) { 
                        GetOleControl().OnMnemonic(ref msg);
                        Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "\t Processed mnemonic " + msg); 
                        Focus();
                        return true;
                    }
                } 
                catch (Exception t) {
                    Debug.Fail("error in processMnemonic"); 
                    Debug.Fail(t.ToString()); 
                    return false;
                } 
            }
            return false;
        }
 
        // misc methods:
 
        ///  
        /// 
        ///     Sets the delegate which will be called when the user selects the "About..." 
        ///     entry on the context menu.
        /// 
        protected void SetAboutBoxDelegate(AboutBoxDelegate d) {
            aboutBoxDelegate += d; 
        }
 
        ///  
        /// 
        ///     Sets the persisted state of the control. 
        ///     This should either be null, obtained from getOcxState, or
        ///     read from a resource.  The value of this property will
        ///     be used after the control is created but before it is
        ///     shown. 
        ///     Computes the persisted state of the underlying ActiveX control and
        ///     returns it in the encapsulated State object. 
        ///     If the control has been modified since it was last saved to a 
        ///     persisted state, it will be asked to save itself.
        ///  
        [
        DefaultValue(null),
        RefreshProperties(RefreshProperties.All),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced) 
        ]
        public State OcxState { 
            get { 
                if (IsDirty() || ocxState == null) {
                    Debug.Assert(!axState[disposed], "we chould not be asking for the object when we are axState[disposed]..."); 
                    ocxState = CreateNewOcxState(ocxState);
                }
                return ocxState;
            } 

            set { 
                axState[ocxStateSet] = true; 

                if (value == null) return; 

                if (storageType != STG_UNKNOWN && storageType != value.type) {
                    Debug.Fail("Trying to reload with a OcxState that is of a different type.");
                    throw new InvalidOperationException(SR.GetString(SR.AXOcxStateLoaded)); 
                }
 
                if (this.ocxState == value) 
                    return;
 
                this.ocxState = value;

                if (this.ocxState != null) {
                    this.axState[manualUpdate] = ocxState._GetManualUpdate(); 
                    this.licenseKey = ocxState._GetLicenseKey();
                } 
                else { 
                    this.axState[manualUpdate] = false;
                    this.licenseKey = null; 
                }

                if (this.ocxState != null && GetOcState() >= OC_RUNNING) {
                    DepersistControl(); 
                }
            } 
        } 

        private State CreateNewOcxState(State oldOcxState) { 
            NoComponentChangeEvents++;

            try {
                if (GetOcState() < OC_RUNNING) { 
                    return null;
                } 
 
                try {
                    PropertyBagStream propBag = null; 

                    if (iPersistPropBag != null) {
                        propBag = new PropertyBagStream();
                        iPersistPropBag.Save(propBag, true, true); 
                    }
 
                    MemoryStream ms = null; 
                    switch (storageType) {
                        case STG_STREAM: 
                        case STG_STREAMINIT:
                            ms = new MemoryStream();
                            if (storageType == STG_STREAM) {
                                iPersistStream.Save(new UnsafeNativeMethods.ComStreamFromDataStream(ms), true); 
                            }
                            else { 
                                iPersistStreamInit.Save(new UnsafeNativeMethods.ComStreamFromDataStream(ms), true); 
                            }
                            break; 
                        case STG_STORAGE:
                            Debug.Assert(oldOcxState != null, "we got to have an old state which holds out scribble storage...");
                            if (oldOcxState != null) return oldOcxState.RefreshStorage(iPersistStorage);
                            return null; 
                        default:
                            Debug.Fail("unknown storage type."); 
                            return null; 
                    }
                    if (ms != null) { 
                        return new State(ms, storageType, this, propBag);
                    }
                    else if (propBag != null) {
                        return new State(propBag); 
                    }
                } 
                catch (Exception e) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Could not create new OCX State: " + e.ToString());
                } 
            }
            finally {
                NoComponentChangeEvents--;
            } 

            return null; 
        } 

        ///  
        /// 
        ///     Returns this control's logicaly containing form.
        ///     At design time this is always the form being designed.
        ///     At runtime it is either the form set with setContainingForm or, 
        ///     by default, the parent form.
        ///     Sets the form which is the logical container of this control. 
        ///     By default, the parent form performs that function.  It is 
        ///     however possible for another form higher in the parent chain
        ///     to serve in that role.  The logical container of this 
        ///     control determines the set of logical sibling control.
        ///     In general this property exists only to enable some speficic
        ///     behaviours of ActiveX controls and should in general not be set
        ///     by the user. 
        /// 
        [ 
            Browsable(false), 
            EditorBrowsable(EditorBrowsableState.Advanced),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public ContainerControl ContainingControl {
            get {
                Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "GetParent Demanded"); 
                IntSecurity.GetParent.Demand();
 
                if (containingControl == null) { 
                    containingControl = FindContainerControlInternal();
                } 

                return containingControl;
            }
 
            set {
                containingControl = value; 
            } 
        }
 
        /// 
        /// 
        /// Determines if the Text property needs to be persisted.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)]
        internal override bool ShouldSerializeText() { 
            bool ret = false; 
            try {
                ret = (Text.Length != 0); 
            }
            catch (COMException) {
            }
            return ret; 
        }
 
        ///  
        ///     Determines whether to persist the ContainingControl property.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)]
        private bool ShouldSerializeContainingControl() {
            return ContainingControl != ParentInternal;
        } 

        private ContainerControl FindContainerControlInternal() { 
            if (Site != null) { 
                IDesignerHost host = (IDesignerHost)Site.GetService(typeof(IDesignerHost));
                if (host != null) { 
                    ContainerControl rootControl = host.RootComponent as ContainerControl;
                    if (rootControl != null)
                    {
                        return rootControl; 
                    }
                } 
            } 

            ContainerControl cc = null; 
            Control control = this;
            while (control != null) {
                ContainerControl tempCC = control as ContainerControl;
                if (tempCC != null) 
                {
                    cc = tempCC; 
                    break; 
                }
                control = control.ParentInternal; 
            }
            return cc;
        }
 
        private bool IsDirty() {
            if (GetOcState() < OC_RUNNING) return false; 
            Debug.Assert(storageType != STG_UNKNOWN, "if we are loaded, out storage type must be set!"); 

            if (axState[valueChanged]) { 
                axState[valueChanged] = false;
                return true;
            }
 
#if DEBUG
            if (AxAlwaysSaveSwitch.Enabled) return true; 
#endif 
            int hr = NativeMethods.E_FAIL;
            switch (storageType) { 
                case STG_STREAM:
                    hr = iPersistStream.IsDirty();
                    break;
                case STG_STREAMINIT: 
                    hr = iPersistStreamInit.IsDirty();
                    break; 
                case STG_STORAGE: 
                    hr = iPersistStorage.IsDirty();
                    break; 
                default:
                    Debug.Fail("unknown storage type");
                    return true;
            } 
            if (hr == NativeMethods.S_FALSE) {
                // NOTE: This was a note from the old AxHost codebase. The problem 
                // with doing this is that the some controls that do not run in 
                // unlicensed mode (e.g. ProtoView ScheduleX pvtaskpad.ocx) will
                // always return S_FALSE to disallow design-time support. 

                // Sadly, some controls lie and never say that they are dirty...
                // SO, we don't believe them unless they told us that they were
                // dirty at least once... 
                return false;
            } 
            else if (NativeMethods.Failed(hr)) { 
                return true;
            } 
            return true;
        }

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        internal bool IsUserMode() {
            ISite site = Site; 
            return site == null || !site.DesignMode; 
        }
 
        private Object GetAmbientProperty(int dispid) {

            Control richParent = ParentInternal;
 
            switch (dispid) {
                case NativeMethods.ActiveX.DISPID_AMBIENT_USERMODE: 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for usermode"); 
                    return IsUserMode();
                case NativeMethods.ActiveX.DISPID_AMBIENT_AUTOCLIP: 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for autoclip");
                    return true;
                case NativeMethods.ActiveX.DISPID_AMBIENT_MESSAGEREFLECT:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for message reflect"); 
                    return true;
                case NativeMethods.ActiveX.DISPID_AMBIENT_UIDEAD: 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for uidead"); 
                    return false;
                case NativeMethods.ActiveX.DISPID_AMBIENT_DISPLAYASDEFAULT: 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for displayasdefault");
                    return false;
                case NativeMethods.ActiveX.DISPID_AMBIENT_FONT:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for font"); 
                    if (richParent != null) {
                        return GetIFontFromFont(richParent.Font); 
                    } 
                    return null;
                case NativeMethods.ActiveX.DISPID_AMBIENT_SHOWGRABHANDLES: 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for showGrabHandles");
                    return false;
                case NativeMethods.ActiveX.DISPID_AMBIENT_SHOWHATCHING:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for showHatching"); 
                    return false;
                case NativeMethods.ActiveX.DISPID_AMBIENT_BACKCOLOR: 
                    if (richParent != null) { 
                        return GetOleColorFromColor(richParent.BackColor);
                    } 
                    return null;
                case NativeMethods.ActiveX.DISPID_AMBIENT_FORECOLOR:
                    if (richParent != null) {
                        return GetOleColorFromColor(richParent.ForeColor); 
                    }
                    return null; 
                case NativeMethods.ActiveX.DISPID_AMBIENT_DISPLAYNAME: 
                    string rval = GetParentContainer().GetNameForControl(this);
                    if (rval == null) rval = ""; 
                    return rval;
                case NativeMethods.ActiveX.DISPID_AMBIENT_LOCALEID:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for localeid");
                    return Thread.CurrentThread.CurrentCulture.LCID; 
                case NativeMethods.ActiveX.DISPID_AMBIENT_RIGHTTOLEFT:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "asked for right to left"); 
                    Control ctl = this; 
                    while (ctl != null) {
                        if (ctl.RightToLeft == System.Windows.Forms.RightToLeft.No) 
                            return false;
                        if (ctl.RightToLeft == System.Windows.Forms.RightToLeft.Yes)
                            return true;
                        if (ctl.RightToLeft == System.Windows.Forms.RightToLeft.Inherit) 
                            ctl = ctl.Parent;
                    } 
                    return null; 
                default:
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "unsupported ambient "+dispid.ToString(CultureInfo.InvariantCulture)); 
                    return null;
            }
        }
 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public void DoVerb(int verb) {
            Control parent = ParentInternal;
            GetOleObject().DoVerb(verb, IntPtr.Zero, oleSite, -1, parent != null ? parent.Handle : IntPtr.Zero, FillInRect(new NativeMethods.COMRECT(), Bounds));
        } 

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        private bool AwaitingDefreezing() { 
            return freezeCount > 0;
        } 

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        private void Freeze(bool v) {
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "freezing "+v.ToString()); 
            if (v) {
                try { 
                    GetOleControl().FreezeEvents(-1); 
                }
                catch (COMException t) { 
                    Debug.Fail(t.ToString());
                }
                freezeCount ++;
            } 
            else {
                try { 
                    GetOleControl().FreezeEvents(0); 
                }
                catch (COMException t) { 
                    Debug.Fail(t.ToString());
                }
                freezeCount --;
            } 
            Debug.Assert(freezeCount >=0, "invalid freeze count!");
        } 
 
        private int UiDeactivate() {
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "calling uiDeactivate for "+this.ToString()); 
            bool ownDispose = this.axState[ownDisposing];
            this.axState[ownDisposing] = true;
            int hr = 0;
            try { 
                hr = GetInPlaceObject().UIDeactivate();
            } 
            finally { 
                this.axState[ownDisposing] = ownDispose;
            } 
            return hr;
        }

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        private int GetOcState() {
            return ocState; 
        } 

        private void SetOcState(int nv) { 
            ocState = nv;
        }

        private string GetLicenseKey() { 
            return GetLicenseKey(this.clsid);
        } 
 
        private string GetLicenseKey(Guid clsid) {
            if (licenseKey != null || !axState[needLicenseKey]) { 
                return licenseKey;
            }

            try { 
                UnsafeNativeMethods.IClassFactory2 icf2 = UnsafeNativeMethods.CoGetClassObject(ref clsid, INPROC_SERVER, 0, ref icf2_Guid);
                NativeMethods.tagLICINFO licInfo = new NativeMethods.tagLICINFO(); 
                icf2.GetLicInfo(licInfo); 
                if (licInfo.fRuntimeAvailable != 0) {
                    string[] rval = new string[1]; 
                    icf2.RequestLicKey(0, rval);
                    licenseKey = rval[0];
                    return licenseKey;
                } 
            }
            catch (COMException e) { 
                if (e.ErrorCode == E_NOINTERFACE.ErrorCode) return null; 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to get the license key: " + e.ToString());
                axState[needLicenseKey] = false; 
            }
            catch (Exception t) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to get the license key: " + t.ToString());
                axState[needLicenseKey] = false; 
            }
            return null; 
        } 

        private void CreateWithoutLicense(Guid clsid) { 
            object ret = null;
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Creating object without license: " + clsid.ToString());
            ret = UnsafeNativeMethods.CoCreateInstance(ref clsid, null, INPROC_SERVER, ref NativeMethods.ActiveX.IID_IUnknown);
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t" + (ret != null).ToString()); 
            instance = ret;
        } 
 
        private void CreateWithLicense(string license, Guid clsid) {
            if (license != null) { 
                try {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Creating object with license: " + clsid.ToString());
                    UnsafeNativeMethods.IClassFactory2 icf2 = UnsafeNativeMethods.CoGetClassObject(ref clsid, INPROC_SERVER, 0, ref icf2_Guid);
 
                    if (icf2 != null) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\tClassFactory" + (icf2 != null).ToString()); 
                        icf2.CreateInstanceLic(null, null, ref NativeMethods.ActiveX.IID_IUnknown, license, out instance); 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t" + (instance != null).ToString());
                    } 
                }
                catch (Exception t) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to create with license: " + t.ToString());
                } 
            }
 
            if (instance == null) { 
                CreateWithoutLicense(clsid);
            } 
        }

        private void CreateInstance() {
            Debug.Assert(instance == null, "instance must be null"); 
            //Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "before created "+Windows.GetCurrentThreadId());
            //Debug.WriteStackTraceIf("AxHTrace"); 
            //checkThreadingModel(); 
            try {
                instance = CreateInstanceCore(this.clsid); 
                Debug.Assert(instance != null, "w/o an exception being thrown we must have an object...");
            }
            catch (ExternalException e) {
                if (e.ErrorCode == unchecked((int)0x80040112)) { // CLASS_E_NOTLICENSED 
                    throw new LicenseException(GetType(), this, SR.GetString(SR.AXNoLicenseToUse));
                } 
                throw; 
            }
 
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "created");
            SetOcState(OC_LOADED);
        }
 

        ///  
        ///    Called to create the ActiveX control.  Override this member to perform your own creation logic 
        ///    or call base to do the default creation logic.
        ///  
        protected virtual object CreateInstanceCore(Guid clsid) {
            if (IsUserMode()) {
                CreateWithLicense(licenseKey, clsid);
            } 
            else {
                CreateWithoutLicense(clsid); 
            } 
            return instance;
        } 


        private CategoryAttribute GetCategoryForDispid(int dispid) {
            NativeMethods.ICategorizeProperties icp = GetCategorizeProperties(); 
            if (icp == null) return null;
            CategoryAttribute rval = null; 
            int propcat = 0; 
            try {
                icp.MapPropertyToCategory(dispid, ref propcat); 
                if (propcat != 0) {
                    int cat = -propcat;
                    if (cat > 0 && cat < categoryNames.Length && categoryNames[cat] != null) {
                        return categoryNames[cat]; 
                    }
                    cat = - cat; 
                    Int32 key = cat; 
                    if (objectDefinedCategoryNames != null) {
                        rval = (CategoryAttribute) objectDefinedCategoryNames[key]; 
                        if (rval != null) return rval;
                    }

                    string name = null; 
                    int hr = icp.GetCategoryName(cat, CultureInfo.CurrentCulture.LCID, out name);
                    if (hr == NativeMethods.S_OK && name != null) { 
                        rval = new CategoryAttribute(name); 
                        if (objectDefinedCategoryNames == null) {
                            objectDefinedCategoryNames = new Hashtable(); 
                        }
                        objectDefinedCategoryNames.Add(key, rval);
                        return rval;
                    } 
                }
            } 
            catch (Exception t) { 
                Debug.Fail(t.ToString());
            } 
            return null;
        }

        private void SetSelectionStyle(int selectionStyle) { 
            if (!this.IsUserMode()) {
                // selectionStyle can be 0 (not selected), 1 (selected) or 2 (active) 
                Debug.Assert(selectionStyle >= 0 && selectionStyle <= 2, "Invalid selection style"); 

                ISelectionService iss = GetSelectionService(); 
                this.selectionStyle = selectionStyle;
                if (iss != null && iss.GetComponentSelected(this)) {
                    // The AX Host designer will offer an extender property called "SelectionStyle"
                    // 
                    PropertyDescriptor prop = TypeDescriptor.GetProperties(this)["SelectionStyle"];
                    if (prop != null && prop.PropertyType == typeof(int)) { 
                        prop.SetValue(this, selectionStyle); 
                    }
                } 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public void InvokeEditMode() { 
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "invoking EditMode for "+this.ToString());
            Debug.Assert((flags & AxFlags.PreventEditMode) == 0, "edit mode should have been disabled");
            if (editMode != EDITM_NONE) return;
            AddSelectionHandler(); 
            editMode = EDITM_HOST;
            SetSelectionStyle(2); 
            IntPtr hwndFocus = UnsafeNativeMethods.GetFocus(); 
            try {
                UiActivate(); 
            }
            catch (Exception t) {
                Debug.Fail(t.ToString());
            } 
            // It so happens that some controls don't get focus in this case, so
            // we have got to force it onto them... 
            //         int hwndFocusNow = NativeMethods.GetFocus(); 
            //         Windows.SetFocus(getHandle());
            //         while (hwndFocusNow != getHandle()) { 
            //             if (hwndFocusNow == 0) {
            //                 break;
            //             }
            //             hwndFocusNow = Windows.GetParent(hwndFocusNow); 
            //         }
        } 
 
        //
        // ICustomTypeDescriptor implementation. 
        //

        /// 
        ///  
        /// 
        /// [To be supplied.] 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        AttributeCollection ICustomTypeDescriptor.GetAttributes() { 
            if (!axState[editorRefresh] && HasPropertyPages()) {
                axState[editorRefresh] = true;
                TypeDescriptor.Refresh(this.GetType());
            } 
            return TypeDescriptor.GetAttributes(this, true);
        } 
 
        /// 
        ///  
        /// 
        /// Retrieves the class name for this object.  If null is returned,
        /// the type name is used.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        string ICustomTypeDescriptor.GetClassName() { 
            return null; 
        }
 
        /// 
        /// 
        /// 
        /// Retrieves the name for this object.  If null is returned, 
        /// the default is used.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        string ICustomTypeDescriptor.GetComponentName() {
            return null; 
        }

        /// 
        ///  
        /// 
        /// Retrieves the type converter for this object. 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        TypeConverter ICustomTypeDescriptor.GetConverter() { 
            return null;
        }

        ///  
        /// 
        ///  
        /// [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }
 
        /// 
        ///  
        ///  
        /// [To be supplied.]
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() {
            return TypeDescriptor.GetDefaultProperty(this, true);
        } 

        ///  
        ///  
        /// 
        /// Retrieves the an editor for this object. 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        Object ICustomTypeDescriptor.GetEditor(Type editorBaseType) {
            if (editorBaseType != typeof(ComponentEditor)) 
                return null;
 
            if (editor != null) 
                return editor;
 
            if (editor == null && HasPropertyPages())
                editor = new AxComponentEditor();

            return editor; 
        }
 
        ///  
        /// 
        ///  
        /// [To be supplied.]
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { 
            return TypeDescriptor.GetEvents(this, true);
        } 
 
        /// 
        ///  
        /// 
        /// [To be supplied.]
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) {
            return TypeDescriptor.GetEvents(this, attributes, true); 
        } 

        private void OnIdle(object sender, EventArgs e) { 
            if (axState[refreshProperties]) {
                TypeDescriptor.Refresh(this.GetType());
            }
        } 

        private bool RefreshAllProperties { 
            get { 
                return axState[refreshProperties];
            } 
            set {
                axState[refreshProperties] = value;
                if (value && !axState[listeningToIdle]) {
                    Application.Idle += new EventHandler(this.OnIdle); 
                    axState[listeningToIdle] = true;
                } 
                else if (!value && axState[listeningToIdle]) { 
                    Application.Idle -= new EventHandler(this.OnIdle);
                    axState[listeningToIdle] = false; 
                }
            }
        }
 
        private PropertyDescriptorCollection FillProperties(Attribute[] attributes) {
            if (RefreshAllProperties) { 
                RefreshAllProperties = false; 
                propsStash = null;
                attribsStash = null; 
            }
            else if (propsStash != null) {
                if (attributes == null && attribsStash == null) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Returning stashed values for : " + ""); 
                    return propsStash;
                } 
                else if (attributes != null && attribsStash != null && attributes.Length == attribsStash.Length) { 
                    bool attribsEqual = true;
                    int i = 0; 
                    foreach(Attribute attrib in attributes) {
                        if (!attrib.Equals(attribsStash[i++])) {
                            attribsEqual = false;
                            break; 
                        }
                    } 
 
                    if (attribsEqual) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Returning stashed values for : " + attributes.Length); 
                        return propsStash;
                    }
                }
            } 

            ArrayList retProps = new ArrayList(); 
 
            if (properties == null)
                properties = new Hashtable(); 

            if (propertyInfos == null) {
                propertyInfos = new Hashtable();
 
                PropertyInfo[] propInfos = this.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
 
                foreach(PropertyInfo propInfo in propInfos) 
                    propertyInfos.Add(propInfo.Name, propInfo);
            } 

            PropertyDescriptorCollection baseProps = TypeDescriptor.GetProperties(this, null, true);
            if (baseProps != null) {
                for (int i = 0; i < baseProps.Count; ++i) { 
                    Debug.Assert(baseProps[i] != null, "Null base prop at location: " + i.ToString(CultureInfo.InvariantCulture));
 
                    if (baseProps[i].DesignTimeOnly) { 
                        retProps.Add(baseProps[i]);
                        continue; 
                    }

                    string propName = baseProps[i].Name;
                    PropertyDescriptor prop = null; 
                    PropertyInfo propInfo = (PropertyInfo)propertyInfos[propName];
 
                    // We do not support "write-only" properties that some activex controls support. 
                    if (propInfo != null && !propInfo.CanRead)
                        continue; 

                    if (!properties.ContainsKey(propName)) {
                        if (propInfo != null) {
                            Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Added AxPropertyDescriptor for: " + propName); 
                            prop = new AxPropertyDescriptor(baseProps[i], this);
                            ((AxPropertyDescriptor)prop).UpdateAttributes(); 
                        } 
                        else {
                            Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Added PropertyDescriptor for: " + propName); 
                            prop = baseProps[i];
                        }
                        properties.Add(propName, prop);
                        retProps.Add(prop); 
                    }
                    else { 
                        PropertyDescriptor propDesc = (PropertyDescriptor)properties[propName]; 
                        Debug.Assert(propDesc != null, "Cannot find cached entry for: " + propName);
                        AxPropertyDescriptor axPropDesc = propDesc as AxPropertyDescriptor; 
                        if ((propInfo == null && axPropDesc != null) || (propInfo != null && axPropDesc == null)) {
                            Debug.Fail("Duplicate property with same name: " + propName);
                            Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Duplicate property with same name: " + propName);
                        } 
                        else {
                            if (axPropDesc != null) { 
                                axPropDesc.UpdateAttributes(); 
                            }
                            retProps.Add(propDesc); 
                        }
                    }
                }
 
                // Filter only the Browsable attribute, since that is the only
                // one we mess with. 
                // 
                if (attributes != null) {
                    Attribute browse = null; 
                    foreach(Attribute attr in attributes) {
                        if (attr is BrowsableAttribute) {
                            browse = attr;
                        } 
                    }
 
                    if (browse != null) { 
                        ArrayList removeList = null;
 
                        foreach(PropertyDescriptor prop in retProps) {
                            if (prop is AxPropertyDescriptor) {
                                Attribute attr = prop.Attributes[typeof(BrowsableAttribute)];
                                if (attr != null && !attr.Equals(browse)) { 
                                    if (removeList == null) {
                                        removeList = new ArrayList(); 
                                    } 
                                    removeList.Add(prop);
                                } 
                            }
                        }

                        if (removeList != null) { 
                            foreach(object prop in removeList)
                                retProps.Remove(prop); 
                        } 
                    }
                } 
            }

            PropertyDescriptor[] temp = new PropertyDescriptor[retProps.Count];
            retProps.CopyTo(temp, 0); 

            // Update our stashed values. 
            // 
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Updating stashed values for : " + ((attributes != null) ? attributes.Length.ToString(CultureInfo.InvariantCulture) : ""));
            propsStash = new PropertyDescriptorCollection(temp); 
            attribsStash = attributes;

            return propsStash;
        } 

        ///  
        ///  
        /// 
        /// [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() {
            return FillProperties(null); 
        }
 
        ///  
        /// 
        ///  
        /// [To be supplied.]
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { 
            return FillProperties(attributes);
        } 
 
        /// 
        ///  
        /// 
        /// [To be supplied.]
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        Object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) {
            return this; 
        } 

        private AxPropertyDescriptor GetPropertyDescriptorFromDispid(int dispid) { 
            Debug.Assert(dispid != NativeMethods.ActiveX.DISPID_UNKNOWN, "Wrong dispid sent to GetPropertyDescriptorFromDispid");

            PropertyDescriptorCollection props = FillProperties(null);
            foreach (PropertyDescriptor prop in props) { 
                AxPropertyDescriptor axprop = prop as AxPropertyDescriptor;
                if (axprop != null && axprop.Dispid == dispid) { 
                        return axprop; 
                }
            } 

            return null;
        }
 
#if false
        // FxCop: Currently not used 
        private void CheckThreadingModel() { 
#if DEBUG
            if (AxIgnoreTMSwitch.Enabled) return; 
#endif
            if ((flags & AxFlags.IgnoreThreadModel) != 0) return;

            bool singleThreaded = true; 

            new RegistryPermission(PermissionState.Unrestricted).Assert(); 
            try { 
                try {
                    using (RegistryKey rk = Registry.ClassesRoot.OpenSubKey("CLSID\\" + clsid.ToString() + "\\InprocServer32", /*writable*/false)) { 
                        object value = rk.GetValue("ThreadingModel");

                        if (value != null && value is string) {
                            if (value.Equals("Both") 
                                || value.Equals("Apartment")
                                || value.Equals("Free")) { 
 
                                singleThreaded = false;
                            } 
                        }
                    }
                }
                catch (Exception t) { 
                    Debug.Fail(t.ToString());
                    throw new InvalidOperationException(SR.GetString(SR.AXNoThreadInfo)); 
                } 
            }
            finally { 
                System.Security.CodeAccessPermission.RevertAssert();
            }

            if (singleThreaded) { 
                throw new InvalidOperationException(SR.GetString(SR.AXSingleThreaded));
            } 
        } 
#endif
 
        private void ActivateAxControl() {
            if (QuickActivate()) {
                DepersistControl();
            } 
            else {
                SlowActivate(); 
            } 

            SetOcState(OC_RUNNING); 
        }


        private void DepersistFromIPropertyBag(UnsafeNativeMethods.IPropertyBag propBag) { 
            iPersistPropBag.Load(propBag, null);
        } 
 
        private void DepersistFromIStream(UnsafeNativeMethods.IStream istream) {
            storageType = STG_STREAM; 
            iPersistStream.Load(istream);
        }

        private void DepersistFromIStreamInit(UnsafeNativeMethods.IStream istream) { 
            storageType = STG_STREAMINIT;
            iPersistStreamInit.Load(istream); 
        } 

        private void DepersistFromIStorage(UnsafeNativeMethods.IStorage storage) { 
            storageType = STG_STORAGE;

            // ASURT 65913 Looks like MapPoint control does not create a valid IStorage
            // until some property has changed. Since we end up creating a bogus (empty) 
            // storage, we end up not being able to re-create a valid one and this would
            // fail. 
            // 
            if (storage != null) {
                int hr = iPersistStorage.Load(storage); 
                if (hr != NativeMethods.S_OK) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Error trying load depersist from IStorage: " + hr);
                }
            } 
        }
 
        private void DepersistControl() { 
            Freeze(true);
 
            if (ocxState == null) {
                // must init new:
                //
                if (instance is UnsafeNativeMethods.IPersistStreamInit) { 
                    iPersistStreamInit = (UnsafeNativeMethods.IPersistStreamInit) instance;
                    try { 
                        storageType = STG_STREAMINIT; 
                        iPersistStreamInit.InitNew();
                    } 
                    catch (Exception e1) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistStreamInit.InitNew(). Is this good?"  + e1.ToString());
                    }
                    return; 
                }
                if (instance is UnsafeNativeMethods.IPersistStream) { 
                    storageType = STG_STREAM; 
                    iPersistStream = (UnsafeNativeMethods.IPersistStream) instance;
                    return; 
                }
                if (instance is UnsafeNativeMethods.IPersistStorage) {
                    storageType = STG_STORAGE;
                    ocxState = new State(this); 
                    iPersistStorage = (UnsafeNativeMethods.IPersistStorage) instance;
                    try { 
                        iPersistStorage.InitNew(ocxState.GetStorage()); 
                    }
                    catch (Exception e2) { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistStorage.InitNew(). Is this good?"  + e2.ToString());
                    }
                    return;
                } 
                if (instance is UnsafeNativeMethods.IPersistPropertyBag) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, this + " supports IPersistPropertyBag."); 
                    iPersistPropBag = (UnsafeNativeMethods.IPersistPropertyBag) instance; 
                    try {
                        iPersistPropBag.InitNew(); 
                    }
                    catch (Exception e1) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistPropertyBag.InitNew(). Is this good?"  + e1.ToString());
                    } 
                }
 
                Debug.Fail("no implemented persitance interfaces on object"); 
                throw new InvalidOperationException(SR.GetString(SR.UnableToInitComponent));
            } 

            // Otherwise, we have state to deperist from:
            switch (ocxState.Type) {
                case STG_STREAM: 
                    try {
                        iPersistStream = (UnsafeNativeMethods.IPersistStream) instance; 
                        DepersistFromIStream(ocxState.GetStream()); 
                    }
                    catch (Exception e) { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistStream.DepersistFromIStream(). Is this good?"  + e.ToString());
                    }
                    break;
                case STG_STREAMINIT: 
                    if (instance is UnsafeNativeMethods.IPersistStreamInit) {
                        try { 
                            iPersistStreamInit = (UnsafeNativeMethods.IPersistStreamInit) instance; 
                            DepersistFromIStreamInit(ocxState.GetStream());
                        } 
                        catch (Exception e) {
                            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistStreamInit.DepersistFromIStreamInit(). Is this good?"  + e.ToString());
                        }
                        GetControlEnabled(); 
                    }
                    else { 
                        ocxState.Type = STG_STREAM; 
                        DepersistControl();
                        return; 
                    }
                    break;
                case STG_STORAGE:
                    try { 
                        iPersistStorage = (UnsafeNativeMethods.IPersistStorage) instance;
                        DepersistFromIStorage(ocxState.GetStorage()); 
                    } 
                    catch (Exception e) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistStorage.DepersistFromIStorage(). Is this good?"  + e.ToString()); 
                    }
                    break;
                default:
                    Debug.Fail("unknown storage type."); 
                    throw new InvalidOperationException(SR.GetString(SR.UnableToInitComponent));
            } 
 
            if (ocxState.GetPropBag() != null) {
                try { 
                    iPersistPropBag = (UnsafeNativeMethods.IPersistPropertyBag)instance;
                    DepersistFromIPropertyBag(ocxState.GetPropBag());
                }
                catch (Exception e) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Exception thrown trying to IPersistPropertyBag.DepersistFromIPropertyBag(). Is this good?"  + e.ToString());
                } 
            } 
        }
 
        /// 
        /// 
        ///     Returns the IUnknown pointer to the enclosed ActiveX control.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        public object GetOcx() { 
            return instance;
        } 

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        private Object GetOcxCreate() {
            if (instance == null) { 
                CreateInstance();
                RealizeStyles(); 
                AttachInterfaces(); 
                oleSite.OnOcxCreate();
            } 
            return instance;
        }

        private void StartEvents() { 
            if (!axState[sinkAttached]) {
                try { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Creating sink for events..."); 
                    CreateSink();
                    oleSite.StartEvents(); 
                }
                catch (Exception t) {
                    Debug.Fail(t.ToString());
                } 
                axState[sinkAttached] = true;
            } 
        } 

        private void StopEvents() { 
            if (axState[sinkAttached]) {
                try {
                    DetachSink();
                } 
                catch (Exception t) {
                    Debug.Fail(t.ToString()); 
                } 
                axState[sinkAttached] = false;
            } 
            oleSite.StopEvents();
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void CreateSink() { 
                // nop...  windows forms wrapper will override...
        }

 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected virtual void DetachSink() {
                // nop...  windows forms wrapper will override...
        }
 

        private bool CanShowPropertyPages() { 
            if (GetOcState() < OC_RUNNING) return false; 
            return(GetOcx() is NativeMethods.ISpecifyPropertyPages);
        } 


        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public bool HasPropertyPages() { 
            if (!CanShowPropertyPages()) return false;
            NativeMethods.ISpecifyPropertyPages ispp = (NativeMethods.ISpecifyPropertyPages) GetOcx(); 
            try {
                NativeMethods.tagCAUUID uuids = new NativeMethods.tagCAUUID();
                try {
                    ispp.GetPages(uuids); 
                    if (uuids.cElems > 0) return true;
                } 
                finally { 
                    if (uuids.pElems != IntPtr.Zero) {
                        Marshal.FreeCoTaskMem(uuids.pElems); 
                    }
                }
            }
            catch { 
            }
            return false; 
        } 

        unsafe private void ShowPropertyPageForDispid(int dispid, Guid guid) { 
            try {
                IntPtr pUnk = Marshal.GetIUnknownForObject(GetOcx());
                NativeMethods.OCPFIPARAMS opcparams = new NativeMethods.OCPFIPARAMS();
                opcparams.hwndOwner = (ContainingControl == null) ? IntPtr.Zero : ContainingControl.Handle; 
                opcparams.lpszCaption = Name;
                opcparams.ppUnk = (IntPtr) (long) &pUnk; 
                opcparams.uuid = (IntPtr)(long) &guid; 
                opcparams.dispidInitial = dispid;
                UnsafeNativeMethods.OleCreatePropertyFrameIndirect(opcparams); 
            }
            catch (Exception t) {
                Debug.Fail(t.ToString());
                throw t; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public void MakeDirty() { 
            ISite isite = Site;
            if (isite == null) 
                return; 

            IComponentChangeService ccs = (IComponentChangeService)isite.GetService(typeof(IComponentChangeService)); 
            if (ccs == null)
                return;

            ccs.OnComponentChanging(this, null); 

            ccs.OnComponentChanged(this, null, null, null); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public void ShowPropertyPages() { 
            if (ParentInternal == null) return;
            if (!ParentInternal.IsHandleCreated) return; 
            ShowPropertyPages(ParentInternal); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public void ShowPropertyPages(Control control) {
            try { 
                if (!CanShowPropertyPages()) return; 
                NativeMethods.ISpecifyPropertyPages ispp = (NativeMethods.ISpecifyPropertyPages) GetOcx();
                NativeMethods.tagCAUUID uuids = new NativeMethods.tagCAUUID(); 
                try {
                    ispp.GetPages(uuids);
                    if (uuids.cElems <= 0) return;
                } 
                catch {
                    return; 
                } 

                // State oldOcxState = OcxState; 

                IDesignerHost host = null;
                if (Site != null)
                    host = (IDesignerHost)Site.GetService(typeof(IDesignerHost)); 

                DesignerTransaction trans = null; 
                try { 
                    if (host != null)
                        trans = host.CreateTransaction(SR.GetString(SR.AXEditProperties)); 

                    string name = null;
                    object o = GetOcx();
                    IntPtr handle = (ContainingControl == null) ? IntPtr.Zero : ContainingControl.Handle; 
                    SafeNativeMethods.OleCreatePropertyFrame(new HandleRef(this, handle), 0, 0, name, 1, ref o, uuids.cElems, new HandleRef(null, uuids.pElems), Application.CurrentCulture.LCID, 0, IntPtr.Zero);
                } 
                finally { 
                    if (oleSite != null)
                        ((UnsafeNativeMethods.IPropertyNotifySink)oleSite).OnChanged(NativeMethods.MEMBERID_NIL); 

                    if (trans != null)
                        trans.Commit();
 
                    if (uuids.pElems != IntPtr.Zero)
                        Marshal.FreeCoTaskMem(uuids.pElems); 
                } 
            }
            catch (Exception t) { 
                Debug.Fail(t.ToString());
                throw t;
            }
        } 

 
        internal override IntPtr InitializeDCForWmCtlColor (IntPtr dc, int msg) 
        {
            if (isMaskEdit) { 
                return base.InitializeDCForWmCtlColor(dc, msg);
            }
            else {
                return IntPtr.Zero; // bypass Control's anti-reflect logic 
            }
        } 
 
        /// 
        ///  
        ///     AxHost wndProc. All messages are sent to wndProc after getting filtered
        ///     through the preProcessMessage function.
        ///     Certain messages are forwarder directly to the ActiveX control,
        ///     others are first processed by the wndProc of Control 
        /// 
 
        protected override void WndProc(ref Message m) { 

#pragma warning disable 162, 429 
// Ignore the warnings generated by the following code (unreachable code, and unreachable expression)
            if (false && (axState[manualUpdate] && IsUserMode())) {
                DefWndProc(ref m);
                return; 
            }
#pragma warning restore 162, 429 
 
            switch (m.Msg) {
                // Things we explicitly ignore and pass to the ocx's windproc 
                case NativeMethods.WM_ERASEBKGND:

                case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFYFORMAT:
 
                case NativeMethods.WM_SETCURSOR:
                case NativeMethods.WM_SYSCOLORCHANGE: 
 
                // Some of the MSComCtl controls respond to this message
                // to do some custom painting. So, we should just pass this message 
                // through.
                //
                case NativeMethods.WM_DRAWITEM:
 
                case NativeMethods.WM_LBUTTONDBLCLK:
                case NativeMethods.WM_LBUTTONUP: 
                case NativeMethods.WM_MBUTTONDBLCLK: 
                case NativeMethods.WM_MBUTTONUP:
                case NativeMethods.WM_RBUTTONDBLCLK: 
                case NativeMethods.WM_RBUTTONUP:
                    DefWndProc(ref m);
                    break;
 
                case NativeMethods.WM_LBUTTONDOWN:
                case NativeMethods.WM_MBUTTONDOWN: 
                case NativeMethods.WM_RBUTTONDOWN: 
                    if (IsUserMode()) {
                        Focus(); 
                    }
                    DefWndProc(ref m);
                    break;
 
                case NativeMethods.WM_KILLFOCUS:
                { 
                    hwndFocus = m.WParam; 
                    try {
                        base.WndProc(ref m); 
                    }
                    finally {
                         hwndFocus = IntPtr.Zero;
                    } 
                    break;
                } 
 
                case NativeMethods.WM_COMMAND:
                    if (!ReflectMessageInternal(m.LParam, ref m)) 
                        DefWndProc(ref m);
                    break;

                case NativeMethods.WM_CONTEXTMENU: 
                    DefWndProc(ref m);
                    break; 
 
                case NativeMethods.WM_DESTROY:
#if DEBUG 
                    if (!OwnWindow()) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "WM_DESTROY naughty control is destroying the window from under us..." + GetType().ToString());
                    }
#endif 
                    //
                    // If we are currently in a state of InPlaceActive or above, 
                    // we should first reparent the ActiveX control to our parking 
                    // window before we transition to a state below InPlaceActive.
                    // Otherwise we face all sorts of problems when we try to 
                    // transition back to a state >= InPlaceActive.
                    //
                    if (GetOcState() >= OC_INPLACE) {
                        UnsafeNativeMethods.IOleInPlaceObject ipo = GetInPlaceObject(); 
                        IntPtr hwnd;
                        if (NativeMethods.Succeeded(ipo.GetWindow(out hwnd))) { 
                            Application.ParkHandle(new HandleRef(ipo, hwnd)); 
                        }
                    } 

                    bool visible = GetState(STATE_VISIBLE);

                    TransitionDownTo(OC_RUNNING); 
                    DetachAndForward(ref m);
 
                    if (visible != GetState(STATE_VISIBLE)) { 
                        SetState(STATE_VISIBLE, visible);
                    } 

                    break;
                case NativeMethods.WM_HELP:
                    // We want to both fire the event, and let the ocx have the message... 
                    base.WndProc(ref m);
                    DefWndProc(ref m); 
                    break; 

                case NativeMethods.WM_KEYUP: 
                    if (axState[processingKeyUp])
                        break;

                    axState[processingKeyUp] = true; 
                    try {
                        if (PreProcessControlMessage(ref m) != PreProcessControlState.MessageProcessed) 
                            DefWndProc(ref m); 
                    }
                    finally { 
                        axState[processingKeyUp] = false;
                    }

                    break; 

                case NativeMethods.WM_NCDESTROY: 
#if DEBUG 
                    if (!OwnWindow()) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "WM_NCDESTROY naughty control is destroying the window from under us..." + GetType().ToString()); 
                    }
#endif
                    // need to detach it now...
                    DetachAndForward(ref m); 
                    break;
 
                default: 
                    if (m.Msg == REGMSG_MSG) {
                        m.Result = (IntPtr)REGMSG_RETVAL; 
                        return;
                    }
                    // Other things we may care about and we will pass them to the Control's wndProc
                    base.WndProc(ref m); 
                    break;
            } 
        } 

        private void DetachAndForward(ref Message m) { 
            IntPtr handle = GetHandleNoCreate();
            DetachWindow();
            if (handle != IntPtr.Zero) {
                IntPtr wndProc = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, handle), NativeMethods.GWL_WNDPROC); 
                m.Result = UnsafeNativeMethods.CallWindowProc(wndProc, handle, m.Msg, m.WParam, m.LParam);
            } 
        } 

        private void DetachWindow() { 
            if (IsHandleCreated) {
                OnHandleDestroyed(EventArgs.Empty);
                for (Control c = this; c != null; c = c.ParentInternal) {
                    /* NOT NEEDED 
                    if (c.GetAxState(STATE_HANDLEHOOK)) {
                        ((IHandleHook)c.Site.GetService(IHandleHook.class)).OnDestroyHandle(GetHandle()); 
                        break; 
                    }
                    */ 
                }
                this.WindowReleaseHandle();
            }
        } 

        private void InformOfNewHandle() { 
            Debug.Assert(IsHandleCreated, "we got to have a handle to be here..."); 
            for (Control c = this; c != null; c = c.ParentInternal) {
                /* NOT NEEDED 
                if (c.GetAxState(STATE_HANDLEHOOK)) {
                    ((IHandleHook)c.Site.GetService(IHandleHook.class)).OnCreateHandle(GetHandle());
                    break;
                } 
                */
            } 
            wndprocAddr = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, Handle), NativeMethods.GWL_WNDPROC); 
            /* NOT NEEDED
            SetAxState(STATE_CREATENOTIFIED, true); 
            */
        }

        private void AttachWindow(IntPtr hwnd) { 
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "attaching window for "+this.ToString()+" "+hwnd.ToString());
            if (!axState[fFakingWindow]) { 
                this.WindowAssignHandle(hwnd, axState[assignUniqueID]); 
            }
            UpdateZOrder(); 

            // Get the latest bounds set by the user.
            Size setExtent = Size;
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "SetBounds " + setExtent.ToString()); 

            // Get the default bounds set by the ActiveX control. 
            UpdateBounds(); 
            Size ocxExtent = GetExtent();
            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "OcxBounds " + ocxExtent.ToString()); 

            Point location = Location;

            // Choose the setBounds unless it is smaller than the default bounds. 
            if (setExtent.Width < ocxExtent.Width || setExtent.Height < ocxExtent.Height)
                Bounds = new Rectangle(location.X, location.Y, ocxExtent.Width, ocxExtent.Height); 
            else { 
                Size newSize = SetExtent(setExtent.Width, setExtent.Height);
                if (!newSize.Equals(setExtent)) { 
                    Bounds = new Rectangle(location.X, location.Y, newSize.Width, newSize.Height);
                }
            }
 
            OnHandleCreated(EventArgs.Empty);
            InformOfNewHandle(); 
        } 

        ///  
        /// 
        ///     Inheriting classes should override this method to find out when the
        ///     handle has been created.
        ///     Call base.OnHandleCreated first. 
        /// 
        protected override void OnHandleCreated(EventArgs e) { 
            // ASURT 43741 This is needed to prevent some controls (for e.g. Office Web Components) from 
            // failing to InPlaceActivate() when they call RegisterDragDrop() but do not call
            // OleInitialize(). The EE calls CoInitializeEx() on the thread, but I believe 
            // that is not good enough for DragDrop.
            //
            if (Application.OleRequired() != System.Threading.ApartmentState.STA) {
                throw new ThreadStateException(SR.GetString(SR.ThreadMustBeSTA)); 
            }
 
            SetAcceptDrops(AllowDrop); 
            RaiseCreateHandleEvent(e);
        } 

        /// 
        [AttributeUsage(AttributeTargets.Class, Inherited = false)]
        public sealed class ClsidAttribute : Attribute { 
            private String val;
 
            ///  
            public ClsidAttribute(String clsid) {
                val = clsid; 
            }

            /// 
            public String Value { 
                get {
                    return val; 
                } 
            }
        } 

        /// 
        [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
        public sealed class TypeLibraryTimeStampAttribute : Attribute { 
            private DateTime val;
 
            ///  
            public TypeLibraryTimeStampAttribute(string timestamp) {
                val = DateTime.Parse(timestamp, CultureInfo.InvariantCulture); 
            }

            /// 
            public DateTime Value { 
                get {
                    return val; 
                } 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")] 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] 
        public class ConnectionPointCookie {
            private UnsafeNativeMethods.IConnectionPoint connectionPoint; 
            private int cookie;
            internal int threadId;
#if DEBUG
            private string callStack; 
#endif
            ///  
            ///  
            /// Creates a connection point to of the given interface type.
            /// which will call on a managed code sink that implements that interface. 
            /// 
            public ConnectionPointCookie(object source, object sink, Type eventInterface)
                : this(source, sink, eventInterface, true) {
            } 

            internal ConnectionPointCookie(object source, object sink, Type eventInterface, bool throwException) { 
                if (source is UnsafeNativeMethods.IConnectionPointContainer) { 
                    UnsafeNativeMethods.IConnectionPointContainer cpc = (UnsafeNativeMethods.IConnectionPointContainer)source;
 
                    try {
                        Guid tmp = eventInterface.GUID;
                        if (cpc.FindConnectionPoint(ref tmp, out connectionPoint) != NativeMethods.S_OK) {
                            connectionPoint = null; 
                        }
                    } 
                    catch { 
                        connectionPoint = null;
                    } 

                    if (connectionPoint == null) {
                        if (throwException) {
                            throw new ArgumentException(SR.GetString(SR.AXNoEventInterface, eventInterface.Name)); 
                        }
                    } 
                    else if (sink == null || !eventInterface.IsInstanceOfType(sink)) { 
                        if (throwException) {
                            throw new InvalidCastException(SR.GetString(SR.AXNoSinkImplementation, eventInterface.Name)); 
                        }
                    }
                    else {
                        int hr = connectionPoint.Advise(sink, ref cookie); 
                        if (hr == NativeMethods.S_OK) {
                            threadId = Thread.CurrentThread.ManagedThreadId; 
                        } 
                        else {
                            cookie = 0; 
                            Marshal.ReleaseComObject(connectionPoint);
                            connectionPoint = null;
                            if (throwException) {
                                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.AXNoSinkAdvise, eventInterface.Name), hr)); 
                            }
                        } 
                    } 
                }
                else { 
                    if (throwException) {
                        throw new InvalidCastException(SR.GetString(SR.AXNoConnectionPointContainer));
                    }
                } 

 
                if (connectionPoint == null || cookie == 0) { 
                    if (connectionPoint != null) {
                        Marshal.ReleaseComObject(connectionPoint); 
                    }

                    if (throwException) {
                        throw new ArgumentException(SR.GetString(SR.AXNoConnectionPoint, eventInterface.Name)); 
                    }
                } 
#if DEBUG 
                new EnvironmentPermission(PermissionState.Unrestricted).Assert();
                try { 
                    callStack = Environment.StackTrace;
                }
                finally {
                    System.Security.CodeAccessPermission.RevertAssert(); 
                }
#endif 
            } 

            ///  
            /// 
            /// Disconnect the current connection point.  If the object is not connected,
            /// this method will do nothing.
            ///  
            public void Disconnect() {
                if (connectionPoint != null && cookie != 0) { 
                    try { 
                        connectionPoint.Unadvise(cookie);
                    } 
                    catch (Exception ex) {
                        if (ClientUtils.IsCriticalException(ex)) {
                            throw;
                        } 
                    }
                    finally { 
                        cookie = 0; 
                    }
 
                    try {
                        Marshal.ReleaseComObject(connectionPoint);
                    }
                    catch (Exception ex) { 
                        if (ClientUtils.IsCriticalException(ex)) {
                            throw; 
                        } 
                    }
                    finally { 
                        connectionPoint = null;
                    }
                }
            } 

            ///  
            ///  
            ~ConnectionPointCookie(){
                if (connectionPoint != null && cookie != 0) { 
                    if (!AppDomain.CurrentDomain.IsFinalizingForUnload()) {
                        SynchronizationContext context = SynchronizationContext.Current;
                        if (context == null) {
                            Debug.Fail("Attempted to disconnect ConnectionPointCookie from the finalizer with no SynchronizationContext."); 
                        }
                        else { 
                            context.Post(new SendOrPostCallback(AttemptDisconnect), null); 
                        }
                    } 
                }
            }

            void AttemptDisconnect(object trash) { 
                if (threadId == Thread.CurrentThread.ManagedThreadId) {
                    Disconnect(); 
                } 
                else {
                    Debug.Fail("Attempted to disconnect ConnectionPointCookie from the wrong thread (finalizer)."); 
                }
            }

            internal bool Connected { 
                get {
                    return connectionPoint != null && cookie != 0; 
                } 
            }
        } 

        /// 
        public enum ActiveXInvokeKind {
            ///  
            MethodInvoke,
            ///  
            PropertyGet, 
            /// 
            PropertySet 
        }

        /// 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")] 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")]
        public class InvalidActiveXStateException : Exception { 
            private string name; 
            private ActiveXInvokeKind kind;
 
            /// 
            public InvalidActiveXStateException(string name, ActiveXInvokeKind kind) {
                this.name = name;
                this.kind = kind; 
            }
 
            ///  
            public InvalidActiveXStateException() {
            } 

            /// 
            public override string ToString() {
                switch (kind) { 
                    case ActiveXInvokeKind.MethodInvoke:
                        return SR.GetString(SR.AXInvalidMethodInvoke, name); 
                    case ActiveXInvokeKind.PropertyGet: 
                        return SR.GetString(SR.AXInvalidPropertyGet, name);
                    case ActiveXInvokeKind.PropertySet: 
                        return SR.GetString(SR.AXInvalidPropertySet, name);
                    default:
                        return base.ToString();
                } 
            }
        } 
 
        // This private class encapsulates all of the ole interfaces so that users
        // will not be able to access and call them directly... 

        /// 
        /// 
        private class OleInterfaces 
            : UnsafeNativeMethods.IOleControlSite, UnsafeNativeMethods.IOleClientSite, UnsafeNativeMethods.IOleInPlaceSite, UnsafeNativeMethods.ISimpleFrameSite, UnsafeNativeMethods.IVBGetControl, UnsafeNativeMethods.IGetVBAObject, UnsafeNativeMethods.IPropertyNotifySink, IReflect {
 
            private AxHost host; 
            private ConnectionPointCookie connectionPoint;
 
            internal OleInterfaces(AxHost host) {
                if (host == null)
                    throw new ArgumentNullException("host");
                this.host = host; 
            }
 
            ~OleInterfaces() { 
                if (!AppDomain.CurrentDomain.IsFinalizingForUnload()) {
                    SynchronizationContext context = SynchronizationContext.Current; 
                    if (context == null) {
                        Debug.Fail("Attempted to disconnect ConnectionPointCookie from the finalizer with no SynchronizationContext.");
                    }
                    else { 
                        context.Post(new SendOrPostCallback(AttemptStopEvents), null);
                    } 
                } 
            }
 
            internal AxHost GetAxHost() {
                return host;
            }
 
            internal void OnOcxCreate() {
                StartEvents(); 
            } 

            internal void StartEvents() { 
                if (connectionPoint != null)
                    return;

                Object nativeObject = host.GetOcx(); 

                try { 
                    connectionPoint = new ConnectionPointCookie(nativeObject, this, typeof(UnsafeNativeMethods.IPropertyNotifySink)); 
                }
                catch { 
                }
            }

            void AttemptStopEvents(object trash) { 
                if (connectionPoint.threadId == Thread.CurrentThread.ManagedThreadId) {
                    StopEvents(); 
                } 
                else {
                    Debug.Fail("Attempted to disconnect ConnectionPointCookie from the wrong thread (finalizer)."); 
                }
            }

            internal void StopEvents() { 
                if (connectionPoint != null) {
                    connectionPoint.Disconnect(); 
                    connectionPoint = null; 
                }
            } 

            // IGetVBAObject methods:

            int UnsafeNativeMethods.IGetVBAObject.GetObject(ref Guid riid, UnsafeNativeMethods.IVBFormat[] rval, int dwReserved) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetObject");
 
                if (rval == null || riid.Equals(Guid.Empty)) 
                    return NativeMethods.E_INVALIDARG;
 
                if (riid.Equals(ivbformat_Guid)) {
                    rval[0] = new VBFormat();
                    return NativeMethods.S_OK;
                } 
                else {
                    rval[0] = null; 
                    return NativeMethods.E_NOINTERFACE; 
                }
            } 

            // IVBGetControl methods:

            int UnsafeNativeMethods.IVBGetControl.EnumControls(int dwOleContF, int dwWhich, out UnsafeNativeMethods.IEnumUnknown ppenum) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in EnumControls");
                ppenum = null; 
                ppenum = host.GetParentContainer().EnumControls(host, dwOleContF, dwWhich); 
                return NativeMethods.S_OK;
            } 

            // ISimpleFrameSite methods:

            int UnsafeNativeMethods.ISimpleFrameSite.PreMessageFilter(IntPtr hwnd, int msg, IntPtr wp, IntPtr lp, ref IntPtr plResult, ref int pdwCookie) { 
                return NativeMethods.S_OK;
            } 
 
            int UnsafeNativeMethods.ISimpleFrameSite.PostMessageFilter(IntPtr hwnd, int msg, IntPtr wp, IntPtr lp, ref IntPtr plResult, int dwCookie) {
                return NativeMethods.S_FALSE; 
            }

            // IReflect methods:
 
            MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr,Binder binder, Type[] types,ParameterModifier[] modifiers) {
                return null; 
            } 

            MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr) { 
                return null;
            }

            MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) { 
                return new MethodInfo[0];
            } 
 
            FieldInfo IReflect.GetField(String name, BindingFlags bindingAttr) {
                return null; 
            }

            FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) {
                return new FieldInfo[0]; 
            }
 
            PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr) { 
                return null;
            } 

            PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) {
                return null;
            } 

            PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) { 
                return new PropertyInfo[0]; 
            }
 
            MemberInfo[] IReflect.GetMember(String name, BindingFlags bindingAttr) {
                return new MemberInfo[0];
            }
 
            MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) {
                return new MemberInfo[0]; 
            } 

            Object IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, 
                                                    Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) {
                if (name.StartsWith("[DISPID=")) {
                    int endIndex = name.IndexOf("]");
                    int dispid = Int32.Parse(name.Substring(8, endIndex - 8), CultureInfo.InvariantCulture); 
                    object ambient = host.GetAmbientProperty(dispid);
                    if (ambient != null) return ambient; 
                } 

                throw E_FAIL; 
            }

            Type IReflect.UnderlyingSystemType {
                get { 
                    return null;
                } 
            } 

            // IOleControlSite methods: 


            int UnsafeNativeMethods.IOleControlSite.OnControlInfoChanged() {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnControlInfoChanged"); 
                return NativeMethods.S_OK;
            } 
 
            int UnsafeNativeMethods.IOleControlSite.LockInPlaceActive(int fLock) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in LockInPlaceActive"); 
                return NativeMethods.E_NOTIMPL;
            }

            int UnsafeNativeMethods.IOleControlSite.GetExtendedControl(out object ppDisp) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetExtendedControl " + host.ToString());
                ppDisp = host.GetParentContainer().GetProxyForControl(host); 
                if (ppDisp == null) 
                    return NativeMethods.E_NOTIMPL;
 
                return NativeMethods.S_OK;
            }

            int UnsafeNativeMethods.IOleControlSite.TransformCoords(NativeMethods._POINTL pPtlHimetric, NativeMethods.tagPOINTF pPtfContainer, int dwFlags) { 
                int hr = SetupLogPixels(false);
                if (NativeMethods.Failed(hr)) 
                    return hr; 

                if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_HIMETRICTOCONTAINER)  != 0) { 
                    if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_SIZE) != 0) {
                        pPtfContainer.x = (float) host.HM2Pix(pPtlHimetric.x, logPixelsX);
                        pPtfContainer.y = (float) host.HM2Pix(pPtlHimetric.y, logPixelsY);
                    } 
                    else if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_POSITION) != 0) {
                        pPtfContainer.x = (float) host.HM2Pix(pPtlHimetric.x, logPixelsX); 
                        pPtfContainer.y = (float) host.HM2Pix(pPtlHimetric.y, logPixelsY); 
                    }
                    else { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose,"\t dwFlags not supported: " + dwFlags);
                        return NativeMethods.E_INVALIDARG;
                    }
                } 
                else if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_CONTAINERTOHIMETRIC) != 0) {
                    if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_SIZE) != 0) { 
                        pPtlHimetric.x = host.Pix2HM((int)pPtfContainer.x, logPixelsX); 
                        pPtlHimetric.y = host.Pix2HM((int)pPtfContainer.y, logPixelsY);
                    } 
                    else if ((dwFlags & NativeMethods.ActiveX.XFORMCOORDS_POSITION) != 0) {
                        pPtlHimetric.x = host.Pix2HM((int)pPtfContainer.x, logPixelsX);
                        pPtlHimetric.y = host.Pix2HM((int)pPtfContainer.y, logPixelsY);
                    } 
                    else {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t dwFlags not supported: " + dwFlags); 
                        return NativeMethods.E_INVALIDARG; 
                    }
                } 
                else {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t dwFlags not supported: " + dwFlags);
                    return NativeMethods.E_INVALIDARG;
                } 

                return NativeMethods.S_OK; 
            } 

            int UnsafeNativeMethods.IOleControlSite.TranslateAccelerator(ref NativeMethods.MSG pMsg, int grfModifiers) { 
                Debug.Assert(!host.GetAxState(AxHost.siteProcessedInputKey), "Re-entering UnsafeNativeMethods.IOleControlSite.TranslateAccelerator!!!");
                host.SetAxState(AxHost.siteProcessedInputKey, true);

                Message msg = new Message(); 
                msg.Msg = pMsg.message;
                msg.WParam = pMsg.wParam; 
                msg.LParam = pMsg.lParam; 
                msg.HWnd = pMsg.hwnd;
 
                try {
                    bool f = ((Control)host).PreProcessMessage(ref msg);
                    return f ? NativeMethods.S_OK : NativeMethods.S_FALSE;
                } 
                finally {
                    host.SetAxState(AxHost.siteProcessedInputKey, false); 
                } 
            }
 
            int UnsafeNativeMethods.IOleControlSite.OnFocus(int fGotFocus) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnFocus " + ((fGotFocus == 0) ? "lost" : "gained"));
                return NativeMethods.S_OK;
            } 

            int UnsafeNativeMethods.IOleControlSite.ShowPropertyFrame() { 
                if (host.CanShowPropertyPages()) { 
                    host.ShowPropertyPages();
                    return NativeMethods.S_OK; 
                }
                return NativeMethods.E_NOTIMPL;
            }
 
            // IOleClientSite methods:
 
            int UnsafeNativeMethods.IOleClientSite.SaveObject() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in SaveObject");
                return NativeMethods.E_NOTIMPL; 
            }

            int UnsafeNativeMethods.IOleClientSite.GetMoniker(int dwAssign, int dwWhichMoniker, out Object moniker) {
                Debug.WriteLineIf(CompModSwitches.ActiveX.TraceInfo, "AxSource:GetMoniker"); 
                moniker = null;
                return NativeMethods.E_NOTIMPL; 
            } 

            int UnsafeNativeMethods.IOleClientSite.GetContainer(out UnsafeNativeMethods.IOleContainer container) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getContainer");
                container = host.GetParentContainer();
                return NativeMethods.S_OK;
            } 

 
            int UnsafeNativeMethods.IOleClientSite.ShowObject() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in ShowObject");
                if (host.GetAxState(AxHost.fOwnWindow)) { 
                    Debug.Fail("we can't be in showobject if we own our window...");
                    return NativeMethods.S_OK;
                }
                if (host.GetAxState(AxHost.fFakingWindow)) { 
                    // we really should not be here...
                    // this means that the ctl inplace deactivated and didn't call on inplace activate before calling showobject 
                    // so we need to destroy our fake window first... 
                    host.DestroyFakeWindow();
 
                    // ASURT 46393
                    // The fact that we have a fake window means that the OCX inplace deactivated when we hid it. It means
                    // that we have to bring it back from RUNNING to INPLACE so that it can re-create its handle properly.
                    // 
                    host.TransitionDownTo(OC_LOADED);
                    host.TransitionUpTo(OC_INPLACE); 
                } 
                if (host.GetOcState() < OC_INPLACE)
                    return NativeMethods.S_OK; 

                IntPtr hwnd;
                if (NativeMethods.Succeeded(host.GetInPlaceObject().GetWindow(out hwnd))) {
                    if (host.GetHandleNoCreate() != hwnd) { 
                        host.DetachWindow();
                        if (hwnd != IntPtr.Zero) { 
                            host.AttachWindow(hwnd); 
                        }
                    } 
                }
                else if (host.GetInPlaceObject() is UnsafeNativeMethods.IOleInPlaceObjectWindowless) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Windowless control.");
                    throw new InvalidOperationException(SR.GetString(SR.AXWindowlessControl)); 
                }
 
                return NativeMethods.S_OK; 
            }
 
            int UnsafeNativeMethods.IOleClientSite.OnShowWindow(int fShow) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnShowWindow");
                return NativeMethods.S_OK;
            } 

            int UnsafeNativeMethods.IOleClientSite.RequestNewObjectLayout() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in RequestNewObjectLayout"); 
                return NativeMethods.E_NOTIMPL;
            } 

            // IOleInPlaceSite methods:

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            IntPtr UnsafeNativeMethods.IOleInPlaceSite.GetWindow() {
                try { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetWindow");
                    Control parent = host.ParentInternal;
                    return parent != null ? parent.Handle : IntPtr.Zero;
                } 
                catch (Exception t) {
                    Debug.Fail(t.ToString()); 
                    throw t; 
                }
            } 

            /// 
            ///    [To be supplied.]
            ///  
            int UnsafeNativeMethods.IOleInPlaceSite.ContextSensitiveHelp(int fEnterMode) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in ContextSensitiveHelp"); 
                return NativeMethods.E_NOTIMPL; 
            }
 
            int UnsafeNativeMethods.IOleInPlaceSite.CanInPlaceActivate() {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in CanInPlaceActivate");
                return NativeMethods.S_OK;
            } 

            int UnsafeNativeMethods.IOleInPlaceSite.OnInPlaceActivate() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnInPlaceActivate"); 
                host.SetAxState(AxHost.ownDisposing, false);
                host.SetAxState(AxHost.rejectSelection, false); 
                host.SetOcState(OC_INPLACE);
                return NativeMethods.S_OK;
            }
 
            int UnsafeNativeMethods.IOleInPlaceSite.OnUIActivate() {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnUIActivate for " + host.ToString()); 
                host.SetOcState(OC_UIACTIVE); 
                host.GetParentContainer().OnUIActivate(host);
                return NativeMethods.S_OK; 
            }

            int UnsafeNativeMethods.IOleInPlaceSite.GetWindowContext(out UnsafeNativeMethods.IOleInPlaceFrame ppFrame, out UnsafeNativeMethods.IOleInPlaceUIWindow ppDoc,
                                                 NativeMethods.COMRECT lprcPosRect, NativeMethods.COMRECT lprcClipRect, NativeMethods.tagOIFI lpFrameInfo) { 
                ppDoc = null;
                ppFrame = host.GetParentContainer(); 
                FillInRect(lprcPosRect, host.Bounds); 
                host.GetClipRect(lprcClipRect);
                if (lpFrameInfo != null) { 
                    lpFrameInfo.cb = Marshal.SizeOf(typeof(NativeMethods.tagOIFI));
                    lpFrameInfo.fMDIApp = false;
                    lpFrameInfo.hAccel = IntPtr.Zero;
                    lpFrameInfo.cAccelEntries = 0; 
                    lpFrameInfo.hwndFrame = host.ParentInternal.Handle;
                } 
                return NativeMethods.S_OK; 
            }
 
            int UnsafeNativeMethods.IOleInPlaceSite.Scroll(NativeMethods.tagSIZE scrollExtant) {
                try {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in Scroll");
                } 
                catch (Exception t) {
                    Debug.Fail(t.ToString()); 
                    throw t; 
                }
                return(NativeMethods.S_FALSE); 
            }

            int UnsafeNativeMethods.IOleInPlaceSite.OnUIDeactivate(int fUndoable) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnUIDeactivate for " + host.ToString()); 
                host.GetParentContainer().OnUIDeactivate(host);
                if (host.GetOcState() > OC_INPLACE) { 
                    host.SetOcState(OC_INPLACE); 
                }
                return NativeMethods.S_OK; 
            }

            int UnsafeNativeMethods.IOleInPlaceSite.OnInPlaceDeactivate() {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnInPlaceDeactivate"); 
                if (host.GetOcState() == OC_UIACTIVE) {
                    ((UnsafeNativeMethods.IOleInPlaceSite)this).OnUIDeactivate(0); 
                } 

                host.GetParentContainer().OnInPlaceDeactivate(host); 
                host.DetachWindow();
                host.SetOcState(OC_RUNNING);
                return NativeMethods.S_OK;
            } 

            int UnsafeNativeMethods.IOleInPlaceSite.DiscardUndoState() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in DiscardUndoState"); 
                return NativeMethods.S_OK;
            } 

            int UnsafeNativeMethods.IOleInPlaceSite.DeactivateAndUndo() {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in DeactivateAndUndo for "+host.ToString());
                return host.GetInPlaceObject().UIDeactivate(); 
            }
 
            int UnsafeNativeMethods.IOleInPlaceSite.OnPosRectChange(NativeMethods.COMRECT lprcPosRect) { 
                // ASURT 68752
                // The MediaPlayer control has a AllowChangeDisplaySize property that users 
                // can set to control size changes at runtime, but the control itself ignores that and sets the new size.
                // We prevent this by not allowing controls to call OnPosRectChange(), unless we instantiated the resize.
                // visual basic6 does the same.
                // 
                bool useRect = true;
                if (AxHost.windowsMediaPlayer_Clsid.Equals(host.clsid)) 
                    useRect = host.GetAxState(AxHost.handlePosRectChanged); 

                if (useRect) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnPosRectChange" + lprcPosRect.ToString());
                    host.GetInPlaceObject().SetObjectRects(lprcPosRect, host.GetClipRect(new NativeMethods.COMRECT()));
                    host.MakeDirty();
                } 
                else {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Control directly called OnPosRectChange... ignoring the new size"); 
                } 
                return NativeMethods.S_OK;
            } 

            // IPropertyNotifySink methods

            void UnsafeNativeMethods.IPropertyNotifySink.OnChanged(int dispid) { 
                // Some controls fire OnChanged() notifications when getting values of some properties. ASURT 20190.
                // To prevent this kind of recursion, we check to see if we are already inside a OnChanged() call. 
                // 
                if (host.NoComponentChangeEvents != 0)
                    return; 

                host.NoComponentChangeEvents++;
                try {
                    AxPropertyDescriptor prop = null; 

                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnChanged"); 
 
                     if (dispid != NativeMethods.ActiveX.DISPID_UNKNOWN) {
                        prop = host.GetPropertyDescriptorFromDispid(dispid); 
                        if (prop != null) {
                            prop.OnValueChanged(this.host);
                            if (!prop.SettingValue) {
                                prop.UpdateTypeConverterAndTypeEditor(true); 
                            }
                        } 
                    } 
                    else {
                        // update them all for DISPID_UNKNOWN. 
                        //
                        PropertyDescriptorCollection props = ((ICustomTypeDescriptor)host).GetProperties();
                        foreach(PropertyDescriptor p in props) {
                            prop = p as AxPropertyDescriptor; 
                            if (prop != null && !prop.SettingValue) {
                                prop.UpdateTypeConverterAndTypeEditor(true); 
                            } 
                        }
                    } 

                    ISite site = host.Site;
                    if (site != null) {
                        IComponentChangeService changeService = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); 

                        if (changeService != null) { 
                            try { 
                                changeService.OnComponentChanging(host, prop);
                            } 
                            catch (CheckoutException coEx) {
                                if (coEx == CheckoutException.Canceled) {
                                    return;
                                } 
                                throw coEx;
                            } 
 
                            // Now notify the change service that the change was successful.
                            // 
                            changeService.OnComponentChanged(host, prop, null, ((prop != null) ? prop.GetValue(host) : null));
                        }
                    }
                } 
                catch (Exception t) {
                    Debug.Fail(t.ToString()); 
                    throw t; 
                }
                finally { 
                    host.NoComponentChangeEvents--;
                }
            }
 
            int UnsafeNativeMethods.IPropertyNotifySink.OnRequestEdit(int dispid) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in OnRequestEdit for "+host.ToString()); 
                return NativeMethods.S_OK; 
            }
        } 

        private const int HMperInch = 2540;
        private int Pix2HM(int pix, int logP) {
            return(HMperInch * pix + ( logP >> 1)) / logP; 
        }
 
        private int HM2Pix(int hm, int logP) { 
            return(logP * hm + HMperInch / 2) / HMperInch;
        } 

        private bool QuickActivate() {
            if (!(instance is UnsafeNativeMethods.IQuickActivate)) return false;
            UnsafeNativeMethods.IQuickActivate iqa = (UnsafeNativeMethods.IQuickActivate) instance; 

            UnsafeNativeMethods.tagQACONTAINER qaContainer = new UnsafeNativeMethods.tagQACONTAINER(); 
            UnsafeNativeMethods.tagQACONTROL qaControl = new UnsafeNativeMethods.tagQACONTROL(); 

            qaContainer.pClientSite = oleSite; 
            qaContainer.pPropertyNotifySink = oleSite;
            //         qaContainer.pControlSite = oleSite;
            //         qaContainer.pAdviseSink = null;
            //         qaContainer.pUnkEventSink = null; 
            //         qaContainer.pUndoMgr = null;
            //         qaContainer.pBindHost = null; 
            //         qaContainer.pServiveProvider = null; 
            //         qaContainer.hpal = 0;
            qaContainer.pFont = GetIFontFromFont(GetParentContainer().parent.Font); 
            qaContainer.dwAppearance = 0;
            qaContainer.lcid = Application.CurrentCulture.LCID;

            Control p = ParentInternal; 

            if (p != null) { 
                qaContainer.colorFore = GetOleColorFromColor(p.ForeColor); 
                qaContainer.colorBack = GetOleColorFromColor(p.BackColor);
            } 
            else {
                qaContainer.colorFore = GetOleColorFromColor(SystemColors.WindowText);
                qaContainer.colorBack = GetOleColorFromColor(SystemColors.Window);
            } 
            qaContainer.dwAmbientFlags = NativeMethods.ActiveX.QACONTAINER_AUTOCLIP | NativeMethods.ActiveX.QACONTAINER_MESSAGEREFLECT |
                                         NativeMethods.ActiveX.QACONTAINER_SUPPORTSMNEMONICS; 
            if (IsUserMode()) { 
                qaContainer.dwAmbientFlags |= NativeMethods.ActiveX.QACONTAINER_USERMODE;
            } 
            else {
                // Can't set ui dead becuase MFC controls return NOWHERE on NCHITTEST which
                // messes up the designer...
                // But, without this the FarPoint SpreadSheet and the Office SpreadSheet 
                // controls take keyboard input at design time.
                //qaContainer.dwAmbientFlags |= NativeMethods.ActiveX.QACONTAINER_UIDEAD; 
                // qaContainer.dwAmbientFlags |= ActiveX.QACONTAINER_SHOWHATCHING; 
            }
 
            try {
                iqa.QuickActivate(qaContainer, qaControl);
            }
            catch (Exception t) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to QuickActivate: " + t.ToString());
                DisposeAxControl(); 
                return false; 
            }
            miscStatusBits = qaControl.dwMiscStatus; 
            ParseMiscBits(miscStatusBits);
            return true;
        }
 
        internal override void DisposeAxControls() {
            axState[rejectSelection] = true; 
            base.DisposeAxControls(); 
            TransitionDownTo(OC_PASSIVE);
        } 


        private bool GetControlEnabled() {
            try { 
                return IsHandleCreated;
            } 
            catch (Exception t) { 
                Debug.Fail(t.ToString());
                return true; 
            }
        }

        internal override bool CanSelectCore() { 
            if (!GetControlEnabled() || axState[rejectSelection]) return false;
            return base.CanSelectCore(); 
        } 

        ///  
        /// 
        ///     Frees all resources assocaited with this control. This method may not be
        ///     called at runtime. Any resources used by the control should be setup to
        ///     be released when the control is garbage collected. Inheriting classes should always 
        ///     call base.dispose.
        ///  
        protected override void Dispose(bool disposing) { 
 			
            if (disposing) { 
                TransitionDownTo(OC_PASSIVE);
                if (newParent != null)
                {
                    newParent.Dispose(); 
                }
            } 
            base.Dispose(disposing); 
        }
 
        private bool GetSiteOwnsDeactivation() {
            return axState[ownDisposing];
        }
 
        private void DisposeAxControl() {
            if (GetParentContainer() != null) { 
                GetParentContainer().RemoveControl(this); 
            }
            TransitionDownTo(OC_RUNNING); 
            if (GetOcState() == OC_RUNNING) {
                GetOleObject().SetClientSite(null);
                SetOcState(OC_LOADED);
            } 
        }
 
        private void ReleaseAxControl() { 
            // This line is like a bit of magic...
            // sometimes, we crash with it on, 
            // sometimes, with it off...
            // Lately, I have decided to leave it on...
            // (oh, yes, and the crashes seemed to disappear...)
            //cpr: ComLib.Release(instance); 

            this.NoComponentChangeEvents++; 
 
            ContainerControl f = ContainingControl;
            if (f != null) { 
                f.VisibleChanged -= this.onContainerVisibleChanged;
            }

            try { 
                if (instance != null) {
                    Marshal.FinalReleaseComObject(instance); 
                    instance = null; 
                    iOleInPlaceObject = null;
                    iOleObject = null; 
                    iOleControl = null;
                    iOleInPlaceActiveObject = null;
                    iOleInPlaceActiveObjectExternal = null;
                    iPerPropertyBrowsing = null; 
                    iCategorizeProperties = null;
                    iPersistStream = null; 
                    iPersistStreamInit = null; 
                    iPersistStorage = null;
                } 

                axState[checkedIppb] = false;
                axState[checkedCP] = false;
                axState[disposed] = true; 

                freezeCount = 0; 
                axState[sinkAttached] = false; 
                wndprocAddr = IntPtr.Zero;
 
                SetOcState(OC_PASSIVE);
            }
            finally {
                this.NoComponentChangeEvents--; 
            }
        } 
 
        private void ParseMiscBits(int bits) {
            axState[fOwnWindow] = ((bits & NativeMethods.ActiveX.OLEMISC_INVISIBLEATRUNTIME) != 0) && IsUserMode(); 
            axState[fSimpleFrame] = ((bits & NativeMethods.ActiveX.OLEMISC_SIMPLEFRAME) != 0);
        }

        private void SlowActivate() { 

            bool setClientSite = false; 
 
            if ((miscStatusBits & NativeMethods.ActiveX.OLEMISC_SETCLIENTSITEFIRST) != 0) {
                GetOleObject().SetClientSite(oleSite); 
                setClientSite = true;
            }

            DepersistControl(); 

            if (!setClientSite) { 
                GetOleObject().SetClientSite(oleSite); 
            }
        } 


        private static NativeMethods.COMRECT FillInRect(NativeMethods.COMRECT dest, Rectangle source) {
            dest.left = source.X; 
            dest.top = source.Y;
            dest.right = source.Width + source.X; 
            dest.bottom = source.Height + source.Y; 
            return dest;
        } 

        private AxContainer GetParentContainer() {
            Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "GetParent Demanded");
            IntSecurity.GetParent.Demand(); 

            if (container == null) { 
                container = AxContainer.FindContainerForControl(this); 
            }
            if (container == null) { 
                ContainerControl f = ContainingControl;
                if (f == null) {
                    // ContainingCointrol can be null if the AxHost is still not parented to a containerControl
                    // In everett we used to return a parking window. 
                    // now we just set the containingControl to a dummyValue.
                    if (newParent == null) 
                    { 
                        newParent = new ContainerControl();
                        axContainer = newParent.CreateAxContainer(); 
                        axContainer.AddControl(this);
                    }
                    return axContainer;
                } 
                else {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "calling upon "+f.ToString()+" to create a container"); 
                    container = f.CreateAxContainer(); 
                    container.AddControl(this);
                    containingControl = f; 
                }
            }
            return container;
        } 

        private UnsafeNativeMethods.IOleControl GetOleControl() { 
            if (iOleControl == null) { 
                Debug.Assert(instance != null, "must have the ocx");
                iOleControl = (UnsafeNativeMethods.IOleControl) instance; 
            }
            return iOleControl;
        }
 
        private UnsafeNativeMethods.IOleInPlaceActiveObject GetInPlaceActiveObject() {
            // if our AxContainer was set an external active object then use it. 
            if(iOleInPlaceActiveObjectExternal != null) { 
                return iOleInPlaceActiveObjectExternal;
            } 

            // otherwise use our instance.
            if (iOleInPlaceActiveObject == null) {
                Debug.Assert(instance != null, "must have the ocx"); 
                try {
                    iOleInPlaceActiveObject = (UnsafeNativeMethods.IOleInPlaceActiveObject)instance; 
                } 
                catch (InvalidCastException e) {
                    Debug.Fail("Invalid cast in GetInPlaceActiveObject: " + e.ToString()); 
                }
            }
            return iOleInPlaceActiveObject;
        } 

        private UnsafeNativeMethods.IOleObject GetOleObject() { 
            if (iOleObject == null) { 
                Debug.Assert(instance != null, "must have the ocx");
                iOleObject = (UnsafeNativeMethods.IOleObject) instance; 
            }
            return iOleObject;
        }
 
        private UnsafeNativeMethods.IOleInPlaceObject GetInPlaceObject() {
            if (iOleInPlaceObject == null) { 
                Debug.Assert(instance != null, "must have the ocx"); 
                iOleInPlaceObject = (UnsafeNativeMethods.IOleInPlaceObject) instance;
 
#if DEBUG
                if (iOleInPlaceObject is UnsafeNativeMethods.IOleInPlaceObjectWindowless)
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, GetType().FullName + " Can also be a Windowless control.");
#endif //DEBUG 
            }
            return iOleInPlaceObject; 
        } 

        private NativeMethods.ICategorizeProperties GetCategorizeProperties() { 
            if (iCategorizeProperties == null && !axState[checkedCP] && instance != null) {
                axState[checkedCP] = true;
                if (instance is NativeMethods.ICategorizeProperties) {
                    iCategorizeProperties = (NativeMethods.ICategorizeProperties) instance; 
                }
            } 
            return iCategorizeProperties; 
        }
 
        private NativeMethods.IPerPropertyBrowsing GetPerPropertyBrowsing() {
            if (iPerPropertyBrowsing == null && !axState[checkedIppb] && instance != null) {
                axState[checkedIppb] = true;
                if (instance is NativeMethods.IPerPropertyBrowsing) { 
                    iPerPropertyBrowsing = (NativeMethods.IPerPropertyBrowsing) instance;
                } 
            } 
            return iPerPropertyBrowsing;
        } 


        // Mapping functions:
 
#if false
        // FxCop: Currently not used 
        private static IntPtr CopyPalette(IntPtr hPal) { 
            if (hPal == IntPtr.Zero) return IntPtr.Zero;
            int[] nEntries = new int[1]; 
            UnsafeNativeMethods.GetObject(new HandleRef(null, hPal), 4, nEntries);
            IntPtr memory = Marshal.AllocHGlobal(nEntries[0] * 4 + 8);
            IntPtr ret = IntPtr.Zero;
 
            try {
                Marshal.WriteInt32(memory, 0, 0x300); 
                Marshal.WriteInt32(memory, 4, nEntries[0]); 
                SafeNativeMethods.GetPaletteEntries(new HandleRef(null, hPal), 0, nEntries[0], (IntPtr)((long)memory + 8));
                ret = SafeNativeMethods.CreatePalette(new HandleRef(null, memory)); 
            }
            finally {
                Marshal.FreeHGlobal(memory);
            } 
            return ret;
        } 
#endif 

        private static Object GetPICTDESCFromPicture(Image image) { 
            Bitmap bmp = image as Bitmap;
            if (bmp != null) {
                return new NativeMethods.PICTDESCbmp(bmp);
            } 

            Metafile mf = image as Metafile; 
            if (mf != null) 
            {
                return new NativeMethods.PICTDESCemf(mf); 
            }
            throw new ArgumentException(SR.GetString(SR.AXUnknownImage), "image");
        }
 
        /// 
        ///  
        ///     Maps from a System.Drawing.Image to an OLE IPicture 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static object GetIPictureFromPicture(Image image) {
            if (image == null) return null;
            Object pictdesc = GetPICTDESCFromPicture(image);
            return UnsafeNativeMethods.OleCreateIPictureIndirect(pictdesc, ref ipicture_Guid, true); 
        }
 
        ///  
        /// 
        ///     Maps from a System.Drawing.Cursor to an OLE IPicture 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected static object GetIPictureFromCursor(Cursor cursor) {
            if (cursor == null) return null; 
            NativeMethods.PICTDESCicon pictdesc = new NativeMethods.PICTDESCicon(Icon.FromHandle(cursor.Handle));
            return UnsafeNativeMethods.OleCreateIPictureIndirect(pictdesc, ref ipicture_Guid, true); 
        } 

        ///  
        /// 
        ///     Maps from a System.Drawing.Image to an OLE IPictureDisp
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static object GetIPictureDispFromPicture(Image image) {
            if (image == null) return null; 
            Object pictdesc = GetPICTDESCFromPicture(image); 
            return UnsafeNativeMethods.OleCreateIPictureDispIndirect(pictdesc, ref ipictureDisp_Guid, true);
        } 

        /// 
        /// 
        ///     Maps from an OLE IPicture to a System.Drawing.Image 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static Image GetPictureFromIPicture(object picture) { 
            if (picture == null) return null;
            IntPtr hPal = IntPtr.Zero; 
            UnsafeNativeMethods.IPicture pict = (UnsafeNativeMethods.IPicture)picture;
            int type = pict.GetPictureType();
            if (type == NativeMethods.Ole.PICTYPE_BITMAP) {
                try { 
                    hPal = pict.GetHPal();
                } 
                catch (COMException) { 
                }
            } 
            return GetPictureFromParams(pict, pict.GetHandle(), type, hPal, pict.GetWidth(), pict.GetHeight());
        }

        ///  
        /// 
        ///     Maps from an OLE IPictureDisp to a System.Drawing.Image 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected static Image GetPictureFromIPictureDisp(object picture) { 
            if (picture == null) return null;
            IntPtr hPal = IntPtr.Zero;
            UnsafeNativeMethods.IPictureDisp pict = (UnsafeNativeMethods.IPictureDisp)picture;
            int type = pict.PictureType; 
            if (type == NativeMethods.Ole.PICTYPE_BITMAP) {
                try { 
                    hPal = pict.HPal; 
                }
                catch (COMException) { 
                }
            }
            return GetPictureFromParams(pict, pict.Handle, type, hPal, pict.Width, pict.Height);
        } 

        private static Image GetPictureFromParams(object pict, IntPtr handle, int type, IntPtr paletteHandle, int width, int height) { 
            switch (type) { 
                case NativeMethods.Ole.PICTYPE_ICON:
                    return(Image)(Icon.FromHandle(handle)).Clone(); 
                case NativeMethods.Ole.PICTYPE_METAFILE:
                    WmfPlaceableFileHeader header = new WmfPlaceableFileHeader();
                    header.BboxRight = (short)width;
                    header.BboxBottom = (short)height; 
                    return(Image)(new Metafile(handle, header, false)).Clone();
                case NativeMethods.Ole.PICTYPE_ENHMETAFILE: 
                    return(Image)(new Metafile(handle, false)).Clone(); 
                case NativeMethods.Ole.PICTYPE_BITMAP:
                    return Image.FromHbitmap(handle, paletteHandle); 
                case NativeMethods.Ole.PICTYPE_NONE:
                    // MSDN sez this should not be a valid value, but comctl32 returns it...
                    return null;
                case NativeMethods.Ole.PICTYPE_UNINITIALIZED: 
                    return null;
                default: 
                    Debug.Fail("Invalid image type "+ type.ToString(CultureInfo.InvariantCulture)); 
                    throw new ArgumentException(SR.GetString(SR.AXUnknownImage), "type");
            } 
        }

        private static NativeMethods.FONTDESC GetFONTDESCFromFont(Font font) {
            NativeMethods.FONTDESC fdesc = null; 

            if (fontTable == null) { 
                fontTable = new Hashtable(); 
            }
            else { 
                fdesc = (NativeMethods.FONTDESC)fontTable[font];
            }

            if (fdesc == null) { 
                fdesc = new NativeMethods.FONTDESC();
                fdesc.lpstrName = font.Name; 
                fdesc.cySize = (long)(font.SizeInPoints * 10000); 
                NativeMethods.LOGFONT logfont = new NativeMethods.LOGFONT();
                font.ToLogFont(logfont); 
                fdesc.sWeight = (short) logfont.lfWeight;
                fdesc.sCharset = logfont.lfCharSet;
                fdesc.fItalic = font.Italic;
                fdesc.fUnderline = font.Underline; 
                fdesc.fStrikethrough = font.Strikeout;
 
                fontTable[font] = fdesc; 
            }
 
            return fdesc;
        }

        ///  
        /// 
        ///     Maps from an OLE COLOR to a System.Drawing.Color 
        ///  
        [CLSCompliantAttribute(false)]
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static Color GetColorFromOleColor(uint color) {
            return ColorTranslator.FromOle((int)color);
        }
 
        /// 
        ///  
        ///     Maps from an System.Drawing.Color to an OLE COLOR 
        /// 
        [CLSCompliantAttribute(false)] 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected static uint GetOleColorFromColor(Color color) {
            return (uint)ColorTranslator.ToOle(color);
        } 

        ///  
        ///  
        ///     Maps from a System.Drawing.Font object to an OLE IFont
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected static object GetIFontFromFont(Font font) {
            if (font == null) return null;
 
            if (font.Unit != GraphicsUnit.Point)
                throw new ArgumentException(SR.GetString(SR.AXFontUnitNotPoint), "font"); 
 
            try {
                return (UnsafeNativeMethods.IFont)UnsafeNativeMethods.OleCreateIFontIndirect(GetFONTDESCFromFont(font), ref ifont_Guid); 
            }
            catch {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to create IFrom from font: " + font.ToString());
                return null; 
            }
        } 
 

        ///  
        /// 
        ///     Maps from an OLE IFont to a System.Drawing.Font object
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static Font GetFontFromIFont(object font) {
            if (font == null) return null; 
 
            UnsafeNativeMethods.IFont oleFont = (UnsafeNativeMethods.IFont)font;
            try { 
                Font f = Font.FromHfont(oleFont.GetHFont());

                if (f.Unit != GraphicsUnit.Point)
                    f = new Font(f.Name, f.SizeInPoints, f.Style, GraphicsUnit.Point, f.GdiCharSet, f.GdiVerticalFont); 

                return f; 
            } 
            catch (Exception e) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Could not create font." + e.Message); 
                return DefaultFont;
            }
        }
 

        ///  
        ///  
        ///     Maps from a System.Drawing.Font object to an OLE IFontDisp
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected static object GetIFontDispFromFont(Font font) {
            if (font == null) return null;
 
            if (font.Unit != GraphicsUnit.Point)
                throw new ArgumentException(SR.GetString(SR.AXFontUnitNotPoint), "font"); 
 
            SafeNativeMethods.IFontDisp rval = SafeNativeMethods.OleCreateIFontDispIndirect(GetFONTDESCFromFont(font), ref ifontDisp_Guid);
            return rval; 
        }

        /// 
        ///  
        ///     Maps from an IFontDisp to a System.Drawing.Font object
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static Font GetFontFromIFontDisp(object font) {
            if (font == null) 
            {
                return null;
            }
 
            UnsafeNativeMethods.IFont ifont = font as UnsafeNativeMethods.IFont;
            if (ifont != null) 
            { 
                return GetFontFromIFont(ifont);
            } 

            SafeNativeMethods.IFontDisp oleFont = (SafeNativeMethods.IFontDisp)font;
            FontStyle style = FontStyle.Regular;
 
            Font f = null;
            try { 
                if (oleFont.Bold) 
                    style |= FontStyle.Bold;
 
                if (oleFont.Italic)
                    style |= FontStyle.Italic;

                if (oleFont.Underline) 
                    style |= FontStyle.Underline;
 
                if (oleFont.Strikethrough) 
                    style |= FontStyle.Strikeout;
 
                if ((int) oleFont.Weight >= 700) // bold
                    style |= FontStyle.Bold;

                f = new Font(oleFont.Name, (float)oleFont.Size/(float)10000, style, GraphicsUnit.Point, (byte)oleFont.Charset); 
                return f;
            } 
            catch(Exception e) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Could not create font from: " + oleFont.Name + ". " + e.Message);
                return DefaultFont; 
            }
        }

 
        /// 
        ///  
        ///     Maps from a DateTime object to an OLE DATE (expressed as a double) 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static double GetOADateFromTime(DateTime time) {
            return time.ToOADate();
        }
 
        /// 
        ///  
        ///     Maps from an OLE DATE (expressed as a double) to a DateTime object 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected static DateTime GetTimeFromOADate(double date) {
            return DateTime.FromOADate(date);
        }
 
        /// 
        ///  
        ///  
        private int Convert2int(Object o, bool xDirection) {
            o = ((Array)o).GetValue(0); 
            // yacky yacky yacky...
            // so, usercontrols & other visual basic related controls give us coords as floats in twips
            // but mfc controls give us integers as pixels...
            if (o.GetType() == typeof(Single)) { 
                return Twip2Pixel(Convert.ToDouble(o, CultureInfo.InvariantCulture), xDirection);
            } 
            return Convert.ToInt32(o, CultureInfo.InvariantCulture); 
        }
 
        /// 
        /// 
        /// 
        private short Convert2short(Object o) { 
            o = ((Array)o).GetValue(0);
            return Convert.ToInt16(o, CultureInfo.InvariantCulture); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Design", "CA1025:ReplaceRepetitiveArgumentsWithParamsArray")] 
        protected void RaiseOnMouseMove(Object o1, Object o2, Object o3, Object o4) {
            RaiseOnMouseMove(Convert2short(o1), Convert2short(o2), Convert2int(o3, true), Convert2int(o4, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseMove(short button, short shift, float x, float y) {
            RaiseOnMouseMove(button, shift, Twip2Pixel((int) x, true), Twip2Pixel((int) y, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseMove(short button, short shift, int x, int y) {
            base.OnMouseMove(new MouseEventArgs( (MouseButtons)(((int)button) << 20), 1, x, y, 0)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Design", "CA1025:ReplaceRepetitiveArgumentsWithParamsArray")] 
        protected void RaiseOnMouseUp(Object o1, Object o2, Object o3, Object o4) {
            RaiseOnMouseUp(Convert2short(o1), Convert2short(o2), Convert2int(o3, true), Convert2int(o4, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseUp(short button, short shift, float x, float y) {
            RaiseOnMouseUp(button, shift, Twip2Pixel((int) x, true), Twip2Pixel((int) y, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseUp(short button, short shift, int x, int y) {
            base.OnMouseUp(new MouseEventArgs((MouseButtons)(((int)button) << 20), 1, x, y, 0)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Design", "CA1025:ReplaceRepetitiveArgumentsWithParamsArray")] 
        protected void RaiseOnMouseDown(Object o1, Object o2, Object o3, Object o4) {
            RaiseOnMouseDown(Convert2short(o1), Convert2short(o2), Convert2int(o3, true), Convert2int(o4, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseDown(short button, short shift, float x, float y) {
            RaiseOnMouseDown(button, shift, Twip2Pixel((int) x,true), Twip2Pixel((int) y, false)); 
        } 

        ///  
        /// 
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected void RaiseOnMouseDown(short button, short shift, int x, int y) {
            base.OnMouseDown(new MouseEventArgs((MouseButtons)(((int)button) << 20), 1, x, y, 0)); 
        } 

        ///  
        /// 
        private class VBFormat : UnsafeNativeMethods.IVBFormat {

            // IVBFormat methods: 
            //
            int UnsafeNativeMethods.IVBFormat.Format(ref Object var, IntPtr pszFormat, IntPtr lpBuffer, short cpBuffer, int lcid, short firstD, short firstW, short[] result) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in Format"); 
                if (result == null)
                    return NativeMethods.E_INVALIDARG; 

                result[0] = 0;
                if (lpBuffer == IntPtr.Zero || cpBuffer < 2)
                    return NativeMethods.E_INVALIDARG; 

                IntPtr pbstr = IntPtr.Zero; 
                int hr = UnsafeNativeMethods.VarFormat(ref var, new HandleRef(null, pszFormat), firstD, firstW, 32 /* VAR_FORMAT_NOSUBSTITUTE */, ref pbstr); 

                try { 
                    int i = 0;
                    if (pbstr != IntPtr.Zero) {
                        short ch = 0;
                        cpBuffer --; 
                        for (;i < cpBuffer && (ch = Marshal.ReadInt16(pbstr, i * 2)) != 0; i++) {
                            Marshal.WriteInt16(lpBuffer, i * 2, ch); 
                        } 
                    }
                    Marshal.WriteInt16(lpBuffer, i * 2, (short) 0); 
                    result[0] = (short) i;
                }
                finally {
                    SafeNativeMethods.SysFreeString(new HandleRef(null, pbstr)); 
                }
 
                return NativeMethods.S_OK; 
            }
        } 



        ///  
        /// 
        internal class EnumUnknown : UnsafeNativeMethods.IEnumUnknown { 
            private Object[] arr; 
            private int loc;
            private int size; 

            internal EnumUnknown(Object[] arr) {
                //if (AxHTraceSwitch.TraceVerbose) Debug.WriteObject(arr);
                this.arr = arr; 
                loc = 0;
                size = (arr == null) ? 0 : arr.Length; 
            } 

            private EnumUnknown(Object[] arr, int loc) : this(arr) { 
                this.loc = loc;
            }

            unsafe int UnsafeNativeMethods.IEnumUnknown.Next(int celt, IntPtr rgelt, IntPtr pceltFetched) { 
                if (pceltFetched != IntPtr.Zero)
                    Marshal.WriteInt32(pceltFetched, 0, 0); 
 
                if (celt < 0) {
                    return NativeMethods.E_INVALIDARG; 
                }

                int fetched = 0;
                if (loc >= size) { 
                    fetched = 0;
                } 
                else { 
                    for (; loc < size && fetched < celt; ++loc) {
                        if (arr[loc] != null) { 
                            Marshal.WriteIntPtr(rgelt, Marshal.GetIUnknownForObject(arr[loc]));
                            rgelt = (IntPtr)((long)rgelt + (long)sizeof(IntPtr));
                            ++fetched;
                        } 
                    }
                } 
 
                if (pceltFetched != IntPtr.Zero)
                    Marshal.WriteInt32(pceltFetched, 0, fetched); 

                if (fetched != celt) {
                    return(NativeMethods.S_FALSE);
                } 
                return NativeMethods.S_OK;
            } 
 
            int UnsafeNativeMethods.IEnumUnknown.Skip(int celt) {
                loc += celt; 
                if (loc >= size) {
                    return(NativeMethods.S_FALSE);
                }
                return NativeMethods.S_OK; 
            }
 
            void UnsafeNativeMethods.IEnumUnknown.Reset() { 
                loc = 0;
            } 

            void UnsafeNativeMethods.IEnumUnknown.Clone(out UnsafeNativeMethods.IEnumUnknown ppenum) {
                ppenum = new EnumUnknown(arr, loc);
            } 
        }
 
 
        /// 
        ///  
        internal class AxContainer : UnsafeNativeMethods.IOleContainer, UnsafeNativeMethods.IOleInPlaceFrame, IReflect {
            internal ContainerControl parent;
            private IContainer assocContainer; // associated IContainer...
            // the assocContainer may be null, in which case all this container does is 
            // forward [de]activation messages to the requisite container...
            private AxHost siteUIActive; 
            private AxHost siteActive; 
            private bool formAlreadyCreated = false;
            private Hashtable containerCache = new Hashtable();  // name -> Control 
            private int lockCount = 0;
            private Hashtable components = null;  // Control -> any
            private Hashtable proxyCache = null;
            private AxHost ctlInEditMode = null; 

            private const int GC_CHILD = 0x1; 
            private const int GC_LASTSIBLING = 0x2; 
            private const int GC_FIRSTSIBLING = 0x4;
            private const int GC_CONTAINER = 0x20; 
            private const int GC_PREVSIBLING = 0x40;
            private const int GC_NEXTSIBLING = 0x80;

            internal AxContainer(ContainerControl parent) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in constructor.  Parent created : "+parent.Created.ToString());
                this.parent = parent; 
                if (parent.Created) FormCreated(); 
            }
 
            // IReflect methods:

            MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr,Binder binder, Type[] types,ParameterModifier[] modifiers) {
                return null; 
            }
 
            MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr) { 
                return null;
            } 

            MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) {
                return new MethodInfo[0];
            } 

            FieldInfo IReflect.GetField(String name, BindingFlags bindingAttr) { 
                return null; 
            }
 
            FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) {
                return new FieldInfo[0];
            }
 
            PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr) {
                return null; 
            } 

            PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { 
                return null;
            }

            PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) { 
                return new PropertyInfo[0];
            } 
 
            MemberInfo[] IReflect.GetMember(String name, BindingFlags bindingAttr) {
                return new MemberInfo[0]; 
            }

            MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) {
                return new MemberInfo[0]; 
            }
 
            Object IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, 
                                                    Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) {
 
                foreach(DictionaryEntry e in containerCache) {
                    string ctlName = GetNameForControl((Control)e.Key);
                    if (ctlName.Equals(name)) {
                        return GetProxyForControl((Control)e.Value); 
                    }
                } 
 
                throw E_FAIL;
            } 

            Type IReflect.UnderlyingSystemType {
                get {
                    return null; 
                }
            } 
 
            /// 
            ///    [To be supplied.] 
            /// 
            internal UnsafeNativeMethods.IExtender GetProxyForControl(Control ctl) {
                UnsafeNativeMethods.IExtender rval = null;
                if (proxyCache == null) { 
                    proxyCache = new Hashtable();
                } 
                else { 
                    rval = (UnsafeNativeMethods.IExtender) proxyCache[ctl];
                } 
                if (rval == null) {
                    if (ctl != parent && !GetControlBelongs(ctl)) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "!parent || !belongs NYI");
                        AxContainer c = FindContainerForControl(ctl); 
                        if (c != null) {
                            rval = new ExtenderProxy(ctl, c); 
                        } 
                        else {
                            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "unable to find proxy, returning null"); 
                            return null;
                        }
                    }
                    else { 
                        rval = new ExtenderProxy(ctl, this);
                    } 
                    proxyCache.Add(ctl, rval); 
                }
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "found proxy "+rval.ToString()); 
                return rval;
            }

            ///  
            ///    [To be supplied.]
            ///  
            internal string GetNameForControl(Control ctl) { 
                string name = (ctl.Site != null) ? ctl.Site.Name : ctl.Name;
                return (name == null) ? "" : name; 
            }

            /// 
            ///    [To be supplied.] 
            /// 
            internal Object GetProxyForContainer() { 
                return this; 
            }
 
            /// 
            ///    [To be supplied.]
            /// 
            internal void AddControl(Control ctl) { 
                //
                lock(this) { 
                    if (containerCache.Contains(ctl)) 
                        throw new ArgumentException(SR.GetString(SR.AXDuplicateControl, GetNameForControl(ctl)), "ctl");
 
                    containerCache.Add(ctl, ctl);

                    if (assocContainer == null) {
                        ISite site = ctl.Site; 
                        if (site != null) {
                            assocContainer = site.Container; 
                            IComponentChangeService ccs = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); 
                            if (ccs != null) {
                                ccs.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved); 
                            }
                        }
                    }
                    else { 
#if DEBUG
                            ISite site = ctl.Site; 
                            if (site != null && assocContainer != site.Container) { 
                                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "mismatch between assoc container & added control");
                            } 
#endif
                    }
                }
            } 

            internal void RemoveControl(Control ctl) { 
                // 
                lock(this) {
                    if (containerCache.Contains(ctl)) { 
                        containerCache.Remove(ctl);
                    }
                }
            } 

 
            ///  
            ///    [To be supplied.]
            ///  
            private void LockComponents() {
                lockCount++;
            }
 
            /// 
            ///    [To be supplied.] 
            ///  
            private void UnlockComponents() {
                lockCount--; 
                if (lockCount == 0) {
                    components = null;
                }
            } 

            ///  
            ///    [To be supplied.] 
            /// 
            internal UnsafeNativeMethods.IEnumUnknown EnumControls(Control ctl, int dwOleContF, int dwWhich) { 
                GetComponents();

                LockComponents();
                try { 
                    ArrayList l = null;
                    bool selected = (dwWhich & NativeMethods.ActiveX.GC_WCH_FSELECTED) != 0; 
                    bool reverse = (dwWhich & NativeMethods.ActiveX.GC_WCH_FREVERSEDIR) != 0; 
                    // Note that visual basic actually ignores the next/prev flags... we will not
                    bool onlyNext = (dwWhich & NativeMethods.ActiveX.GC_WCH_FONLYNEXT) != 0; 
                    bool onlyPrev = (dwWhich & NativeMethods.ActiveX.GC_WCH_FONLYPREV) != 0;
                    dwWhich = dwWhich & ~(NativeMethods.ActiveX.GC_WCH_FSELECTED | NativeMethods.ActiveX.GC_WCH_FREVERSEDIR |
                                          NativeMethods.ActiveX.GC_WCH_FONLYNEXT | NativeMethods.ActiveX.GC_WCH_FONLYPREV);
                    if (onlyNext && onlyPrev) { 
                        Debug.Fail("onlyNext && onlyPrev are both set!");
                        throw E_INVALIDARG; 
                    } 
                    if (dwWhich == NativeMethods.ActiveX.GC_WCH_CONTAINER || dwWhich == NativeMethods.ActiveX.GC_WCH_CONTAINED) {
                        if (onlyNext || onlyPrev) { 
                            Debug.Fail("GC_WCH_FONLYNEXT or FONLYPREV used with CONTANER or CONATINED");
                            throw E_INVALIDARG;
                        }
                    } 
                    int first = 0;
                    int last = -1; // meaning all 
                    Control[] ctls  = null; 
                    switch (dwWhich) {
                        default: 
                            Debug.Fail("Bad GC_WCH");
                            throw E_INVALIDARG;
                        case NativeMethods.ActiveX.GC_WCH_CONTAINED:
                            ctls = ctl.GetChildControlsInTabOrder(false); 
                            ctl = null;
                            break; 
                        case NativeMethods.ActiveX.GC_WCH_SIBLING: 
                            Control p = ctl.ParentInternal;
                            if (p != null) { 
                                ctls = p.GetChildControlsInTabOrder(false);
                                if (onlyPrev) {
                                    last = ctl.TabIndex;
                                } 
                                else if (onlyNext) {
                                    first = ctl.TabIndex + 1; 
                                } 
                            }
                            else { 
                                ctls = new Control[0];
                            }
                            ctl = null;
                            break; 
                        case NativeMethods.ActiveX.GC_WCH_CONTAINER:
                            l = new ArrayList(); 
                            MaybeAdd(l, ctl, selected, dwOleContF, false); 
                            while (ctl != null) {
                                AxContainer cont = FindContainerForControl(ctl); 
                                if (cont != null) {
                                    MaybeAdd(l, cont.parent, selected, dwOleContF, true);
                                    ctl = cont.parent;
                                } 
                                else {
                                    break; 
                                } 
                            }
                            break; 
                        case NativeMethods.ActiveX.GC_WCH_ALL:
                            Hashtable htbl = GetComponents();
                            ctls = new Control[htbl.Keys.Count];
                            htbl.Keys.CopyTo(ctls, 0); 
                            ctl = parent;
                            break; 
                    } 
                    if (l == null) {
                        l = new ArrayList(); 
                        if (last == -1 && ctls != null) last = ctls.Length;
                        if (ctl != null) MaybeAdd(l, ctl, selected, dwOleContF, false);
                        for (int i = first; i < last; i++) {
                            MaybeAdd(l, ctls[i], selected, dwOleContF, false); 
                        }
                    } 
                    Object[] rval = new Object[l.Count]; 
                    l.CopyTo(rval, 0);
                    if (reverse) { 
                        for (int i = 0, j = rval.Length - 1; i < j; i++, j--) {
                            Object temp = rval[i];
                            rval[i] = rval[j];
                            rval[j] = temp; 
                        }
                    } 
                    return new EnumUnknown(rval); 
                }
                finally { 
                    UnlockComponents();
                }
            }
 
            /// 
            ///    [To be supplied.] 
            ///  
            private void MaybeAdd(ArrayList l, Control ctl, bool selected, int dwOleContF, bool ignoreBelong) {
                if (!ignoreBelong && ctl != parent && !GetControlBelongs(ctl)) return; 
                if (selected) {
                    ISelectionService iss = GetSelectionService(ctl);
                    if (iss == null || !iss.GetComponentSelected(this)) return;
                } 
                AxHost hostctl = ctl as AxHost;
                if (hostctl != null && (dwOleContF & NativeMethods.ActiveX.OLECONTF_EMBEDDINGS) != 0) { 
                    l.Add(hostctl.GetOcx()); 
                }
                else if ((dwOleContF & NativeMethods.ActiveX.OLECONTF_OTHERS) != 0) { 
                    Object item = GetProxyForControl(ctl);
                    if (item != null) l.Add(item);
                }
            } 

            ///  
            ///    [To be supplied.] 
            /// 
            private void FillComponentsTable(IContainer container) { 
                if (container != null) {
                    ComponentCollection comps = container.Components;
                    if (comps != null) {
                        components = new Hashtable(); 
                        foreach (IComponent comp in comps) {
                            if (comp is Control && comp != parent && comp.Site != null) { 
                                components.Add(comp, comp); 
                            }
                        } 
                        return;
                    }
                }
 
                Debug.Assert(parent.Site == null, "Parent is sited but we could not find IContainer!!!");
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Did not find a container in FillComponentsTable!!!"); 
 
                bool checkHashTable = true;
                Control[] ctls = new Control[containerCache.Values.Count]; 
                containerCache.Values.CopyTo(ctls, 0);
                if (ctls != null) {
                    if (ctls.Length > 0 && components == null) {
                        components = new Hashtable(); 
                        checkHashTable = false;
                    } 
                    for (int i = 0; i < ctls.Length; i ++) { 
                        if (checkHashTable && !components.Contains(ctls[i])) {
                            components.Add(ctls[i], ctls[i]); 
                        }
                    }
                }
 
                GetAllChildren(this.parent);
            } 
 
            private void GetAllChildren(Control ctl) {
                if (ctl == null) 
                    return;

                if (components == null) {
                    components = new Hashtable(); 
                }
 
                if (ctl != this.parent && !components.Contains(ctl)) 
                    components.Add(ctl, ctl);
 
                foreach(Control c in ctl.Controls) {
                    GetAllChildren(c);
                }
            } 

            ///  
            ///    [To be supplied.] 
            /// 
            private Hashtable GetComponents() { 
                return GetComponents(GetParentsContainer());
            }

            ///  
            ///    [To be supplied.]
            ///  
            private Hashtable GetComponents(IContainer cont) { 
                if (lockCount == 0) {
                    FillComponentsTable(cont); 
                }
                return components;
            }
 
            /// 
            ///    [To be supplied.] 
            ///  
            private bool GetControlBelongs(Control ctl) {
                Hashtable comps = GetComponents(); 
                return comps[ctl] != null;
            }

            ///  
            ///    [To be supplied.]
            ///  
            private IContainer GetParentIsDesigned() { 
                ISite site = parent.Site;
                if (site != null && site.DesignMode) return site.Container; 
                return null;
            }

            ///  
            ///    [To be supplied.]
            ///  
            private IContainer GetParentsContainer() { 
                IContainer rval = GetParentIsDesigned();
                Debug.Assert(rval == null || assocContainer == null || (rval == assocContainer), 
                             "mismatch between getIPD & aContainer");
                return rval == null ? assocContainer : rval;
            }
 
            /// 
            ///    [To be supplied.] 
            ///  
            private bool RegisterControl(AxHost ctl) {
                ISite site = ctl.Site; 
                if (site != null) {
                    IContainer cont = site.Container;
                    if (cont != null) {
                        if (assocContainer != null) { 
                            return cont == assocContainer;
                        } 
                        else { 
                            assocContainer = cont;
                            IComponentChangeService ccs = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); 
                            if (ccs != null) {
                                ccs.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved);
                            }
                            return true; 
                        }
                    } 
                } 
                return false;
            } 

            private void OnComponentRemoved(object sender, ComponentEventArgs e) {
                Control c = e.Component as Control;
                if (sender == assocContainer && c != null) { 
                    RemoveControl(c);
                } 
            } 

            ///  
            ///    [To be supplied.]
            /// 
            internal static AxContainer FindContainerForControl(Control ctl) {
                AxHost axctl = ctl as AxHost; 
                if (axctl != null)
                { 
                    if (axctl.container != null) return axctl.container; 
                    ContainerControl f = axctl.ContainingControl;
                    if (f != null) { 
                        AxContainer container = f.CreateAxContainer();
                        if (container.RegisterControl(axctl)) {
                            container.AddControl(axctl);
                            return container; 
                        }
                    } 
                } 
                return null;
            } 

#if false
            // FxCop: Currently not used
            private void OnOldActiveControl(Control valueOld, Control valueNew) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "onOAC called with old: "+valueOld.ToString()+" new: "+valueNew.ToString());
                if (!(valueOld is AxHost)) return; 
                AxContainer c = FindContainerForControl(valueOld); 
                if (c != null) {
                    c.OnOldActiveControlInternal(valueOld); 
                }
                else {
                    Debug.Fail("control w/o a container... pretty bad..."+valueOld.ToString());
                } 
            }
 
            ///  
            ///    [To be supplied.]
            ///  
            // FxCop: Currently not used
            private void OnOldActiveControlInternal(Control valueOld) {
                if (siteUIActive == valueOld) siteUIActive.UiDeactivate();
            } 

            // FxCop: Currently not used 
            private void OnNewActiveControl(Control value) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "onNAC called with new: "+value.ToString());
                if (!(value is AxHost)) return; 
                AxContainer c = FindContainerForControl(value);
                if (c != null) {
                    c.OnNewActiveControlInternal((AxHost)value);
                } 
                else {
                    Debug.Fail("control w/o a container... pretty bad..."+value.ToString()); 
                } 
            }
 
            /// 
            ///    [To be supplied.]
            /// 
            // FxCop: Currently not used 
            private void OnNewActiveControlInternal(AxHost value) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "New active control. siteUIActive is" +siteUIActive.ToString()+" Control is "+value.ToString()); 
                if (siteUIActive != null && siteUIActive != value) { 
                    Debug.Fail("we should not have an ui active site on this container!"+parent.ToString());
                    siteUIActive.UiDeactivate(); 
                }
#if DEBUG
                if (siteUIActive != null && siteUIActive != value) Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Why is "+siteUIActive.ToString()+" still active?");
                if (!value.CanUIActivate) Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "why can't "+value.ToString()+" be uiactivated?"); 
#endif
                if (siteUIActive == null && value.CanUIActivate) { 
                    // we need to uiactivate it ourselves... 
                    try {
                        ((AxHost)value).UiActivate(); 
                    }
                    catch (Exception e) {
                        Debug.Fail(e.ToString());
                    } 
                }
#if DEBUG 
                if (siteUIActive != parent.ActiveControl && value.CanUIActivate) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "form's active control is "+parent.ActiveControl.ToString());
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "could not reconcile active controls... bad things loom on the horizon..."); 
                }
#endif
                if (siteUIActive == null) {
                    // so now the form thinks that value is the active control but it's not ui active... 
                    // this can often lead to bad things unless we are carefull...
                    siteActive = value; 
                    // basically, when siteActive goes inplacedeactivate, we need to treat it the same as a 
                    // siteuiactive going uiactivedeactivate...
                } 
            }
#endif

            ///  
            ///    [To be supplied.]
            ///  
            internal void OnInPlaceDeactivate(AxHost site) { 
                if (siteActive == site) {
                    siteActive = null; 
                    if (site.GetSiteOwnsDeactivation()) {
                        parent.ActiveControl = null;
                    }
                    else { 
                        // we need to tell the form to switch activation to the next thingie...
                        Debug.Fail("what pathological control is calling inplacedeactivate by itself?"); 
                    } 
                }
            } 

            /// 
            ///    [To be supplied.]
            ///  
            internal void OnUIDeactivate(AxHost site) {
#if DEBUG 
                if (siteUIActive != null) 
                    Debug.Assert(siteUIActive == site, "deactivating when not active...");
#endif // DEBUG 

                siteUIActive = null;
                site.RemoveSelectionHandler();
                site.SetSelectionStyle(1); 
                site.editMode = EDITM_NONE;
                if (site.GetSiteOwnsDeactivation()) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, " our site owns deactivation "); 
                    ContainerControl f = site.ContainingControl;
                    Debug.Assert(f != null, "a control has to be on a ContainerControl..."); 
                    if (f != null) {
                        //    f.setActiveControl(null);
                    }
                } 
            }
 
            ///  
            ///    [To be supplied.]
            ///  
            internal void OnUIActivate(AxHost site) {
                // The ShDocVw control repeatedly calls OnUIActivate() with the same
                // site. This causes the assert below to fire.
                // 
                if (siteUIActive == site)
                    return; 
 
                if (siteUIActive != null && siteUIActive != site) {
                    AxHost tempSite = siteUIActive; 
                    bool ownDisposing = tempSite.GetAxState(AxHost.ownDisposing);
                    try {
                        tempSite.SetAxState(AxHost.ownDisposing, true);
                        tempSite.GetInPlaceObject().UIDeactivate(); 
                    }
                    finally { 
                        tempSite.SetAxState(AxHost.ownDisposing, ownDisposing); 
                    }
                } 
                site.AddSelectionHandler();
                Debug.Assert(siteUIActive == null, "Object did not call OnUIDeactivate");
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "active Object is now "+site.ToString());
                siteUIActive = site; 
                ContainerControl f = site.ContainingControl;
                Debug.Assert(f != null, "a control has to be on a ContainerControl..."); 
                if (f != null) { 
                    f.ActiveControl = site;
                } 
            }

            /// 
            ///    [To be supplied.] 
            /// 
            private void ListAxControls(ArrayList list, bool fuseOcx) { 
                Hashtable components = GetComponents(); 
                if (components == null) return;
                Control[] ctls = new Control[components.Keys.Count]; 
                components.Keys.CopyTo(ctls, 0);
                if (ctls != null) {
                    for (int i = 0; i < ctls.Length; i++) {
                        Control ctl = ctls[i]; 
                        AxHost hostctl = ctl as AxHost;
                        if (hostctl != null) { 
                            if (fuseOcx) { 
                                list.Add(hostctl.GetOcx());
                            } 
                            else {
                                list.Add(ctl);
                            }
                        } 
                    }
                } 
            } 

            ///  
            ///    [To be supplied.]
            /// 
            internal void ControlCreated(AxHost invoker) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in controlCreated for "+invoker.ToString()+" fAC: "+formAlreadyCreated.ToString()); 
                if (formAlreadyCreated) {
                    if (invoker.IsUserMode() && invoker.AwaitingDefreezing()) { 
                        invoker.Freeze(false); 
                    }
                } 
                else {
                    // the form will be created in the future
                    parent.CreateAxContainer();
                } 
            }
 
            internal void FormCreated() { 
                if (formAlreadyCreated) return;
                formAlreadyCreated = true; 
                ArrayList l = new ArrayList();
                ListAxControls(l, false);
                AxHost[] axControls = new AxHost[l.Count];
                l.CopyTo(axControls, 0); 
                for (int i = 0; i < axControls.Length; i++) {
                    AxHost control = axControls[i]; 
                    if (control.GetOcState() >= OC_RUNNING && control.IsUserMode() && control.AwaitingDefreezing()) { 
                        control.Freeze(false);
                    } 
                }
            }

 
            // IOleContainer methods:
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleContainer.ParseDisplayName(Object pbc, string pszDisplayName, int[] pchEaten, Object[] ppmkOut) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in ParseDisplayName");
                if (ppmkOut != null) 
                    ppmkOut[0] = null;
                 return NativeMethods.E_NOTIMPL; 
            } 

 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            int UnsafeNativeMethods.IOleContainer.EnumObjects(int grfFlags, out UnsafeNativeMethods.IEnumUnknown ppenum) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in EnumObjects"); 
                ppenum = null; 
                if ((grfFlags & 1) != 0) { // 1 == OLECONTF_EMBEDDINGS
                    Debug.Assert(parent != null, "gotta have it..."); 
                    ArrayList list = new ArrayList();
                    ListAxControls(list, true);
                    if (list.Count > 0) {
                        Object[] temp = new Object[list.Count]; 
                        list.CopyTo(temp, 0);
                        ppenum = new EnumUnknown(temp); 
                        return NativeMethods.S_OK; 
                    }
                } 
                ppenum = new EnumUnknown(null);
                return NativeMethods.S_OK;
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleContainer.LockContainer(bool fLock) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in LockContainer");
                return NativeMethods.E_NOTIMPL;
            }
 
            // IOleInPlaceFrame methods:
 
            IntPtr UnsafeNativeMethods.IOleInPlaceFrame.GetWindow() { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetWindow");
                return parent.Handle; 
            }

            int UnsafeNativeMethods.IOleInPlaceFrame.ContextSensitiveHelp(int fEnterMode) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in ContextSensitiveHelp"); 
                return NativeMethods.S_OK;
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.GetBorder(NativeMethods.COMRECT lprectBorder) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetBorder"); 
                return NativeMethods.E_NOTIMPL;
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.RequestBorderSpace(NativeMethods.COMRECT pborderwidths) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in RequestBorderSpace"); 
                return NativeMethods.E_NOTIMPL;
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.SetBorderSpace(NativeMethods.COMRECT pborderwidths) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in SetBorderSpace"); 
                return NativeMethods.E_NOTIMPL;
            } 
 
            /// 
            ///    [To be supplied.] 
            /// 
            internal void OnExitEditMode(AxHost ctl) {
                Debug.Assert(ctlInEditMode == null || ctlInEditMode == ctl, "who is exiting edit mode?");
                if (ctlInEditMode == null || ctlInEditMode != ctl) return; 
                ctlInEditMode = null;
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.SetActiveObject(UnsafeNativeMethods.IOleInPlaceActiveObject pActiveObject, string pszObjName) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in SetActiveObject " + ((pszObjName == null) ? "" : pszObjName)); 
                if (siteUIActive != null) {
                    if (siteUIActive.iOleInPlaceActiveObjectExternal != pActiveObject) { 
                        if (siteUIActive.iOleInPlaceActiveObjectExternal != null) { 
                            Marshal.ReleaseComObject(siteUIActive.iOleInPlaceActiveObjectExternal);
                        } 
                        siteUIActive.iOleInPlaceActiveObjectExternal = pActiveObject;
                    }
                }
                if (pActiveObject == null) { 
                    if (ctlInEditMode != null) {
                        ctlInEditMode.editMode = EDITM_NONE; 
                        ctlInEditMode = null; 
                    }
                    return NativeMethods.S_OK; 
                }
                AxHost ctl = null;
                if (pActiveObject is UnsafeNativeMethods.IOleObject) {
                    UnsafeNativeMethods.IOleObject oleObject = (UnsafeNativeMethods.IOleObject) pActiveObject; 
                    UnsafeNativeMethods.IOleClientSite clientSite = null;
                    try { 
                        clientSite = oleObject.GetClientSite(); 
                        if (clientSite is OleInterfaces) {
                            ctl = ((OleInterfaces)(clientSite)).GetAxHost(); 
                        }
                    }
                    catch (COMException t) {
                        Debug.Fail(t.ToString()); 
                    }
                    if (ctlInEditMode != null) { 
                        Debug.Fail("control " + ctlInEditMode.ToString() + " did not reset its edit mode to null"); 
                        ctlInEditMode.SetSelectionStyle(1);
                        ctlInEditMode.editMode = EDITM_NONE; 
                    }

                    if (ctl == null) {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "control w/o a valid site called setactiveobject"); 
                        ctlInEditMode = null;
                    } 
                    else { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "resolved to " + ctl.ToString());
                        if (!ctl.IsUserMode()) { 
                            ctlInEditMode = ctl;
                            ctl.editMode = EDITM_OBJECT;
                            ctl.AddSelectionHandler();
                            ctl.SetSelectionStyle(2); 
                        }
                    } 
                } 
                return NativeMethods.S_OK;
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.InsertMenus(IntPtr hmenuShared, NativeMethods.tagOleMenuGroupWidths lpMenuWidths) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in InsertMenus"); 
                return NativeMethods.S_OK;
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.SetMenu(IntPtr hmenuShared, IntPtr holemenu, IntPtr hwndActiveObject) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in SetMenu"); 
                return NativeMethods.E_NOTIMPL;
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.RemoveMenus(IntPtr hmenuShared) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in RemoveMenus"); 
                return NativeMethods.E_NOTIMPL;
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.SetStatusText(string pszStatusText) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in SetStatusText"); 
                return NativeMethods.E_NOTIMPL;
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            int UnsafeNativeMethods.IOleInPlaceFrame.EnableModeless(bool fEnable) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in EnableModeless"); 
                return NativeMethods.E_NOTIMPL;
            } 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            int UnsafeNativeMethods.IOleInPlaceFrame.TranslateAccelerator(ref NativeMethods.MSG lpmsg, short wID) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in IOleInPlaceFrame.TranslateAccelerator"); 
                return NativeMethods.S_FALSE; 
            }
 
            // EXPOSED

            /// 
            ///  
            private class ExtenderProxy : UnsafeNativeMethods.IExtender, UnsafeNativeMethods.IVBGetControl, UnsafeNativeMethods.IGetVBAObject, UnsafeNativeMethods.IGetOleObject, IReflect {
                private WeakReference pRef; 
                private WeakReference pContainer; 

                internal ExtenderProxy(Control principal, AxContainer container) { 
                    pRef = new WeakReference(principal);
                    pContainer = new WeakReference(container);
                }
 
                private Control GetP() {
                    return(Control) pRef.Target; 
                } 

                private AxContainer GetC() { 
                    return(AxContainer) pContainer.Target;
                }

                int UnsafeNativeMethods.IVBGetControl.EnumControls(int dwOleContF, int dwWhich, out UnsafeNativeMethods.IEnumUnknown ppenum) { 
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in EnumControls for proxy");
                    ppenum = GetC().EnumControls(GetP(), dwOleContF, dwWhich); 
                    return NativeMethods.S_OK; 
                }
 
                object UnsafeNativeMethods.IGetOleObject.GetOleObject(ref Guid riid) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetOleObject for proxy");
                    if (!riid.Equals(ioleobject_Guid))
                        throw E_INVALIDARG; 

                    Control ctl = GetP(); 
                    if (ctl != null && ctl is AxHost) { 
                        return ((AxHost)ctl).GetOcx();
                    } 

                    throw E_FAIL;
                }
 
                int UnsafeNativeMethods.IGetVBAObject.GetObject(ref Guid riid, UnsafeNativeMethods.IVBFormat[] rval, int dwReserved) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in GetObject for proxy"); 
                    if (rval == null || riid.Equals(Guid.Empty)) 
                        return NativeMethods.E_INVALIDARG;
 
                    if (riid.Equals(ivbformat_Guid)) {
                        rval[0] = new VBFormat();
                        return NativeMethods.S_OK;
                    } 
                    else {
                        rval[0] = null; 
                        return NativeMethods.E_NOINTERFACE; 
                    }
                } 

                public int Align {
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getAlign for proxy for "+ GetP().ToString()); 
                        int rval = (int)((Control)GetP()).Dock;
                        if (rval < NativeMethods.ActiveX.ALIGN_MIN || rval > NativeMethods.ActiveX.ALIGN_MAX) { 
                            rval = NativeMethods.ActiveX.ALIGN_NO_CHANGE; 
                        }
                        return rval; 
                    }

                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setAlign for proxy for "+ GetP().ToString()+" "+ 
                                          value.ToString(CultureInfo.InvariantCulture));
                        GetP().Dock = (DockStyle)value; 
                    } 
                }
 
                public UInt32 BackColor {
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getBackColor for proxy for "+ GetP().ToString());
                        return AxHost.GetOleColorFromColor(((Control)GetP()).BackColor); 
                    }
 
                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setBackColor for proxy for "+ GetP().ToString()+" "+
                                          value.ToString(CultureInfo.InvariantCulture)); 
                        GetP().BackColor = AxHost.GetColorFromOleColor(value);
                    }
                }
 
                public bool Enabled {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getEnabled for proxy for "+ GetP().ToString()); 
                        return GetP().Enabled;
                    } 

                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setEnabled for proxy for "+ GetP().ToString()+" "+value.ToString());
                        GetP().Enabled = value; 
                    }
                } 
 
                public UInt32 ForeColor {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getForeColor for proxy for "+ GetP().ToString());
                        return AxHost.GetOleColorFromColor(((Control)GetP()).ForeColor);
                    }
 
                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setForeColor for proxy for "+ GetP().ToString()+" "+ 
                                          value.ToString(CultureInfo.InvariantCulture)); 
                        GetP().ForeColor = AxHost.GetColorFromOleColor(value);
                    } 
                }

                public int Height {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getHeight for proxy for "+ GetP().ToString());
                        return Pixel2Twip(GetP().Height, false); 
                    } 

                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setHeight for proxy for "+ GetP().ToString()+" "+
                                          Twip2Pixel(value,false).ToString(CultureInfo.InvariantCulture));
                        GetP().Height = Twip2Pixel(value, false);
                    } 
                }
 
                public int Left { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getLeft for proxy for "+ GetP().ToString()); 
                        return Pixel2Twip(GetP().Left, true);
                    }

                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setLeft for proxy for "+ GetP().ToString()+" "+
                                          Twip2Pixel(value, true).ToString(CultureInfo.InvariantCulture)); 
                        GetP().Left = Twip2Pixel(value, true); 
                    }
                } 

                public object Parent {
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getParent for proxy for "+ GetP().ToString()); 
                        return GetC().GetProxyForControl(GetC().parent);
                    } 
                } 

                public short TabIndex { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getTabIndex for proxy for "+ GetP().ToString());
                        return (short)GetP().TabIndex;
                    } 

                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setTabIndex for proxy for "+ GetP().ToString()+" "+ 
                                          value.ToString(CultureInfo.InvariantCulture));
                        GetP().TabIndex = (int)value; 
                    }
                }

                public bool TabStop { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getTabStop for proxy for "+ GetP().ToString()); 
                        return GetP().TabStop; 
                    }
 
                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setTabStop for proxy for "+ GetP().ToString()+" "+value.ToString());
                        GetP().TabStop = value;
                    } 
                }
 
                public int Top { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getTop for proxy for "+ GetP().ToString()); 
                        return Pixel2Twip(GetP().Top, false);
                    }

                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setTop for proxy for "+ GetP().ToString()+" "+
                                          Twip2Pixel(value, false).ToString(CultureInfo.InvariantCulture)); 
                        GetP().Top = Twip2Pixel(value, false); 
                    }
                } 

                public bool Visible {
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getVisible for proxy for "+ GetP().ToString()); 
                        return GetP().Visible;
                    } 
 
                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setVisible for proxy for "+ GetP().ToString()+" "+value.ToString()); 
                        GetP().Visible = value;
                    }
                }
 
                public int Width {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getWidth for proxy for "+ GetP().ToString()); 
                        return Pixel2Twip(GetP().Width,true);
                    } 

                    set {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setWidth for proxy for "+ GetP().ToString()+" "+
                                          Twip2Pixel(value, true).ToString(CultureInfo.InvariantCulture)); 
                        GetP().Width = Twip2Pixel(value, true);
                    } 
                } 

                public string Name { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getName for proxy for "+ GetP().ToString());
                        return GetC().GetNameForControl(GetP());
                    } 
                }
 
                public IntPtr Hwnd { 
                    get {
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getHwnd for proxy for "+ GetP().ToString()); 
                        return GetP().Handle;
                    }
                }
 
                public object Container {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getContainer for proxy for "+ GetP().ToString()); 
                        return GetC().GetProxyForContainer();
                    } 
                }

                public string Text {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in getText for proxy for "+ GetP().ToString());
                        return GetP().Text; 
                    } 

                    set { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in setText for proxy for "+ GetP().ToString());
                        GetP().Text = value;
                    }
                } 

                public void Move(Object left, Object top, Object width, Object height) { 
                } 

                // IReflect methods: 

                MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr,Binder binder, Type[] types,ParameterModifier[] modifiers) {
                    return null;
                } 

                MethodInfo IReflect.GetMethod(String name,BindingFlags bindingAttr) { 
                    return null; 
                }
 
                MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) {
                    return new MethodInfo[] {this.GetType().GetMethod("Move")};
                }
 
                FieldInfo IReflect.GetField(String name, BindingFlags bindingAttr) {
                    return null; 
                } 

                FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) { 
                    return new FieldInfo[0];
                }

                PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr) { 
                    PropertyInfo prop = GetP().GetType().GetProperty(name, bindingAttr);
                    if (prop == null) { 
                        prop = this.GetType().GetProperty(name, bindingAttr); 
                    }
                    return prop; 
                }

                PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr, Binder binder,Type returnType, Type[] types, ParameterModifier[] modifiers) {
                    PropertyInfo prop = GetP().GetType().GetProperty(name, bindingAttr, binder, returnType, types, modifiers); 
                    if (prop == null) {
                        prop = this.GetType().GetProperty(name, bindingAttr, binder, returnType, types, modifiers); 
                    } 
                    return prop;
                } 

                PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) {
                    PropertyInfo[] extenderProps = this.GetType().GetProperties(bindingAttr);
                    PropertyInfo[] ctlProps = GetP().GetType().GetProperties(bindingAttr); 

                    if (extenderProps == null) { 
                        return ctlProps; 
                    }
                    else if (ctlProps == null) { 
                        return extenderProps;
                    }
                    else {
                        int iProp = 0; 
                        PropertyInfo[] props = new PropertyInfo[extenderProps.Length + ctlProps.Length];
 
                        foreach(PropertyInfo prop in extenderProps) { 
                            props[iProp++] = prop;
                        } 

                        foreach(PropertyInfo prop in ctlProps) {
                            props[iProp++] = prop;
                        } 

                        return props; 
                    } 
                }
 
                MemberInfo[] IReflect.GetMember(String name, BindingFlags bindingAttr) {
                    MemberInfo[] memb = GetP().GetType().GetMember(name, bindingAttr);
                    if (memb == null) {
                        memb = this.GetType().GetMember(name, bindingAttr); 
                    }
                    return memb; 
                } 

                MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) { 
                    MemberInfo[] extenderMembs = this.GetType().GetMembers(bindingAttr);
                    MemberInfo[] ctlMembs = GetP().GetType().GetMembers(bindingAttr);

                    if (extenderMembs == null) { 
                        return ctlMembs;
                    } 
                    else if (ctlMembs == null) { 
                        return extenderMembs;
                    } 
                    else {
                        MemberInfo[] membs = new MemberInfo[extenderMembs.Length + ctlMembs.Length];

                        Array.Copy(extenderMembs, 0, membs, 0, extenderMembs.Length); 
                        Array.Copy(ctlMembs, 0, membs, extenderMembs.Length, ctlMembs.Length);
 
                        return membs; 
                    }
                } 

                Object IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder,
                                             Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) {
                    try { 
                        return this.GetType().InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
                    } 
                    catch(MissingMethodException) { 
                        return this.GetP().GetType().InvokeMember(name, invokeAttr, binder, GetP(), args, modifiers, culture, namedParameters);
                    } 
                }

                Type IReflect.UnderlyingSystemType {
                    get { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "In UnderlyingSystemType");
                        return null; 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///      StateConverter is a class that can be used to convert
        ///      State from one data type to another.  Access this 
        ///      class through the TypeDescriptor. 
        /// 
        ///  
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")]
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")]
        public class StateConverter : TypeConverter {
 
            /// 
            ///  
            ///    Gets a value indicating whether this converter can 
            ///       convert an object in the given source type to the native type of the converter
            ///       using the context. 
            /// 
            /// 
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
                if (sourceType == typeof(byte[])) { 
                    return true;
                } 
 
                return base.CanConvertFrom(context, sourceType);
            } 

            /// 
            /// 
            ///    Gets a value indicating whether this converter can 
            ///       convert an object to the given destination type using the context.
            ///  
            ///  
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
                if (destinationType == typeof(byte[])) { 
                    return true;
                }

                return base.CanConvertTo(context, destinationType); 
            }
 
            ///  
            /// 
            ///    Converts the given object to the converter's native type. 
            /// 
            /// 
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
                if (value is byte[]) { 
                    MemoryStream ms = new MemoryStream((byte[])value);
                    return new State(ms); 
                } 

                return base.ConvertFrom(context, culture, value); 
            }

            /// 
            ///  
            ///      Converts the given object to another type.  The most common types to convert
            ///      are to and from a string object.  The default implementation will make a call 
            ///      to ToString on the object if the object is valid and if the destination 
            ///      type is string.  If this cannot convert to the desitnation type, this will
            ///      throw a NotSupportedException. 
            /// 
            /// 
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
                if (destinationType == null) { 
                    throw new ArgumentNullException("destinationType");
                } 
 
                if (destinationType == typeof(byte[])) {
                    if (value != null) { 
                        MemoryStream ms = new MemoryStream();
                        State state = (State)value;
                        state.Save(ms);
                        ms.Close(); 
                        return ms.ToArray();
                    } 
                    else 
                        return new byte[0];
                } 

                return base.ConvertTo(context, culture, value, destinationType);
            }
        } 

        ///  
        ///  
        ///    The class which encapsulates the persisted state of the underlying activeX control
        ///       An instance of this class my be obtained either by calling getOcxState on an 
        ///       AxHost object, or by reading in from a stream.
        /// 
        [
            TypeConverterAttribute(typeof(TypeConverter)), 
            Serializable
        ] 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")] 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")]
        [SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")] 
        public class State : ISerializable {
            private int VERSION = 1;
            private int length;
            private byte[] buffer; 
            internal int type;
            private MemoryStream ms; 
            private UnsafeNativeMethods.IStorage storage; 
            private UnsafeNativeMethods.ILockBytes iLockBytes;
            private bool manualUpdate = false; 
            private string licenseKey = null;
            private PropertyBagStream propBag;

            // create on save from ipersist stream 
            /// 
            ///    [To be supplied.] 
            ///  
            internal State(MemoryStream ms, int storageType, AxHost ctl, PropertyBagStream propBag) {
                type = storageType; 
                this.propBag = propBag;
                // dangerous?
                length = (int)ms.Length;
                this.ms = ms; 
                this.manualUpdate = ctl.GetAxState(AxHost.manualUpdate);
                this.licenseKey = ctl.GetLicenseKey(); 
            } 

            internal State(PropertyBagStream propBag) { 
                this.propBag = propBag;
            }

            internal State(MemoryStream ms) { 
                this.ms = ms;
                this.length = (int)ms.Length; 
                InitializeFromStream(ms); 
            }
 
            // create on init new w/ storage...
            /// 
            ///    [To be supplied.]
            ///  
            internal State(AxHost ctl) {
                CreateStorage(); 
                manualUpdate = ctl.GetAxState(AxHost.manualUpdate); 
                licenseKey = ctl.GetLicenseKey();
                type = STG_STORAGE; 
            }

            /// 
            ///  
            ///    [To be supplied.]
            ///  
            public State(Stream ms, int storageType, bool manualUpdate, string licKey) { 
                type = storageType;
                // dangerous? 
                length = (int)ms.Length;
                this.manualUpdate = manualUpdate;
                this.licenseKey = licKey;
 
                InitializeBufferFromStream(ms);
            } 
 
            /**
             * Constructor used in deserialization 
             */
            protected State(SerializationInfo info, StreamingContext context) {
                SerializationInfoEnumerator sie = info.GetEnumerator();
                if (sie == null) { 
                    return;
                } 
                for (; sie.MoveNext();) { 
                    if (String.Compare(sie.Name, "Data", true, CultureInfo.InvariantCulture) == 0) {
                        try { 
                            byte[] dat = (byte[])sie.Value;
                            if (dat != null) {
                                InitializeFromStream(new MemoryStream(dat));
                            } 

                        } 
                        catch (Exception e) { 
                            Debug.Fail("failure: " + e.ToString());
                        } 
                    }
                    else if (String.Compare(sie.Name, "PropertyBagBinary", true, CultureInfo.InvariantCulture) == 0) {
                        try {
                            Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Loading up property bag from stream..."); 
                            byte[] dat = (byte[])sie.Value;
                            if (dat != null) { 
                                this.propBag = new PropertyBagStream(); 
                                propBag.Read(new MemoryStream(dat));
                            } 

                        }
                        catch (Exception e) {
                            Debug.Fail("failure: " + e.ToString()); 
                        }
                    } 
                } 
            }
 
            /// 
            ///    [To be supplied.]
            /// 
            internal int Type { 
                get {
                    return type; 
                } 
                set {
                    type = value; 
                }
            }

            internal bool _GetManualUpdate() { 
                return manualUpdate;
            } 
 
            internal string _GetLicenseKey() {
                return licenseKey; 
            }

            /// 
            ///    [To be supplied.] 
            /// 
            private void CreateStorage() { 
                Debug.Assert(storage == null, "but we already have a storage!!!"); 
                IntPtr hglobal = IntPtr.Zero;
                if (buffer != null) { 
                    hglobal = UnsafeNativeMethods.GlobalAlloc(NativeMethods.GMEM_MOVEABLE, length);
                    IntPtr pointer = UnsafeNativeMethods.GlobalLock(new HandleRef(null, hglobal));
                    try {
                        if (pointer != IntPtr.Zero) { 
                            Marshal.Copy(buffer, 0, pointer, length);
                        } 
                    } 
                    finally {
                        UnsafeNativeMethods.GlobalUnlock(new HandleRef(null, hglobal)); 
                    }
                }
                bool failed = false;
                try { 
                    iLockBytes = UnsafeNativeMethods.CreateILockBytesOnHGlobal(new HandleRef(null, hglobal), true);
                    if (buffer == null) { 
                        storage = UnsafeNativeMethods.StgCreateDocfileOnILockBytes(iLockBytes, 
                                                                                   NativeMethods.STGM_CREATE | NativeMethods.STGM_READWRITE | NativeMethods.STGM_SHARE_EXCLUSIVE, 0);
                    } 
                    else {
                        storage = UnsafeNativeMethods.StgOpenStorageOnILockBytes(iLockBytes,
                                                                                 null, NativeMethods.STGM_READWRITE | NativeMethods.STGM_SHARE_EXCLUSIVE, 0, 0);
                    } 
                }
                catch (Exception t) { 
                    Debug.Fail(t.ToString()); 
                    failed = true;
                } 
                if (failed) {
                    if (iLockBytes == null && hglobal != IntPtr.Zero) {
                        UnsafeNativeMethods.GlobalFree(new HandleRef(null, hglobal));
                    } 
                    else {
                        iLockBytes = null; 
                    } 
                    storage = null;
                } 
            }

            internal UnsafeNativeMethods.IPropertyBag GetPropBag() {
                return propBag; 
            }
 
            internal UnsafeNativeMethods.IStorage GetStorage() { 
                if (storage == null)
                    CreateStorage(); 
                return storage;
            }

           internal UnsafeNativeMethods.IStream GetStream() { 
                if (ms == null) {
                    Debug.Assert(buffer != null, "gotta have the buffer already..."); 
                    if (buffer == null) return null; 
                    ms = new MemoryStream(buffer);
                } 
                else {
                    ms.Seek(0, SeekOrigin.Begin);
                }
                return new UnsafeNativeMethods.ComStreamFromDataStream(ms); 
            }
 
            private void InitializeFromStream(Stream ids) { 
               BinaryReader br = new BinaryReader(ids);
 
               type = br.ReadInt32();
               int version = br.ReadInt32();
               manualUpdate = br.ReadBoolean();
               int cc = br.ReadInt32(); 
               if (cc != 0) {
                   licenseKey = new string(br.ReadChars(cc)); 
               } 
               for (int skipUnits = br.ReadInt32(); skipUnits > 0; skipUnits --) {
                   int len = br.ReadInt32(); 
                   ids.Position = ids.Position + len;
               }

               length = br.ReadInt32(); 
               if (length > 0)
                   buffer = br.ReadBytes(length); 
            } 

            private void InitializeBufferFromStream(Stream ids) { 
                BinaryReader br = new BinaryReader(ids);

                length = br.ReadInt32();
                if (length > 0) 
                    buffer = br.ReadBytes(length);
            } 
 
            internal State RefreshStorage(UnsafeNativeMethods.IPersistStorage iPersistStorage) {
                Debug.Assert(storage != null, "how can we not have a storage object?"); 
                Debug.Assert(iLockBytes != null, "how can we have a storage w/o ILockBytes?");
                if (storage == null || iLockBytes == null) return null;
                iPersistStorage.Save(storage, true);
                storage.Commit(0); 
                iPersistStorage.HandsOffStorage();
                try { 
                    buffer = null; 
                    ms = null;
                    NativeMethods.STATSTG stat = new NativeMethods.STATSTG(); 
                    iLockBytes.Stat(stat, NativeMethods.Ole.STATFLAG_NONAME);
                    length = (int) stat.cbSize;
                    buffer = new byte[length];
                    IntPtr hglobal = UnsafeNativeMethods.GetHGlobalFromILockBytes(iLockBytes); 
                    IntPtr pointer = UnsafeNativeMethods.GlobalLock(new HandleRef(null, hglobal));
                    try { 
                        if (pointer != IntPtr.Zero) { 
                            Marshal.Copy(pointer, buffer, 0, length);
                        } 
                        else {
                            length = 0;
                            buffer = null;
                        } 
                    }
                    finally { 
                        UnsafeNativeMethods.GlobalUnlock(new HandleRef(null, hglobal)); 
                    }
                } 
                finally {
                    iPersistStorage.SaveCompleted(storage);
                }
                return this; 
            }
 
            internal void Save(MemoryStream stream) { 
                BinaryWriter bw = new BinaryWriter(stream);
 
                bw.Write(type);
                bw.Write(VERSION);
                bw.Write(manualUpdate);
                if (licenseKey != null) { 
                    bw.Write(licenseKey.Length);
                    bw.Write(licenseKey.ToCharArray()); 
                } 
                else {
                    bw.Write((int)0); 
                }
                bw.Write((int)0); // skip units
                bw.Write(length);
                if (buffer != null) { 
                    bw.Write(buffer);
                } 
                else if (ms != null) { 
                    ms.Position = 0;
                    ms.WriteTo(stream); 
                }
                else {
                    Debug.Assert(length == 0, "if we have no data, then our length has to be 0");
                } 
            }
 
            ///  
            /// 
            /// ISerializable private implementation 
            /// 
            /// 
            void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
                IntSecurity.UnmanagedCode.Demand(); 
                MemoryStream stream = new MemoryStream();
                Save(stream); 
 
                si.AddValue("Data", stream.ToArray());
 
                if (propBag != null) {
                    try {
                        stream = new MemoryStream();
                        propBag.Write(stream); 
                        si.AddValue("PropertyBagBinary", stream.ToArray());
                    } 
                    catch (Exception e) { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to serialize the property bag into ResX : " + e.ToString());
                    } 
                }
            }
        }
 
        internal class PropertyBagStream : UnsafeNativeMethods.IPropertyBag {
            private Hashtable bag = new Hashtable(); 
 
            internal void Read(Stream stream) {
                BinaryFormatter formatter = new BinaryFormatter(); 
                try {
                    bag = (Hashtable)formatter.Deserialize(stream);
                }
                catch { 
                    // Error reading.  Just init an empty hashtable.
                    bag = new Hashtable(); 
                } 
            }
 
            int UnsafeNativeMethods.IPropertyBag.Read(string pszPropName, ref object pVar, UnsafeNativeMethods.IErrorLog pErrorLog) {
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Reading property " + pszPropName +  " from OCXState propertybag.");

                if (!bag.Contains(pszPropName)) 
                    return NativeMethods.E_INVALIDARG;
 
                pVar = bag[pszPropName]; 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\tValue=" + ((pVar == null) ? "" : pVar.ToString()));
 
                // The EE returns a VT_EMPTY for a null. The problem is that visual basic6 expects the caller to respect the
                // "hint" it gives in the VariantType. For eg., for a VT_BSTR, it expects that the callee will null
                // out the BSTR field of the variant. Since, the EE or us cannot do anything about this, we will return
                // a E_INVALIDARG rather than let visual basic6 crash. 
                //
                return (pVar == null) ? NativeMethods.E_INVALIDARG : NativeMethods.S_OK; 
            } 

            int UnsafeNativeMethods.IPropertyBag.Write(string pszPropName, ref object pVar) { 
                Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Writing property " + pszPropName + " [" + pVar + "] into OCXState propertybag.");
                if (pVar != null && !pVar.GetType().IsSerializable) {
                    Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t " + pVar.GetType().FullName + " is not serializable.");
                    return NativeMethods.S_OK; 
                }
 
                bag[pszPropName] = pVar; 
                return NativeMethods.S_OK;
            } 

            internal void Write(Stream stream) {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, bag); 
            }
        } 
 
        /// 
        protected delegate void AboutBoxDelegate(); 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")] 
        [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] 
        [ComVisible(false)]
        public class AxComponentEditor : WindowsFormsComponentEditor { 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public override bool EditComponent(ITypeDescriptorContext context, object obj, IWin32Window parent) {
                AxHost host = obj as AxHost; 
                if (host != null) 
                {
                    try { 
                        Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "in AxComponentEditor.EditComponent");
                        ((UnsafeNativeMethods.IOleControlSite)host.oleSite).ShowPropertyFrame();
                        return true;
                    } 
                    catch (Exception t) {
                        Debug.Fail(t.ToString()); 
                        throw; 
                    }
                } 
                return false;
            }
        }
 
        /// 
        ///  
        internal class AxPropertyDescriptor : PropertyDescriptor { 
            private  PropertyDescriptor baseProp;
            internal AxHost            owner; 
            private  DispIdAttribute   dispid;

            private  TypeConverter     converter;
            private  UITypeEditor      editor; 
            private  ArrayList         updateAttrs = new ArrayList();
            private  int               flags = 0; 
 
            private  const int         FlagUpdatedEditorAndConverter = 0x00000001;
            private  const int         FlagCheckGetter               = 0x00000002; 
            private  const int         FlagGettterThrew              = 0x00000004;
            private  const int         FlagIgnoreCanAccessProperties = 0x00000008;
            private  const int         FlagSettingValue              = 0x00000010;
 

 
 

            [ 
                SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")  // Shipped in Everett
            ]
            internal AxPropertyDescriptor(PropertyDescriptor baseProp, AxHost owner) : base(baseProp) {
                this.baseProp = baseProp; 
                this.owner = owner;
 
                // Get the category for this dispid. 
                //
                dispid = (DispIdAttribute)baseProp.Attributes[typeof(DispIdAttribute)]; 
                if (dispid != null) {
                    // Look to see if this property has a property page.
                    // If it does, then it needs to be Browsable(true).
                    // 
                    if (!this.IsBrowsable && !this.IsReadOnly) {
                        Guid g = GetPropertyPage(dispid.Value); 
 
                        if (!Guid.Empty.Equals(g)) {
                           Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Making property: " + this.Name + " browsable because we found an property page."); 
                           AddAttribute(new BrowsableAttribute(true));
                        }
                    }
 
                    // Use the CategoryAttribute provided by the OCX.
                    // 
                    CategoryAttribute cat = owner.GetCategoryForDispid(dispid.Value); 
                    if (cat != null) {
                        AddAttribute(cat); 
                    }

                    // Check to see if this a DataSource property.
                    // If it is, we can always get and set the value of this property. 
                    //
                    if (this.PropertyType.GUID.Equals(dataSource_Guid)) { 
                        SetFlag(FlagIgnoreCanAccessProperties, true); 
                    }
                } 
            }

            public override Type ComponentType {
                get { 
                    return baseProp.ComponentType;
                } 
            } 

            public override TypeConverter Converter { 
                get {

                    if (dispid != null) {
                        UpdateTypeConverterAndTypeEditorInternal(false, Dispid); 
                    }
                    return (converter != null) ? converter : base.Converter; 
                } 
            }
 
            internal int Dispid {
                get {
                    DispIdAttribute dispid = (DispIdAttribute)baseProp.Attributes[typeof(DispIdAttribute)];
                    if (dispid != null) { 
                        return dispid.Value;
                    } 
 
                    return NativeMethods.ActiveX.DISPID_UNKNOWN;
                } 
            }

            public override bool IsReadOnly {
                get { 
                    return baseProp.IsReadOnly;
                } 
            } 

            public override Type PropertyType { 
                get {
                    return baseProp.PropertyType;
                }
            } 

            internal bool SettingValue { 
                get { 
                    return GetFlag(FlagSettingValue);
                } 
            }

            private void AddAttribute(Attribute attr) {
                updateAttrs.Add(attr); 
            }
 
            public override bool CanResetValue(object o) { 
                return baseProp.CanResetValue(o);
            } 

            public override object GetEditor(Type editorBaseType) {

                UpdateTypeConverterAndTypeEditorInternal(false, dispid.Value); 

                if (editorBaseType.Equals(typeof(UITypeEditor)) && editor != null) { 
                    return editor; 
                }
 
                return base.GetEditor(editorBaseType);
            }

            private bool GetFlag(int flagValue) { 
                return ((flags & flagValue) == flagValue);
            } 
 
            private Guid GetPropertyPage(int dispid) {
                try { 
                    NativeMethods.IPerPropertyBrowsing ippb = owner.GetPerPropertyBrowsing();
                    if (ippb == null) return Guid.Empty;
                    Guid rval;
                    if (NativeMethods.Succeeded(ippb.MapPropertyToPage(dispid, out rval))) { 
                        return rval;
                    } 
                } 
                catch (COMException) {
                } 
                catch (Exception t) {
                    Debug.Fail(t.ToString());
                }
                return Guid.Empty; 
            }
 
            public override object GetValue(object component) { 
                if ((!GetFlag(FlagIgnoreCanAccessProperties) && !owner.CanAccessProperties) || GetFlag(FlagGettterThrew)) {
                    return null; 
                }

                try {
                    // Some controls fire OnChanged() notifications when getting values of some properties. ASURT 20190. 
                    // To prevent this kind of recursion, we check to see if we are already inside a OnChanged() call.
                    // 
                    owner.NoComponentChangeEvents++; 
                    return baseProp.GetValue(component);
                } 
                catch (Exception e) {
                    if (!GetFlag(FlagCheckGetter)) {
                        Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Get failed for : " + Name + " with exception: " + e.Message + " .Making property non-browsable.");
                        SetFlag(FlagCheckGetter, true); 
                        AddAttribute(new BrowsableAttribute(false));
                        owner.RefreshAllProperties = true; 
                        SetFlag(FlagGettterThrew, true); 
                    }
                    throw e; 
                }
                finally {
                    owner.NoComponentChangeEvents--;
                } 
            }
 
            public void OnValueChanged(object component) { 
                this.OnValueChanged(component, EventArgs.Empty);
            } 

            public override void ResetValue(object o) {
                baseProp.ResetValue(o);
            } 

            private void SetFlag(int flagValue, bool value) { 
                if (value) { 
                    flags |= flagValue;
                } 
                else {
                    flags &= ~flagValue;
                }
            } 

            public override void SetValue(Object component, Object value) { 
                if (!GetFlag(FlagIgnoreCanAccessProperties) && !owner.CanAccessProperties) { 
                    return;
                } 

                // State oldOcxState = owner.OcxState;

                try { 
                    SetFlag(FlagSettingValue, true);
                    if (this.PropertyType.IsEnum && (value.GetType() != this.PropertyType)) { 
                        baseProp.SetValue(component, Enum.ToObject(this.PropertyType, value)); 
                    }
                    else { 
                        baseProp.SetValue(component, value);
                    }
                }
                finally { 
                    SetFlag(FlagSettingValue, false);
                } 
 
                OnValueChanged(component);
                if (owner == component) { 
                    owner.SetAxState(AxHost.valueChanged, true);
                }
            }
 
            public override bool ShouldSerializeValue(object o) {
                return baseProp.ShouldSerializeValue(o); 
            } 

            internal void UpdateAttributes() { 
                if (updateAttrs.Count == 0)
                    return;

                ArrayList attributes = new ArrayList(AttributeArray); 
                foreach(Attribute attr in updateAttrs) {
                    attributes.Add(attr); 
                } 

                Attribute[] temp = new Attribute[attributes.Count]; 
                attributes.CopyTo(temp, 0);
                AttributeArray = temp;

                updateAttrs.Clear(); 
            }
 
 
            /// 
            /// Called externally to update the editor or type converter. 
            /// This simply sets flags so this will happen, it doesn't actually to the update...
            /// we wait and do that on-demand for perf.
            /// 
            internal void UpdateTypeConverterAndTypeEditor(bool force) { 
                // if this is an external request, flip the flag to false so we do the update on demand.
                // 
                if (GetFlag(FlagUpdatedEditorAndConverter) && force) { 
                    SetFlag(FlagUpdatedEditorAndConverter, false);
                } 
            }

            /// 
            /// Called externally to update the editor or type converter. 
            /// This simply sets flags so this will happen, it doesn't actually to the update...
            /// we wait and do that on-demand for perf. 
            ///  
            internal void UpdateTypeConverterAndTypeEditorInternal(bool force, int dispid) {
 
                // check to see if we're being forced here or if the work really
                // needs to be done.
                //
                if (GetFlag(FlagUpdatedEditorAndConverter) && !force)  { 
                    return;
                } 
 
                if (owner.GetOcx() == null) {
                    return; 
                }


                try { 
                    NativeMethods.IPerPropertyBrowsing ppb = owner.GetPerPropertyBrowsing();
 
                    if (ppb != null) { 
                        bool hasStrings = false;
 
                        // check for enums
                        NativeMethods.CA_STRUCT caStrings = new NativeMethods.CA_STRUCT();
                        NativeMethods.CA_STRUCT caCookies = new NativeMethods.CA_STRUCT();
 
                        int hr = NativeMethods.S_OK;
 
                        try { 
                            hr = ppb.GetPredefinedStrings(dispid, caStrings, caCookies);
                        } 
                        catch(ExternalException ex) {
                            hr = ex.ErrorCode;
                            Debug.Fail("An exception occurred inside IPerPropertyBrowsing::GetPredefinedStrings(dispid=" +
                                       dispid + "), object type=" + new ComNativeDescriptor().GetClassName(ppb)); 
                        }
 
 
                        if (hr != NativeMethods.S_OK) {
                            hasStrings = false; 
                            // Destroy the existing editor if we created the current one
                            // so if the items have disappeared, we don't hold onto the old
                            // items.
                            if (converter is Com2EnumConverter) { 
                                converter = null;
                            } 
                        } 
                        else {
                            hasStrings = true; 
                        }

                        if (hasStrings) {
                            OleStrCAMarshaler stringMarshaler = new OleStrCAMarshaler(caStrings); 
                            Int32CAMarshaler  intMarshaler = new Int32CAMarshaler(caCookies);
 
                            if (stringMarshaler.Count > 0 && intMarshaler.Count > 0) { 
                                if (converter == null) {
                                    converter = new AxEnumConverter(this, new AxPerPropertyBrowsingEnum(this, owner, stringMarshaler, intMarshaler, true)); 
                                }
                                else if (converter is AxEnumConverter){
                                    ((AxEnumConverter)converter).RefreshValues();
                                    AxPerPropertyBrowsingEnum axEnum = ((AxEnumConverter)converter).com2Enum as AxPerPropertyBrowsingEnum; 
                                    if (axEnum != null) {
                                        axEnum.RefreshArrays(stringMarshaler, intMarshaler); 
                                    } 

                                } 

                            }
                            else {
                                //hasStrings = false; 
                            }
                        } 
                        else { 
                            // if we didn't get any strings, try the proppage edtior
                            // 
                            // Check to see if this is a property that we have already massaged to be a
                            // .Net type. If it is, don't bother with custom property pages. We already
                            // have a .Net Editor for this type.
                            // 
                            ComAliasNameAttribute comAlias = (ComAliasNameAttribute)baseProp.Attributes[typeof(ComAliasNameAttribute)];
                            if (comAlias == null) { 
                                Guid g = GetPropertyPage(dispid); 

                                if (!Guid.Empty.Equals(g)) { 
                                   editor = new AxPropertyTypeEditor(this, g);

                                   // Show any non-browsable property that has an editor through a
                                   // property page. 
                                   //
                                   if (!this.IsBrowsable) { 
                                       Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Making property: " + this.Name + " browsable because we found an editor."); 
                                       AddAttribute(new BrowsableAttribute(true));
                                   } 
                                }
                            }
                        }
                    } 

                    SetFlag(FlagUpdatedEditorAndConverter, true); 
                 } 
                 catch (Exception e) {
                     Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "could not get the type editor for property: " + this.Name + " Exception: " + e); 
                 }
            }
        }
 
        private class AxPropertyTypeEditor : UITypeEditor {
            private AxPropertyDescriptor propDesc; 
            private Guid guid; 

            public AxPropertyTypeEditor(AxPropertyDescriptor pd, Guid guid) { 
                propDesc = pd;
                this.guid = guid;
            }
 
            /// 
            ///  
            ///     Takes the value returned from valueAccess.getValue() and modifies or replaces 
            ///     the value, passing the result into valueAccess.setValue().  This is where
            ///     an editor can launch a modal dialog or create a drop down editor to allow 
            ///     the user to modify the value.  Host assistance in presenting UI to the user
            ///     can be found through the valueAccess.getService function.
            /// 
            public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { 
                try {
                    object instance = context.Instance; 
                    propDesc.owner.ShowPropertyPageForDispid(propDesc.Dispid, this.guid); 
                }
                catch (Exception ex1) { 
                    if (provider != null) {
                          IUIService uiSvc = (IUIService)provider.GetService(typeof(IUIService));
                          if (uiSvc != null){
                            uiSvc.ShowError(ex1, SR.GetString(SR.ErrorTypeConverterFailed)); 
                          }
                    } 
                } 
                return value;
            } 

            /// 
            ///      Retrieves the editing style of the Edit method.  If the method
            ///      is not supported, this will return None. 
            /// 
            public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { 
                return UITypeEditorEditStyle.Modal; 
            }
        } 

        /// 
        /// simple derivation of the com2enumconverter that allows us to intercept
        /// the call to GetStandardValues so we can on-demand update the enum values. 
        /// 
        private class AxEnumConverter : Com2EnumConverter { 
            private AxPropertyDescriptor target; 

            public AxEnumConverter(AxPropertyDescriptor target, Com2Enum com2Enum) : base(com2Enum) { 
                this.target = target;
            }

            public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { 

                // make sure the converter has been properly refreshed -- calling 
                // the Converter property does this. 
                //
                TypeConverter tc = this; 
                tc = target.Converter;
                return base.GetStandardValues(context);

            } 

        } 
 
        // This exists for perf reasons.   We delay doing this until we
        // are actually asked for the array of values. 
        //
        private class AxPerPropertyBrowsingEnum : Com2Enum {
            private AxPropertyDescriptor target;
            private AxHost               owner; 
            private OleStrCAMarshaler    nameMarshaller;
            private Int32CAMarshaler     valueMarshaller; 
            private bool                 arraysFetched; 

            public AxPerPropertyBrowsingEnum(AxPropertyDescriptor targetObject, AxHost owner, OleStrCAMarshaler names, Int32CAMarshaler values, bool allowUnknowns) : base(new string[0], new object[0], allowUnknowns) { 
                this.target = targetObject;
                this.nameMarshaller = names;
                this.valueMarshaller = values;
                this.owner = owner; 
                this.arraysFetched = false;
            } 
 
            /// 
            ///  
            /// Retrieve a copy of the value array
            /// 
            public override object[] Values {
                get { 
                    EnsureArrays();
                    return base.Values; 
                } 
            }
 
            /// 
            /// Retrieve a copy of the nme array.
            /// 
            public override string[] Names { 
                get {
                    EnsureArrays(); 
                    return base.Names; 
                }
            } 

            // ensure that we have processed the caStructs into arrays
            // of values and strings
            // 
            private void EnsureArrays() {
                if (this.arraysFetched) { 
                    return; 
                }
 
                this.arraysFetched = true;

                try {
 
                    // marshal the items.
                    object[] nameItems = nameMarshaller.Items; 
                    object[] cookieItems=   valueMarshaller.Items; 
                    NativeMethods.IPerPropertyBrowsing ppb = (NativeMethods.IPerPropertyBrowsing)owner.GetPerPropertyBrowsing();
                    int itemCount = 0; 

                    Debug.Assert(cookieItems != null && nameItems != null, "An item array is null");

                    if (nameItems.Length > 0) { 
                        object[] valueItems = new object[cookieItems.Length];
                        NativeMethods.VARIANT var = new NativeMethods.VARIANT(); 
                        int cookie; 

                        Debug.Assert(cookieItems.Length == nameItems.Length, "Got uneven names and cookies"); 

                        // for each name item, we ask the object for it's corresponding value.
                        //
                        for (int i = 0; i < nameItems.Length; i++) { 
                            cookie = (int)cookieItems[i];
                            if (nameItems[i] == null || !(nameItems[i] is string)) { 
                                Debug.Fail("Bad IPerPropertyBrowsing item [" + i.ToString(CultureInfo.InvariantCulture) + "], name=" + (nameItems == null ? "(unknown)" : nameItems[i].ToString())); 
                                continue;
                            } 
                            var.vt = (short)NativeMethods.tagVT.VT_EMPTY;
                            int hr = ppb.GetPredefinedValue(target.Dispid, cookie, var);
                            if (hr == NativeMethods.S_OK && var.vt != (short)NativeMethods.tagVT.VT_EMPTY) {
                                valueItems[i] = var.ToObject(); 
                            }
                            var.Clear(); 
                            itemCount++; 
                        }
 
                        // pass this data down to the base Com2Enum object...
                        if (itemCount > 0) {
                            string[] strings = new string[itemCount];
                            Array.Copy(nameItems, 0, strings, 0, itemCount); 
                            base.PopulateArrays(strings, valueItems);
                        } 
                    } 
                }
                catch (Exception ex) { 
                    Debug.Fail("Failed to build IPerPropertyBrowsing editor. " + ex.GetType().Name + ", " + ex.Message);
                }
            }
 
            internal void RefreshArrays( OleStrCAMarshaler names, Int32CAMarshaler values) {
                this.nameMarshaller = names; 
                this.valueMarshaller = values; 
                this.arraysFetched = false;
            } 

#if false
            // FxCop: Currently not used
            private string GetDisplayString(int dispid, ref bool success) { 
                NativeMethods.IPerPropertyBrowsing ppb = (NativeMethods.IPerPropertyBrowsing)owner.GetPerPropertyBrowsing();
                string[] strVal = new string[1]; 
                int hr = ppb.GetDisplayString(dispid, strVal); 
                if (hr == NativeMethods.S_OK) {
                    success = (strVal[0] != null); 
                    //Debug.Assert(success, "IPerPropertyBrowsing::GetDisplayString returned NULL and S_OK -- this is not a valid state. This component does not property implement IPerPropertyBrowsing. (component class=" + TypeDescriptor.GetClassName(ppb) + ")");
                    return strVal[0];
                }
                else { 
                    success = false;
                } 
                return null; 
            }
#endif 

            protected override void PopulateArrays(string[] names, object[] values) {
                // we call base.PopulateArrays directly when we actually want to do this.
            } 

            public override object FromString(string s) { 
                EnsureArrays(); 
                return base.FromString(s);
            } 

            public override string ToString(object v) {
                EnsureArrays();
                return base.ToString(v); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK