Пример #1
0
        // This routine handles the following cases:
        // 1) a parent window is present, build the child window
        // 2) a parent is present, reparent the child window to it
        // 3) a parent window is not present, hide the child window by parenting it to SystemResources.Hwnd window.
        private void BuildOrReparentWindow()
        {
            DemandIfUntrusted();

            // Verify the thread has access to the context.
            // VerifyAccess();

            // Prevent reentry while building a child window,
            // also prevent the reconstruction of Disposed objects.
            if (_isBuildingWindow || _isDisposed)
            {
                return;
            }

            _isBuildingWindow = true;

            // Find the source window, this must be the parent window of
            // the child window.
            IntPtr             hwndParent = IntPtr.Zero;
            PresentationSource source     = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */);

            if (source != null)
            {
                HwndSource hwndSource = source as HwndSource;
                if (hwndSource != null)
                {
                    hwndParent = hwndSource.CriticalHandle;
                }
            }
            else
            {
                // attempt to also walk through 3D - if we get a non-null result then we know we are inside of
                // a 3D scene which is not supported
                PresentationSource goingThrough3DSource = PresentationSource.CriticalFromVisual(this, true /* enable2DTo3DTransition */);
                if (goingThrough3DSource != null)
                {
                    if (TraceHwndHost.IsEnabled)
                    {
                        TraceHwndHost.Trace(TraceEventType.Warning, TraceHwndHost.HwndHostIn3D);
                    }
                }
            }

            try
            {
                if (hwndParent != IntPtr.Zero)
                {
                    if (_hwnd.Handle == IntPtr.Zero)
                    {
                        // We now have a parent window, so we can create the child
                        // window.
                        BuildWindow(new HandleRef(null, hwndParent));
                        this.LayoutUpdated    += _handlerLayoutUpdated;
                        this.IsEnabledChanged += _handlerEnabledChanged;
                        this.IsVisibleChanged += _handlerVisibleChanged;
                    }
                    else if (hwndParent != UnsafeNativeMethods.GetParent(_hwnd))
                    {
                        // We have a different parent window.  Just reparent the
                        // child window under the new parent window.
                        UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null, hwndParent));
                    }
                }
                else
                {
                    // Reparent the window to notification-only window provided by SystemResources
                    // This keeps the child window around, but it is not visible.  We can reparent the
                    // window later when a new parent is available
                    var hwnd = SystemResources.GetDpiAwarenessCompatibleNotificationWindow(_hwnd);
                    UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null, hwnd.Handle));
                    // ...But we have a potential problem: If the SystemResources listener window gets
                    // destroyed ahead of the call to HwndHost.OnDispatcherShutdown(), the HwndHost's window
                    // will be destroyed too, before the "logical" Dispose has had a chance to do proper
                    // shutdown. This turns out to be very significant for WebBrowser/ActiveXHost, which shuts
                    // down the hosted control through the COM interfaces, and the control destroys its
                    // window internally. Evidently, the WebOC fails to do full, proper cleanup if its
                    // window is destroyed unexpectedly.
                    // To avoid this situation, we make sure SystemResources responds to the Dispatcher
                    // shutdown event after this HwndHost.
                    SystemResources.DelayHwndShutdown();
                }
            }
            finally
            {
                // Be careful to clear our guard bit.
                _isBuildingWindow = false;
            }
        }
Пример #2
0
        private void BuildOrReparentWindow()
        {
            this.DemandIfUntrusted();
            if (this._isBuildingWindow || this._isDisposed)
            {
                return;
            }
            this._isBuildingWindow = true;
            IntPtr             intPtr             = IntPtr.Zero;
            PresentationSource presentationSource = PresentationSource.CriticalFromVisual(this, false);

            if (presentationSource != null)
            {
                HwndSource hwndSource = presentationSource as HwndSource;
                if (hwndSource != null)
                {
                    intPtr = hwndSource.CriticalHandle;
                }
            }
            else
            {
                PresentationSource presentationSource2 = PresentationSource.CriticalFromVisual(this, true);
                if (presentationSource2 != null && TraceHwndHost.IsEnabled)
                {
                    TraceHwndHost.Trace(TraceEventType.Warning, TraceHwndHost.HwndHostIn3D);
                }
            }
            try
            {
                if (intPtr != IntPtr.Zero)
                {
                    if (this._hwnd.Handle == IntPtr.Zero)
                    {
                        this.BuildWindow(new HandleRef(null, intPtr));
                        base.LayoutUpdated    += this._handlerLayoutUpdated;
                        base.IsEnabledChanged += this._handlerEnabledChanged;
                        base.IsVisibleChanged += this._handlerVisibleChanged;
                    }
                    else if (intPtr != UnsafeNativeMethods.GetParent(this._hwnd))
                    {
                        UnsafeNativeMethods.SetParent(this._hwnd, new HandleRef(null, intPtr));
                    }
                }
                else
                {
                    IntPtr value = (!FrameworkAppContextSwitches.DisableDevDiv1035544) ? this.Handle : this._hwnd.Handle;
                    if (value != IntPtr.Zero)
                    {
                        HwndWrapper dpiAwarenessCompatibleNotificationWindow = SystemResources.GetDpiAwarenessCompatibleNotificationWindow(this._hwnd);
                        if (dpiAwarenessCompatibleNotificationWindow != null)
                        {
                            UnsafeNativeMethods.SetParent(this._hwnd, new HandleRef(null, dpiAwarenessCompatibleNotificationWindow.Handle));
                            SystemResources.DelayHwndShutdown();
                        }
                        else
                        {
                            Trace.WriteLineIf(dpiAwarenessCompatibleNotificationWindow == null, string.Format("- Warning - Notification Window is null\n{0}", new StackTrace(true).ToString()));
                        }
                    }
                }
            }
            finally
            {
                this._isBuildingWindow = false;
            }
        }