internal override void OnEnterMenuMode() { // We opt-in this HwndSource to the new behavior for "exclusive" // menu mode only if AcquireHwndFocusInMenuMode is false. IsInExclusiveMenuMode = !_acquireHwndFocusInMenuMode; if(IsInExclusiveMenuMode) { Debug.Assert(_weakMenuModeMessageHandler == null); // Re-subscribe to the ComponentDispatcher.ThreadPreprocessMessage so we go first. _weakMenuModeMessageHandler = new WeakEventPreprocessMessage(this, true); // Hide the Win32 caret UnsafeNativeMethods.HideCaret(new HandleRef(this, IntPtr.Zero)); } }
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++; } }