コード例 #1
0
 public bool DetachHwndTarget(HwndTarget hwndTarget)
 {
     Debug.Assert(hwndTarget != null);
     MonitorPowerEvent -= hwndTarget.OnMonitorPowerEvent;
     _hwndTargetCount--;
     Debug.Assert(_hwndTargetCount >= 0);
     return (_hwndTargetCount == 0);
 }
コード例 #2
0
        private void Initialize(HwndSourceParameters parameters)
        {
            _mouse = new SecurityCriticalDataClass<HwndMouseInputProvider>(new HwndMouseInputProvider(this));
            _keyboard = new SecurityCriticalDataClass<HwndKeyboardInputProvider>(new HwndKeyboardInputProvider(this));
            _layoutHook = new HwndWrapperHook(LayoutFilterMessage);
            _inputHook = new HwndWrapperHook(InputFilterMessage);
            _hwndTargetHook = new HwndWrapperHook(HwndTargetFilterMessage);

            _publicHook = new HwndWrapperHook(PublicHooksFilterMessage);

            // When processing WM_SIZE, LayoutFilterMessage must be invoked before
            // HwndTargetFilterMessage. This way layout will be updated before resizing
            // HwndTarget, resulting in single render per resize. This means that
            // layout hook should appear before HwndTarget hook in the wrapper hooks
            // list. If this is done the other way around, first HwndTarget resize will
            // force re-render, then layout will be updated according to the new size,
            // scheduling another render.
            HwndWrapperHook[] wrapperHooks = { _hwndTargetHook, _layoutHook, _inputHook, null };

            if (null != parameters.HwndSourceHook)
            {
                // In case there's more than one delegate, add these to the event storage backwards
                // so they'll get invoked in the expected order.
                Delegate[] handlers = parameters.HwndSourceHook.GetInvocationList();
                for (int i = handlers.Length -1; i >= 0; --i)
                {
                    _hooks += (HwndSourceHook)handlers[i];
                }
                wrapperHooks[3] = _publicHook;
            }

            _restoreFocusMode = parameters.RestoreFocusMode;
            _acquireHwndFocusInMenuMode = parameters.AcquireHwndFocusInMenuMode;

            // A window must be marked WS_EX_LAYERED if (and only if):
            // 1) it is not a child window
            //    -- AND --
            // 2) a color-key is specified
            // 3) or an opacity other than 1.0 is specified
            // 4) or per-pixel alpha is requested.
            if((parameters.WindowStyle & NativeMethods.WS_CHILD) == 0 &&
               ( //parameters.ColorKey != null ||
                 //!MS.Internal.DoubleUtil.AreClose(parameters.Opacity, 1.0) ||
                parameters.UsesPerPixelOpacity))
            {
                parameters.ExtendedWindowStyle |= NativeMethods.WS_EX_LAYERED;
            }
            else
            {
                parameters.ExtendedWindowStyle &= (~NativeMethods.WS_EX_LAYERED);
            }


            _constructionParameters = parameters;
            _hwndWrapper = new HwndWrapper(parameters.WindowClassStyle,
                                       parameters.WindowStyle,
                                       parameters.ExtendedWindowStyle,
                                       parameters.PositionX,
                                       parameters.PositionY,
                                       parameters.Width,
                                       parameters.Height,
                                       parameters.WindowName,
                                       parameters.ParentWindow,
                                       wrapperHooks);

            _hwndTarget = new HwndTarget(_hwndWrapper.Handle);
            //_hwndTarget.ColorKey = parameters.ColorKey;
            //_hwndTarget.Opacity = parameters.Opacity;
            _hwndTarget.UsesPerPixelOpacity = parameters.UsesPerPixelOpacity;
            if(_hwndTarget.UsesPerPixelOpacity)
            {
                _hwndTarget.BackgroundColor = Colors.Transparent;

                // Prevent this window from being themed.
                UnsafeNativeMethods.CriticalSetWindowTheme(new HandleRef(this, _hwndWrapper.Handle), "", "");
            }
            _constructionParameters = null;

            if (!parameters.HasAssignedSize)
                _sizeToContent = SizeToContent.WidthAndHeight;

            _adjustSizingForNonClientArea = parameters.AdjustSizingForNonClientArea;
            _treatAncestorsAsNonClientArea = parameters.TreatAncestorsAsNonClientArea;
            
            // Listen to the UIContext.Disposed event so we can clean up.
            // The HwndTarget cannot work without a MediaContext which
            // is disposed when the UIContext is disposed.  So we need to
            // dispose the HwndTarget and also never use it again (to
            // paint or process input).  The easiest way to do this is to just
            // dispose the HwndSource at the same time.
            _weakShutdownHandler = new WeakEventDispatcherShutdown(this, this.Dispatcher);

            // Listen to the HwndWrapper.Disposed event so we can clean up.
            // The HwndTarget cannot work without a live HWND, and since
            // the HwndSource represents an HWND, we make sure we dispose
            // ourselves if the HWND is destroyed out from underneath us.
            _hwndWrapper.Disposed += new EventHandler(OnHwndDisposed);

            _stylus = new SecurityCriticalDataClass<HwndStylusInputProvider>(new HwndStylusInputProvider(this));

            // WM_APPCOMMAND events are handled thru this.
            _appCommand = new SecurityCriticalDataClass<HwndAppCommandInputProvider>(new HwndAppCommandInputProvider(this));

            // Register the top level source with the ComponentDispatcher.
            if (parameters.TreatAsInputRoot)
            {
                _weakPreprocessMessageHandler = new WeakEventPreprocessMessage(this, false);
            }
            AddSource();

            // Register dropable window.
            // The checking CallerHasPermissionWithAppDomainOptimization will call RegisterDropTarget
            // safely without the security exception in case of no unmanaged code permission.
            // So RegisterDropTarget will be called safely in case of having the unmanged code permission.
            // Otherwise, the security exception cause System.Printing to be instatiated which will
            // load system.drawing module.
            if (_hwndWrapper.Handle != IntPtr.Zero &&
                SecurityHelper.CallerHasPermissionWithAppDomainOptimization(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)))
            {
                // This call is safe since DragDrop.RegisterDropTarget is checking the unmanged
                // code permission.
                DragDrop.RegisterDropTarget(_hwndWrapper.Handle);
                _registeredDropTargetCount++;
            }
        }
コード例 #3
0
 public void AttachHwndTarget(HwndTarget hwndTarget)
 {
     Debug.Assert(hwndTarget != null);
     MonitorPowerEvent += hwndTarget.OnMonitorPowerEvent;
     if (_hwndTargetCount > 0)
     {
         // Every hwnd which registers to listen PBT_POWERSETTINGCHANGE
         // gets the message atleast once so as to set the appropriate
         // state. This call to the event handler simulates similar
         // behavior. It is too early for the hwnd to paint, hence
         // pass paintOnWake=false assuming that it will soon get
         // a WM_PAINT message.
         hwndTarget.OnMonitorPowerEvent(null, _monitorOn, /*paintOnWake*/ false);
     }
     _hwndTargetCount++;
 }