ActiveXHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Controls / ActiveXHost.cs / 1 / ActiveXHost.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
//
// Description: 
//      An ActiveXHost is a System.Windows.FrameworkElement which can 
//      host a windowed ActiveX control.  This class provides a technology
//      bridge between ActiveX controls and Avalon by wrapping ActiveX controls 
//      and exposing them as fully featured avalon elements. It implements both the
//      container interfaces (via aggregation) required to host the ActiveXControl
//      and also derives from HwndHost to support hosting an HWND in the avalon tree.
// 
//      Currently the activex hosting support is limited to windowed controls.
// 
//      Inheritors of this class simply need to concentrate on defining and implementing the 
//      properties/methods/events of the specific ActiveX control they are wrapping, the
//      default properties etc and the code to implement the activation etc. are 
//      encapsulated in the class below.
//
//      The classid of the ActiveX control is specified in the constructor.
// 
//
// History 
//  04/17/05    [....]      Created 
//
//----------------------------------------------------------------------------- 

using System;
using System.Collections;
using System.Collections.Specialized; 
using System.ComponentModel;
using System.Diagnostics; 
using System.Reflection; 
using System.Runtime.InteropServices;
using System.Security.Permissions; 
using System.Threading;

using System.Windows;
using System.Windows.Interop; 
using System.Windows.Controls;
using System.Windows.Input; 
using System.Windows.Markup; 
using MS.Internal;
using MS.Internal.Controls; 
using MS.Internal.Utility;
using MS.Win32;
using System.Security;
 
// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler.
// We first need to disable warnings about unknown message numbers and unknown pragmas. 
#pragma warning disable 1634, 1691 

namespace MS.Internal.Controls 
{
    #region ActiveXHost

    ///  
    ///     An ActiveXHost is a Systew.Windows.FrameworkElement which can
    ///     host an ActiveX control. Currently the support is limited to 
    ///     windowed controls. This class provides a technology bridge 
    ///     between unmanaged ActiveXControls and Avalon framework.
    ///  
    internal class ActiveXHost : HwndHost
    {
        //-----------------------------------------------------
        // 
        //  Constructors and Finalizers
        // 
        //----------------------------------------------------- 

        #region Constructors and Finalizers 

        static ActiveXHost()
        {
            // We use this map to lookup which invalidator method to call 
            // when the Avalon parent's properties change.
            invalidatorMap[UIElement.VisibilityProperty] = new PropertyInvalidator(OnVisibilityInvalidated); 
            invalidatorMap[FrameworkElement.IsEnabledProperty] = new PropertyInvalidator(OnIsEnabledInvalidated); 

            // register for access keys 
            EventManager.RegisterClassHandler(typeof(ActiveXHost), AccessKeyManager.AccessKeyPressedEvent, new AccessKeyPressedEventHandler(OnAccessKeyPressed));

            Control.IsTabStopProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true));
 
            FocusableProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true));
 
            EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.GotKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnGotFocus)); 
            EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.LostKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnLostFocus));
            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once)); 
        }


        /// constructor for ActiveXHost 
        ///
        ///     Critical - calls trusted HwndHost ctor. 
        ///                Takes the clsid to instantiate as input. 
        ///     NOT TAS. Individual controls ( like WebOC) can become TAS if they justify why.
        /// 
        [SecurityCritical]
        internal ActiveXHost(string clsidString, bool fTrusted ) : base( fTrusted )
        {
            // Thread.ApartmentState is [Obsolete] 
            #pragma warning disable 0618
 
            // 
            if (Thread.CurrentThread.ApartmentState != ApartmentState.STA)
            { 
                throw new ThreadStateException(SR.Get(SRID.AxRequiresApartmentThread, clsidString));
            }

            #pragma warning restore 0618 

            _clsid = new SecurityCriticalDataForSet ( new Guid(clsidString)); 
 
            // hookup so we are notified when loading is finished.
            Initialized += new EventHandler(OnInitialized); 
        }


        #endregion Constructors and Finalizers 

        //------------------------------------------------------ 
        // 
        //  Protected Methods
        // 
        //-----------------------------------------------------

        #region Protected Methods
 
        #region Framework Related
 
        ///  
        ///     Overriden to push the values of invalidated properties down to our
        ///     ActiveX control. 
        /// 
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e); 

            if (e.IsAValueChange || e.IsASubPropertyChange) 
            { 
                DependencyProperty dp = e.Property;
 
                // We lookup the property in our invalidatorMap
                // and call the appropriate method to push
                // down the changed value to the hosted ActiveX control.
                if (dp != null && invalidatorMap.ContainsKey(dp)) 
                {
                    PropertyInvalidator invalidator = (PropertyInvalidator)invalidatorMap[dp]; 
                    invalidator(this); 
                }
            } 
        }

        /// 
        ///     Overriden to create our window and parent it. 
        /// 
        /// 
        ///     Critical - calls methods on critical interface members 
        ///
        [SecurityCritical ] 
        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            this.ParentHandle = hwndParent;
 
            //BuildWindowCore should only be called if visible. Bug 1236445 tracks this.
            TransitionUpTo(ActiveXHelper.ActiveXState.InPlaceActive); 
 
            //The above call should have set this interface
            Invariant.Assert(_axOleInPlaceActiveObject != null, "InPlace activation of ActiveX control failed"); 

            if (ControlHandle.Handle == IntPtr.Zero)
            {
                IntPtr inplaceWindow = IntPtr.Zero; 
                _axOleInPlaceActiveObject.GetWindow(out inplaceWindow);
                AttachWindow(inplaceWindow); 
            } 

            return _axWindow; 
        }

        /// 
        ///     Overridden to plug the ActiveX control into Avalon's layout manager. 
        /// 
        ///  
        ///     Critical - accesses ActiveXSite critical property 
        ///     Not making TAS - you may be able to spoof content of web-pages if you could position any arbitrary
        ///                      control over a WebOC. 
        /// 
        [ SecurityCritical ]
        protected override void OnWindowPositionChanged(Rect bounds)
        { 
            //Its okay to process this if we the control is not yet created
 
            _boundRect = bounds; 

            //These are already transformed to client co-ordinate/device units for high dpi also 
            _bounds.left    = (int) bounds.X;
            _bounds.top     = (int) bounds.Y;
            _bounds.right   = (int) (bounds.Width + bounds.X);
            _bounds.bottom  = (int) (bounds.Height + bounds.Y); 

            //SetExtent only sets height and width, can call it for perf if X, Y haven't changed 
            //We need to call SetObjectRects instead, which updates X, Y, width and height 
            //OnActiveXRectChange calls SetObjectRects
            this.ActiveXSite.OnActiveXRectChange(_bounds); 
        }

        /// 
        ///     Derived classes override this method to actually build the 
        ///     window being hosted.
        ///  
        protected override void DestroyWindowCore(HandleRef hwnd) 
        {
        } 

        /// 
        ///     Overridden to plug the ActiveX control into Avalon's layout manager.
        ///  
        protected override Size MeasureOverride(Size swConstraint)
        { 
            base.MeasureOverride(swConstraint); 

            double newWidth, newHeight; 

            if (Double.IsPositiveInfinity(swConstraint.Width))
                newWidth = 150;
            else 
                newWidth = swConstraint.Width;
 
            if (Double.IsPositiveInfinity(swConstraint.Height)) 
                newHeight = 150;
            else 
                newHeight = swConstraint.Height;

            return new Size(newWidth, newHeight);
        } 

 
        ///  
        ///     Forward the access key to our hosted ActiveX control
        /// 
        protected override void OnAccessKey(AccessKeyEventArgs args)
        {
            Debug.Assert(args.Key.Length > 0, "got an empty access key");
            // 

        } 
 
        #endregion Framework Related
 
        #region ActiveX Related

        protected override void Dispose(bool disposing)
        { 
            try
            { 
                if ((disposing) && (!_isDisposed)) 
                {
                    TransitionDownTo(ActiveXHelper.ActiveXState.Passive); 
                    _isDisposed = true;
                }
            }
            finally 
            {
                //This destroys the parent window, so call base after we have done our processing. 
                base.Dispose(disposing); 
            }
        } 

        // The native ActiveX control QI's for interfaces on it's site to see if
        // it needs to change it's behaviour. Since the AxSite class is generic,
        // it only implements site interfaces that are generic to all sites. QI's 
        // for any more specific interfaces will fail. This is a problem if anyone
        // wants to support any other interfaces on the site. In order to overcome 
        // this, one needs to extend AxSite and implement any additional interfaces 
        // needed.
        // 
        // ActiveX wrapper controls that derive from this class should override the
        // below method and return their own AxSite derived object.
        //
        // This method is protected by an InheritanceDemand (from HwndSource) and 
        // a LinkDemand because extending a site is strictly an advanced feature for
        // which one needs UnmanagedCode permissions. 
        // 

        /// Returns an object that will be set as the site for the native ActiveX control. 
        /// Implementors of the site can derive from ActiveXSite class.
        ///
        /// Critical - calls critical ctor.
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        [SecurityCritical] 
        protected virtual ActiveXSite CreateActiveXSite() 
        {
            return new ActiveXSite(this); 
        }

        /// This will be called when the native ActiveX control has just been created.
        /// Inheritors of this class can override this method to cast the nativeActiveXObject 
        /// parameter to the appropriate interface. They can then cache this interface
        /// value in a member variable. However, they must release this value when 
        /// DetachInterfaces is called (by setting the cached interface variable to null). 
        protected virtual void AttachInterfaces(object nativeActiveXObject)
        { 
        }

        /// See AttachInterfaces for a description of when to override DetachInterfaces.
        protected virtual void DetachInterfaces() 
        {
        } 
 
        /// This will be called when we are ready to start listening to events.
        /// Inheritors can override this method to hook their own connection points. 
        protected virtual void CreateSink()
        {
        }
 
        /// This will be called when it is time to stop listening to events.
        /// This is where inheritors have to disconnect their connection points. 
        protected virtual void DetachSink() 
        {
        } 

        /// 
        /// Called whenever the ActiveX state changes. Subclasses can do additional hookup/cleanup depending
        /// on the state transitions 
        /// 
        ///  
        ///  
        protected virtual void OnActiveXStateChange(int oldState, int newState)
        { 
        }

        #endregion ActiveX Related
 
        #endregion Protected Methods
 
        //------------------------------------------------------ 
        //
        //  Protected Properties 
        //
        //------------------------------------------------------

        #region Protected Properties 

        protected bool IsDisposed 
        { 
            get { return _isDisposed; }
        } 

        #endregion Protected Properties

        //----------------------------------------------------- 
        //
        //  Internal Methods 
        // 
        //------------------------------------------------------
 
        #region Internal Methods

        #region ActiveX Related
 
        /// This method needs to be called by the user of ActiveXHost for each
        /// hosted ActiveX control that has a mnemonic bound to it 
        internal void RegisterAccessKey(char key) 
        {
            AccessKeyManager.Register(key.ToString(), this); 
        }

        ///
        /// Critical - exposes critical _axSite member. 
        ///
        internal ActiveXSite ActiveXSite 
        { 
            [SecurityCritical]
            get 
            {
                if (_axSite == null)
                {
                    _axSite = CreateActiveXSite(); 
                }
                return _axSite; 
            } 
        }
 
        ///
        /// Critical - exposes critical _axContainer member.
        ///
        internal ActiveXContainer Container 
        {
            [SecurityCritical] 
            get 
            {
                if (_axContainer == null) 
                {
                    _axContainer = new ActiveXContainer(this);
                }
                return _axContainer; 
            }
        } 
 
        internal ActiveXHelper.ActiveXState ActiveXState
        { 
            get
            {
                return _axState;
            } 
            set
            { 
                _axState = value; 
            }
        } 

        internal bool GetAxHostState(int mask)
        {
            return _axHostState[mask]; 
        }
 
        internal void SetAxHostState(int mask, bool value) 
        {
            _axHostState[mask] = value; 
        }

        internal void TransitionUpTo(ActiveXHelper.ActiveXState state)
        { 
            if (!this.GetAxHostState(ActiveXHelper.inTransition))
            { 
                this.SetAxHostState(ActiveXHelper.inTransition, true); 

                try 
                {
                    ActiveXHelper.ActiveXState oldState;

                    while (state > this.ActiveXState) 
                    {
                        oldState = this.ActiveXState; 
 
                        switch (this.ActiveXState)
                        { 
                            case ActiveXHelper.ActiveXState.Passive:
                                TransitionFromPassiveToLoaded();
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition");
                                this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; 
                                break;
                            case ActiveXHelper.ActiveXState.Loaded: 
                                TransitionFromLoadedToRunning(); 
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition");
                                this.ActiveXState = ActiveXHelper.ActiveXState.Running; 
                                break;
                            case ActiveXHelper.ActiveXState.Running:
                                TransitionFromRunningToInPlaceActive();
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition"); 
                                this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive;
                                break; 
                            case ActiveXHelper.ActiveXState.InPlaceActive: 
                                TransitionFromInPlaceActiveToUIActive();
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Failed transition"); 
                                this.ActiveXState = ActiveXHelper.ActiveXState.UIActive;
                                break;
                            default:
                                Debug.Fail("bad state"); 
                                this.ActiveXState = this.ActiveXState + 1;  // To exit the loop
                                break; 
                        } 

                        OnActiveXStateChange((int)oldState, (int)this.ActiveXState); 
                    }
                }
                finally
                { 
                    this.SetAxHostState(ActiveXHelper.inTransition, false);
                } 
            } 
        }
 
        internal void TransitionDownTo(ActiveXHelper.ActiveXState state)
        {
            if (!this.GetAxHostState(ActiveXHelper.inTransition))
            { 
                this.SetAxHostState(ActiveXHelper.inTransition, true);
 
                try 
                {
                    ActiveXHelper.ActiveXState oldState; 

                    while (state < this.ActiveXState)
                    {
                        oldState = this.ActiveXState; 

                        switch (this.ActiveXState) 
                        { 
                            case ActiveXHelper.ActiveXState.Open:
                                Debug.Fail("how did we ever get into the open state?"); 
                                this.ActiveXState = ActiveXHelper.ActiveXState.UIActive;
                                break;
                            case ActiveXHelper.ActiveXState.UIActive:
                                TransitionFromUIActiveToInPlaceActive(); 
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition");
                                this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; 
                                break; 
                            case ActiveXHelper.ActiveXState.InPlaceActive:
                                TransitionFromInPlaceActiveToRunning(); 
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition");
                                this.ActiveXState = ActiveXHelper.ActiveXState.Running;
                                break;
                            case ActiveXHelper.ActiveXState.Running: 
                                TransitionFromRunningToLoaded();
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition"); 
                                this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; 
                                break;
                            case ActiveXHelper.ActiveXState.Loaded: 
                                TransitionFromLoadedToPassive();
                                Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Failed transition");
                                this.ActiveXState = ActiveXHelper.ActiveXState.Passive;
                                break; 
                            default:
                                Debug.Fail("bad state"); 
                                this.ActiveXState = this.ActiveXState - 1;  // To exit the loop 
                                break;
                        } 

                        OnActiveXStateChange((int)oldState, (int)this.ActiveXState);
                    }
                } 
                finally
                { 
                    this.SetAxHostState(ActiveXHelper.inTransition, false); 
                }
            } 
        }

        ///
        ///     Critical - runs arbitrary code on critical _axOleObject member. 
        ///
        [SecurityCritical] 
        internal bool DoVerb(int verb) 
        {
            int hr = _axOleObject.DoVerb(verb, 
                                         IntPtr.Zero,
                                         this.ActiveXSite,
                                         0,
                                         this.ParentHandle.Handle, 
                                         _bounds);
 
            Debug.Assert(hr == NativeMethods.S_OK, String.Format("DoVerb call failed for verb 0x{0:X}", verb)); 
            return hr == NativeMethods.S_OK;
        } 

        ///
        ///     Critical - Calls setParent, accesses _axWindow.
        /// 
        [SecurityCritical]
        internal void AttachWindow(IntPtr hwnd) 
        { 
            if (_axWindow.Handle == hwnd)
                return; 

            //

 

            _axWindow = new HandleRef(this, hwnd); 
 
            if (this.ParentHandle.Handle != IntPtr.Zero)
            { 
                UnsafeNativeMethods.SetParent(_axWindow, this.ParentHandle);
            }
        }
 
        ///
        ///     Critical - calls ActiveXSite.StartEvents - critical code. 
        /// 
        [ SecurityCritical ]
        private void StartEvents() 
        {
            if (!this.GetAxHostState(ActiveXHelper.sinkAttached))
            {
                this.SetAxHostState(ActiveXHelper.sinkAttached, true); 
                CreateSink();
            } 
            this.ActiveXSite.StartEvents(); 
        }
 
        ///
        ///     Critical - calls ActiveXSite.StopEvents - critical code.
        ///     NOT TAS: if you can stop listening to events - you could
        ///              potentially turn off a mitigation. On the WebOC this could 
        ///              stop site-locking mitigation.
        /// 
        [ SecurityCritical ] 
        private void StopEvents()
        { 
            if (this.GetAxHostState(ActiveXHelper.sinkAttached))
            {
                this.SetAxHostState(ActiveXHelper.sinkAttached, false);
                DetachSink(); 
            }
            this.ActiveXSite.StopEvents(); 
        } 

        /// 
        /// Critical - Calls critical code ( CoCreateInstance) calls critical interface members, _axInstance
        /// TreatAsSafe - although this method instantiates the control.
        ///               considered safe as the parameter that controls what to instantiate is critical for set.
        ///               and set only via the critical CTOR. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromPassiveToLoaded() 
        {
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Wrong start state to transition from"); 
            if (this.ActiveXState == ActiveXHelper.ActiveXState.Passive)
            {
                //
                // First, create the ActiveX control 
                Debug.Assert(_axInstance == null, "_axInstance must be null");
 
                // We copy the guid here - as it's passed by ref to NativeCode. 
                // Given that it's critical for set - this could potentially allow the CoCreate
                // to change the object instantiated. 
                Guid clsid = _clsid.Value;
                _axInstance = UnsafeNativeMethods.CoCreateInstance(ref clsid , null, NativeMethods.CLSCTX_INPROC_SERVER, ref NativeMethods.IID_IUnknown);
                Debug.Assert(_axInstance != null, "w/o an exception being thrown we must have an object...");
 
                //
                // We are now Loaded! 
                this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; 

                // 
                // Lets give them a chance to cast the ActiveX object
                // to the appropriate interfaces.
                this.AttachInterfacesInternal();
            } 
        }
 
        /// 
        /// Critical - accesses critical interface members, _axInstance
        /// TreatAsSafe - state transitions considered safe. 
        ///                     Instantiating a control is considered critical.
        ///                     However once instantiated, state transitions considered ok.
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromLoadedToPassive()
        { 
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from"); 
            if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded)
            { 
                //
                // Need to make sure that we don't handle any PropertyChanged
                // notifications at this point.
                //this.NoComponentChangeEvents++; 
                try
                { 
                    // 
                    // Release the _axInstance
                    if (_axInstance != null) 
                    {
                        //
                        // Lets first get the cached interface pointers of _axInstance released.
                        this.DetachInterfacesInternal(); 

                        Marshal.FinalReleaseComObject(_axInstance); 
                        _axInstance = null; 
                    }
                } 
                finally
                {
                    //
                } 

                // 
                // We are now Passive! 
                this.ActiveXState = ActiveXHelper.ActiveXState.Passive;
            } 
        }

        ///
        /// Critical - calls critical code - SetClientSite. 
        /// TreatAsSafe - state transitions considered safe.
        ///                     Instantiating a control is considered critical. 
        ///                     However once instantiated, state transitions considered ok. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromLoadedToRunning()
        {
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from");
            if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded) 
            {
                // 
                // See if the ActiveX control returns OLEMISC_SETCLIENTSITEFIRST 
                int bits = 0;
                int hr = _axOleObject.GetMiscStatus(NativeMethods.DVASPECT_CONTENT, out bits); 
                if (NativeMethods.Succeeded(hr) && ((bits & NativeMethods.OLEMISC_SETCLIENTSITEFIRST) != 0))
                {
                    //
                    // Simply setting the site to the ActiveX control should activate it. 
                    // And this will take us to the Running state.
                    _axOleObject.SetClientSite(this.ActiveXSite); 
                } 

                StartEvents(); 

                //
                // We are now Running!
                this.ActiveXState = ActiveXHelper.ActiveXState.Running; 
            }
        } 
 
        ///
        /// Critical - accesses critical code, _axOleOlebject, StopEvents 
        /// TreatAsSafe - state transitions considered safe.
        ///                     Instantiating a control is considered critical.
        ///                     However once instantiated, state transitions considered ok.
        /// 
        [SecurityCritical, SecurityTreatAsSafe ]
        private void TransitionFromRunningToLoaded() 
        { 
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from");
            if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) 
            {
                StopEvents();

                // 
                // Inform the ActiveX control that it's been un-sited.
                _axOleObject.SetClientSite(null); 
 
                //
                // We are now Loaded! 
                this.ActiveXState = ActiveXHelper.ActiveXState.Loaded;
            }
        }
 
        ///
        /// Critical - calls critical code - DoVerb. 
        /// TreatAsSafe - state transitions considered safe. 
        ///                     Instantiating a control is considered critical.
        ///                     However once instantiated, state transitions considered ok. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ]
        private void TransitionFromRunningToInPlaceActive()
        { 
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from");
            if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) 
            { 
                try
                { 
                    DoVerb(NativeMethods.OLEIVERB_INPLACEACTIVATE);
                }
                catch (Exception e)
                { 
                    if(CriticalExceptions.IsCriticalException(e))
                    { 
                        throw; 
                    }
                    else 
                    {
                        throw new TargetInvocationException(SR.Get(SRID.AXNohWnd, GetType().Name), e);
                    }
                } 

                // 
                // We are now InPlaceActive! 
                this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive;
            } 
        }

        ///
        /// Critical - calls critical code - InPlaceDeactivate. 
        /// TreatAsSafe - state transitions considered safe.
        ///                     Instantiating a control is considered critical. 
        ///                     However once instantiated, state transitions considered ok. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromInPlaceActiveToRunning()
        {
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from");
            if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive) 
            {
                // 
                // InPlaceDeactivate. 
                _axOleInPlaceObject.InPlaceDeactivate();
 
                //
                // We are now Running!
                this.ActiveXState = ActiveXHelper.ActiveXState.Running;
            } 
        }
 
        /// 
        /// Critical - calls critical code - DoVerb.
        /// TreatAsSafe - state transitions considered safe. 
        ///                     Instantiating a control is considered critical.
        ///                     However once instantiated, state transitions considered ok.
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromInPlaceActiveToUIActive()
        { 
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from"); 
            if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive)
            { 
                DoVerb(NativeMethods.OLEIVERB_UIACTIVATE);

                //
                // We are now UIActive! 
                this.ActiveXState = ActiveXHelper.ActiveXState.UIActive;
            } 
        } 

        /// 
        /// Critical - accesses critical interface members, _axOleInPlaceObject
        /// TreatAsSafe - state transitions considered safe.
        ///                     Instantiating a control is considered critical.
        ///                     However once instantiated, state transitions considered ok. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        private void TransitionFromUIActiveToInPlaceActive() 
        {
            Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Wrong start state to transition from"); 
            if (this.ActiveXState == ActiveXHelper.ActiveXState.UIActive)
            {
                int hr = _axOleInPlaceObject.UIDeactivate();
                Debug.Assert(NativeMethods.Succeeded(hr), "Failed in IOleInPlaceObject.UiDeactivate"); 

                // 
                // We are now InPlaceActive! 
                this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive;
            } 
        }

        #endregion ActiveX Related
 
        #endregion Internal Methods
 
        //----------------------------------------------------- 
        //
        //  Internal Properties 
        //
        //-----------------------------------------------------

        #region Internal Properties 

        #region Framework Related 
 
        /// 
        ///     The DependencyProperty for the TabIndex property. 
        ///     Flags:              Can be used in style rules
        ///     Default Value:      1
        /// 
        internal static readonly DependencyProperty TabIndexProperty 
            = Control.TabIndexProperty.AddOwner(typeof(ActiveXHost));
 
        ///  
        ///     TabIndex property change the order of Tab navigation between Controls.
        ///     Control with lower TabIndex will get focus before the Control with higher index 
        /// 
        internal int TabIndex
        {
            get { return (int) GetValue(TabIndexProperty); } 
            set { SetValue(TabIndexProperty, value); }
        } 
 
        ///
        ///     Critical - accesses _hwndParent critical member. 
        ///
        internal HandleRef ParentHandle
        {
            [ SecurityCritical ] 
            get { return _hwndParent; }
 
            [ SecurityCritical ] 
            set { _hwndParent = value; }
        } 

        // This returns a COMRECT.
        internal NativeMethods.COMRECT Bounds
        { 
            get { return _bounds; }
            //How do we notify Avalon tree/layout that the control needs a new size? 
            set { _bounds = value; } 
        }
 
        // This returns a Rect.
        internal Rect BoundRect
        {
            get { return _boundRect; } 
        }
 
        #endregion Framework Related 

        #region ActiveX Related 

        /// 
        /// Returns the hosted ActiveX control's handle
        ///  
        ///
        ///     Critical - returns critical _axWindow member 
        /// 
        internal HandleRef ControlHandle
        { 
            [ SecurityCritical ]
            get { return _axWindow; }
        }
 
        ///
        ///Returns the native webbrowser object that this control wraps. Needs FullTrust to access. 
        /// Internally we will access the private field directly for perf reasons, no security checks 
        ///
        /// 
        ///     Critical - returns critical Instance member.
        ///
        internal object ActiveXInstance
        { 
            [ SecurityCritical ]
            get 
            { 
                return _axInstance;
            } 
        }


        /// 
        ///     Critical - returns critical Instance member.
        /// 
        internal UnsafeNativeMethods.IOleInPlaceObject ActiveXInPlaceObject 
        {
            [ SecurityCritical ] 
            get
            {
                return _axOleInPlaceObject;
            } 
        }
 
        /// 
        ///     Critical - returns critical Instance member.
        /// 
        internal UnsafeNativeMethods.IOleInPlaceActiveObject ActiveXInPlaceActiveObject
        {
            [SecurityCritical]
            get 
            {
                return _axOleInPlaceActiveObject; 
            } 
        }
 
        #endregion ActiveXRelated

        #endregion Internal Properties
 
        //-----------------------------------------------------
        // 
        //  Private Methods 
        //
        //------------------------------------------------------ 

        #region Private Methods

        #region Framework Methods 

        private void OnInitialized(object sender, EventArgs e) 
        { 
            //
 



 

 
            this.Initialized -= new EventHandler(this.OnInitialized); 

            //Cannot inplace activate yet, since BuildWindowCore is not called yet 
            //and we need that for getting the parent handle to pass on to the control.
        }

        private static void OnIsEnabledInvalidated(ActiveXHost axHost) 
        {
            // 
 

 

        }

        private static void OnVisibilityInvalidated(ActiveXHost axHost) 
        {
            if (axHost != null) 
            { 
                switch (axHost.Visibility)
                { 
                    case Visibility.Visible:
                        //
                        break;
                    case Visibility.Collapsed: 
                        //
                        break; 
                    case Visibility.Hidden: 
                        //
 


                        break;
                } 
            }
        } 
 
        ///     This event handler forwards focus events to the hosted ActiveX control
        private static void OnGotFocus(object sender, KeyboardFocusChangedEventArgs e) 
        {
            ActiveXHost axhost = sender as ActiveXHost;

            if (axhost != null) 
            {
                Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.InPlaceActive, "Should at least be InPlaceActive when getting focus"); 
 
                if (axhost.ActiveXState < ActiveXHelper.ActiveXState.UIActive)
                { 
                    axhost.TransitionUpTo(ActiveXHelper.ActiveXState.UIActive);
                }
            }
        } 

        ///     This event handler forwards focus events to the hosted WF controls 
        private static void OnLostFocus(object sender, KeyboardFocusChangedEventArgs e) 
        {
            ActiveXHost axhost = sender as ActiveXHost; 

            if (axhost != null)
            {
                // If the focus goes from our control window to one of the child windows, 
                // we should not deactivate.
                // 
 
                Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.UIActive, "Should at least be UIActive when losing focus");
 
                bool uiDeactivate = !axhost.IsKeyboardFocusWithin;

                if (uiDeactivate)
                { 
                    axhost.TransitionDownTo(ActiveXHelper.ActiveXState.InPlaceActive);
                } 
            } 
        }
 
        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs args)
        {
            if (!args.Handled && args.Scope == null && args.Target == null)
            { 
                args.Target = (UIElement)sender;
            } 
        } 

        /* 
                private void GetMnemonicList(SWF.Control control, ArrayList mnemonicList) {

                    // Get the mnemonic for our control
                    // 
                    char mnemonic = HostUtils.GetMnemonic(control.Text, true);
                    if (mnemonic != 0) 
                    { 
                        mnemonicList.Add(mnemonic);
                    } 

                    // And recurse for our children, currently we only support one activex control
                    //
                    if (HostedControl != null) GetMnemonicList(HostedControl, mnemonicList); 
                }
        */ 
 
        #endregion Framework Methods
 
        #region ActiveX Related

        ///
        ///     Critical -  accesses critical interface pointers. 
        ///
        [ SecurityCritical ] 
        private void AttachInterfacesInternal() 
        {
            Debug.Assert(_axInstance != null, "The native control is null"); 
            _axOleObject = (UnsafeNativeMethods.IOleObject)_axInstance;
            _axOleInPlaceObject = (UnsafeNativeMethods.IOleInPlaceObject)_axInstance;
            _axOleInPlaceActiveObject = (UnsafeNativeMethods.IOleInPlaceActiveObject)_axInstance;
            _axOleControl = (UnsafeNativeMethods.IOleControl)_axInstance; 
            //
            // Lets give the inheriting classes a chance to cast 
            // the ActiveX object to the appropriate interfaces. 
            AttachInterfaces(_axInstance);
        } 

        ///
        ///     Critical - accesses critical interface members.
        ///     TreatAsSafe - clearing the interfaces is ok. 
        ///
        [ SecurityCritical, SecurityTreatAsSafe ] 
        private void DetachInterfacesInternal() 
        {
            _axOleObject = null; 
            _axOleInPlaceObject = null;
            _axOleInPlaceActiveObject = null;
            _axOleControl = null;
            // 
            // Lets give the inheriting classes a chance to release
            // their cached interfaces of the ActiveX object. 
            DetachInterfaces(); 
        }
 
        ///
        ///     Critical - calls calls critical interface members.
        ///
        [ SecurityCritical ] 
        private NativeMethods.SIZE SetExtent(int width, int height)
        { 
            NativeMethods.SIZE sz = new NativeMethods.SIZE(); 
            sz.cx = width;
            sz.cy = height; 

            bool resetExtents = false;
            try
            { 
                _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz);
            } 
            catch (COMException) 
            {
                resetExtents = true; 
            }
            if (resetExtents)
            {
                _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); 
                try
                { 
                    _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz); 
                }
                catch (COMException e) 
                {
                    Debug.Fail(e.ToString());
                }
            } 
            return GetExtent();
        } 
 
        ///
        ///     Critical - accesses critical interface member _axOleObject 
        ///     TreatAsSafe - getting the size of the control is considered ok.
        ///
        [ SecurityCritical, SecurityTreatAsSafe ]
        private NativeMethods.SIZE GetExtent() 
        {
            NativeMethods.SIZE sz = new NativeMethods.SIZE(); 
            _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); 
            return sz;
        } 


        //Tunnel down default font changes and such?
        /// 
        ///     Critical - accesses _axInstance, runs arbitrary code.
        /// 
        [ SecurityCritical ] 
        private void AmbientChanged(int dispid)
        { 
            if (_axInstance != null)
            {
                try
                { 
                    //
                    _axOleControl.OnAmbientPropertyChange(dispid); 
                } 
#pragma warning disable 6500
 
// The 6500 warning is actually handled in below code, but the PreSharp explicitly checks the presence of NullReferenceException and SEHException, and still treat below code as violation of presharp rule, so suppress it here.
                catch (Exception ex)
                {
                    if (CriticalExceptions.IsCriticalException(ex)) 
                    {
                        throw; 
                    } 
                    Debug.Fail(ex.ToString());
                } 
#pragma warning restore 6500
            }
        }
 
        #endregion ActiveX Related
 
        #endregion Private Methods 

 
        //-----------------------------------------------------
        //
        //  Private Properties
        // 
        //------------------------------------------------------
 
        #region Private Properties 

        #endregion Private Properties 

        //------------------------------------------------------
        //
        //  Private Fields 
        //
        //----------------------------------------------------- 
 
        #region Private Fields
 
        #region Framework Related

        private static Hashtable invalidatorMap = new Hashtable();
 
        private delegate void PropertyInvalidator(ActiveXHost axhost);
 
        private NativeMethods.COMRECT _bounds    = new NativeMethods.COMRECT(0, 0, 0, 0); 
        private Rect             _boundRect      = new Rect(0, 0, 0, 0);
 
        private Size             _cachedSize     = Size.Empty;
        ///
        ///     Critical - _hwndParent considered critical.
        /// 
        [SecurityCritical ]
        private HandleRef        _hwndParent; 
        private bool             _isDisposed; 

        #endregion Framework Related 

        #region ActiveX Related

        /// 
        ///     Critical - _clsId controls what code to run and instantiate.
        /// 
        private SecurityCriticalDataForSet    _clsid; 

        /// 
        ///     Critical - hwnd of control
        ///
        [ SecurityCritical ]
        private HandleRef                   _axWindow; 
        private BitVector32                 _axHostState    = new BitVector32();
        private ActiveXHelper.ActiveXState  _axState        = ActiveXHelper.ActiveXState.Passive; 
 
        ///
        ///     Critical - ActiveXSite interfaces of control 
        ///
        [ SecurityCritical ]
        private ActiveXSite                 _axSite;
 
        ///
        ///     Critical - ActiveXContainer of control 
        /// 
        [ SecurityCritical ]
        private ActiveXContainer            _axContainer; 

        ///
        ///     Critical - all methods on this Interface are critical
        /// 
        [SecurityCritical]
        private object                      _axInstance; 
 
        // Pointers to the ActiveX object: Interface pointers are cached for perf.
        /// 
        ///     Critical - all methods on this Interface are critical
        ///
        [SecurityCritical]
        private UnsafeNativeMethods.IOleObject              _axOleObject; 

        /// 
        ///     Critical - all methods on this Interface are critical 
        ///
        [SecurityCritical] 
        private UnsafeNativeMethods.IOleInPlaceObject       _axOleInPlaceObject;

        ///
        ///     Critical - all methods on this Interface are critical 
        ///
        [SecurityCritical] 
        private UnsafeNativeMethods.IOleInPlaceActiveObject _axOleInPlaceActiveObject; 

        /// 
        ///     Critical - all methods on this Interface are critical
        ///
        [SecurityCritical]
        private UnsafeNativeMethods.IOleControl             _axOleControl; 

        #endregion ActiveX Related 
 

        #endregion Private Fields 
    }
    #endregion ActiveXHost
}

// 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