Beispiel #1
0
        private static void EnableBlur(Window window)
        {
            var windowHelper = new WindowInteropHelper(window);

            var accent = new Dwm.AccentPolicy
            {
                AccentState = Dwm.AccentState.ACCENT_ENABLE_BLURBEHIND
            };

            var accentStructSize = Marshal.SizeOf(accent);

            var accentPtr = Marshal.AllocHGlobal(accentStructSize);

            Marshal.StructureToPtr(accent, accentPtr, false);

            var data = new Dwm.WindowCompositionAttributeData
            {
                Attribute  = Dwm.WindowCompositionAttribute.WCA_ACCENT_POLICY,
                SizeOfData = accentStructSize,
                Data       = accentPtr
            };

            Dwm.SetWindowCompositionAttribute(windowHelper.Handle, ref data);

            Marshal.FreeHGlobal(accentPtr);
        }
Beispiel #2
0
 /// <summary>
 /// Make sure the monitoring is disabled and the Thumbnail is unregistered
 /// </summary>
 /// <param name="e">EventArgs</param>
 protected override void OnClosed(EventArgs e)
 {
     _locationPool.Return(_thumbnailRect);
     _windowMonitor.Dispose();
     _configurationMonitor.Dispose();
     Dwm.DwmUnregisterThumbnail(_phThumbnail);
     base.OnClosed(e);
 }
Beispiel #3
0
        private void UnregisterThumbnail()
        {
            if (_thumbnailHandle == IntPtr.Zero)
            {
                return;
            }

            Dwm.DwmUnregisterThumbnail(_thumbnailHandle);
            _thumbnailHandle = IntPtr.Zero;
        }
Beispiel #4
0
        public Window GetWindow(IntPtr handle)
        {
            var interopWindow = InteropWindowFactory.CreateFor(handle);

            interopWindow.Fill(InteropWindowCacheFlags.Info | InteropWindowCacheFlags.Text);
            var windowInfo = interopWindow.Info.Value;

            Dwm.GetExtendedFrameBounds(handle, out var nativeBounds);
            var innerBounds = (Rectangle)nativeBounds;
            var outerBounds = (Rectangle)windowInfo.Bounds;

            Rectangle bounds;
            Thickness border;

            if (outerBounds.Width > 0 || outerBounds.Height > 0)
            {
                var rawBorder = innerBounds.GetBorder(outerBounds);
                if (rawBorder.Left < 0 || rawBorder.Top < 0 || rawBorder.Right < 0 || rawBorder.Right < 0)
                {
                    bounds = new Rectangle(
                        innerBounds.Left - Math.Min(rawBorder.Left, 0),
                        innerBounds.Top - Math.Min(rawBorder.Top, 0),
                        innerBounds.Width - Math.Min(rawBorder.Left, 0) - Math.Min(rawBorder.Right, 0),
                        innerBounds.Height - Math.Min(rawBorder.Top, 0) - Math.Min(rawBorder.Bottom, 0));
                    border = new Thickness(
                        Math.Max(rawBorder.Left, 0),
                        Math.Max(rawBorder.Top, 0),
                        Math.Max(rawBorder.Right, 0),
                        Math.Max(rawBorder.Bottom, 0));
                }
                else
                {
                    bounds = innerBounds;
                    border = rawBorder;
                }
            }
            else
            {
                bounds = innerBounds;
                border = Thickness.Empty;
            }

            var dpi = (int)NativeDpiMethods.GetDpiForWindow(handle);

            return(new Window
            {
                Handle = handle,
                Title = interopWindow.Text,
                Bounds = bounds,
                Border = border,
                Dpi = new Point(dpi, dpi),
            });
        }
Beispiel #5
0
        /// <summary>
        /// Change the thumbnail settings
        /// </summary>
        private void UpdateThumbnail()
        {
            Opacity = Math.Max((byte)0x01, _pipConfiguration.Opacity) / 255d;
            // Prepare the displaying of the Thumbnail
            var props = new DwmThumbnailProperties
            {
                Opacity = _pipConfiguration.Opacity,
                Visible = true,
                SourceClientAreaOnly = _pipConfiguration.SourceClientAreaOnly,
                Destination          = new NativeRect(0, 0, Width, Height)
            };

            Dwm.DwmUpdateThumbnailProperties(_phThumbnail, ref props);
        }
Beispiel #6
0
 /// <summary>
 /// Create the thumbnail if the form is shown
 /// </summary>
 /// <param name="e">EventArgs</param>
 protected override void OnShown(EventArgs e)
 {
     base.OnShown(e);
     if (_phThumbnail == IntPtr.Zero)
     {
         var result = Dwm.DwmRegisterThumbnail(Handle, _hWnd, out _phThumbnail);
         if (result.Failed())
         {
             Close();
             return;
         }
         UpdateThumbnail();
     }
     User32Api.BringWindowToTop(Handle);
 }
Beispiel #7
0
        /// <summary>
        ///     Show the thumbnail of the supplied window above (or under) the parent Control
        /// </summary>
        /// <param name="window">WindowDetails</param>
        /// <param name="parentControl">Control</param>
        public void ShowThumbnail(IInteropWindow window, Control parentControl)
        {
            UnregisterThumbnail();

            Dwm.DwmRegisterThumbnail(Handle, window.Handle, out _thumbnailHandle);
            if (_thumbnailHandle == IntPtr.Zero)
            {
                return;
            }

            Dwm.DwmQueryThumbnailSourceSize(_thumbnailHandle, out var sourceSize);
            var thumbnailHeight = 200;
            var thumbnailWidth  = (int)(thumbnailHeight * (sourceSize.Width / (float)sourceSize.Height));

            if (parentControl != null && thumbnailWidth > parentControl.Width)
            {
                thumbnailWidth  = parentControl.Width;
                thumbnailHeight = (int)(thumbnailWidth * (sourceSize.Height / (float)sourceSize.Width));
            }
            Width  = thumbnailWidth;
            Height = thumbnailHeight;
            // Prepare the displaying of the Thumbnail
            var props = new DwmThumbnailProperties
            {
                Opacity = 255,
                Visible = true,
                SourceClientAreaOnly = false,
                Destination          = new NativeRect(0, 0, thumbnailWidth, thumbnailHeight)
            };

            Dwm.DwmUpdateThumbnailProperties(_thumbnailHandle, ref props);
            if (parentControl != null)
            {
                AlignToControl(parentControl);
            }

            if (!Visible)
            {
                Show();
            }
            // Make sure it's on "top"!
            if (parentControl != null)
            {
                User32Api.SetWindowPos(Handle, parentControl.Handle, 0, 0, 0, 0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Change the thumbnail settings
        /// </summary>
        private void UpdateThumbnail()
        {
            // Retrieve the current information about the window, this could changed
            var interopWindow = InteropWindowFactory.CreateFor(_hWnd).Fill();
            var sourceBounds  = interopWindow.Info.Value.Bounds;

            Opacity = Math.Max((byte)0x01, _pipConfiguration.Opacity) / 255d;
            // Prepare the displaying of the Thumbnail
            var props = new DwmThumbnailProperties
            {
                Opacity = _pipConfiguration.Opacity,
                Visible = true,
                SourceClientAreaOnly = _pipConfiguration.SourceClientAreaOnly,
                // This is the size of the DMW Thumbnail
                Destination = new NativeRect(0, 0, Width, Height),
                // Here it would be possible to select only a part of the window, but this is slightly tricky of someone resizes the window
                Source = new NativeRect(0, 0, sourceBounds.Width, sourceBounds.Height)
            };

            Dwm.DwmUpdateThumbnailProperties(_phThumbnail, ref props);
        }
Beispiel #9
0
        public void DecorateWindow()
        {
            try
            {
                // Obtain the window handle for WPF application
                IntPtr     mainWindowPtr = new WindowInteropHelper(window).Handle;
                HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
                mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

                // Get System Dpi
                System.Drawing.Graphics desktop = System.Drawing.Graphics.FromHwnd(mainWindowPtr);
                float DesktopDpiX = desktop.DpiX;
                float DesktopDpiY = desktop.DpiY;

                // Set Margins
                Dwm.MARGINS margins = new Dwm.MARGINS();

                // Extend glass frame into client area
                // Note that the default desktop Dpi is 96dpi. The  margins are
                // adjusted for the system Dpi.
                margins.cxLeftWidth  = Convert.ToInt32(5 * (DesktopDpiX / 96));
                margins.cxRightWidth = Convert.ToInt32(5 * (DesktopDpiX / 96));
                //margins.cyTopHeight = Convert.ToInt32(((int) topBar.ActualHeight + 5) * (DesktopDpiX / 96));
                margins.cyTopHeight    = Convert.ToInt32((32 + 5) * (DesktopDpiX / 96));
                margins.cyBottomHeight = Convert.ToInt32(5 * (DesktopDpiX / 96));

                int hr = Dwm.DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
                //
                if (hr < 0)
                {
                    Debug.WriteLine("DwmExtendFrameIntoClientArea Failed");
                    //DwmExtendFrameIntoClientArea Failed
                }
            }
            // If not Vista, paint background white.
            catch (DllNotFoundException)
            {
                Application.Current.MainWindow.Background = Brushes.White;
            }
        }
        /// <summary>
        ///     Get the WindowInfo
        /// </summary>
        /// <param name="interopWindow">InteropWindow</param>
        /// <param name="forceUpdate">set to true to make sure the value is updated</param>
        /// <returns>WindowInfo</returns>
        public static WindowInfo GetInfo(this IInteropWindow interopWindow, bool forceUpdate = false)
        {
            if (interopWindow.Info.HasValue && !forceUpdate)
            {
                return(interopWindow.Info.Value);
            }
            var windowInfo = WindowInfo.Create();

            User32Api.GetWindowInfo(interopWindow.Handle, ref windowInfo);

            // Now correct the bounds, for Windows 10
            if (Dwm.IsDwmEnabled)
            {
                NativeRect extendedFrameBounds;
                bool       gotFrameBounds = Dwm.GetExtendedFrameBounds(interopWindow.Handle, out extendedFrameBounds);
                if (gotFrameBounds && (interopWindow.IsApp() || WindowsVersion.IsWindows10OrLater && !interopWindow.IsMaximized()))
                {
                    windowInfo.Bounds = extendedFrameBounds;
                }
            }
            interopWindow.Info = windowInfo;
            return(interopWindow.Info.Value);
        }
Beispiel #11
0
        /// <summary>
        ///     Get the WindowInfo
        /// </summary>
        /// <param name="interopWindow">InteropWindow</param>
        /// <param name="forceUpdate">set to true to make sure the value is updated</param>
        /// <param name="autoCorrect">enable auto correction, e,g, have the bounds cropped to the parent(s)</param>
        /// <returns>WindowInfo</returns>
        public static WindowInfo GetInfo(this IInteropWindow interopWindow, bool forceUpdate = false, bool autoCorrect = true)
        {
            if (interopWindow.Info.HasValue && !forceUpdate)
            {
                return(interopWindow.Info.Value);
            }

            var windowInfo = WindowInfo.Create();

            User32Api.GetWindowInfo(interopWindow.Handle, ref windowInfo);

            // Test if we need to correct some values
            if (autoCorrect)
            {
                // Correct the bounds, for Windows 8+
                if (Dwm.IsDwmEnabled)
                {
                    // This only works for top level windows, otherwise a access denied is returned
                    bool gotFrameBounds = Dwm.GetExtendedFrameBounds(interopWindow.Handle, out var extendedFrameBounds);
                    if (gotFrameBounds && (interopWindow.IsApp() || WindowsVersion.IsWindows10OrLater && !interopWindow.IsMaximized()))
                    {
                        windowInfo.Bounds = extendedFrameBounds;
                    }
                }

                var parentWindow = interopWindow.GetParentWindow();
                if (interopWindow.HasParent)
                {
                    var parentInfo = parentWindow.GetInfo(forceUpdate, true);
                    windowInfo.Bounds       = windowInfo.Bounds.Intersect(parentInfo.Bounds);
                    windowInfo.ClientBounds = windowInfo.ClientBounds.Intersect(parentInfo.ClientBounds);
                }
            }

            interopWindow.Info = windowInfo;
            return(windowInfo);
        }
Beispiel #12
0
        /// <summary>
        ///     Capture DWM Window
        /// </summary>
        /// <param name="interopWindow">IInteropWindow</param>
        /// <param name="capture">Capture to fill</param>
        /// <param name="windowCaptureMode">Wanted WindowCaptureModes</param>
        /// <param name="autoMode">True if auto modus is used</param>
        /// <returns>ICapture with the capture</returns>
        public static ICapture CaptureDwmWindow(this IInteropWindow interopWindow, ICapture capture, WindowCaptureModes windowCaptureMode, bool autoMode)
        {
            var  thumbnailHandle = IntPtr.Zero;
            Form tempForm        = null;
            var  tempFormShown   = false;

            try
            {
                tempForm = new Form
                {
                    ShowInTaskbar   = false,
                    FormBorderStyle = FormBorderStyle.None,
                    TopMost         = true
                };

                // Register the Thumbnail
                Dwm.DwmRegisterThumbnail(tempForm.Handle, interopWindow.Handle, out thumbnailHandle);

                // Get the original size
                Dwm.DwmQueryThumbnailSourceSize(thumbnailHandle, out var sourceSize);

                if (sourceSize.Width <= 0 || sourceSize.Height <= 0)
                {
                    return(null);
                }

                // Calculate the location of the temp form
                var windowRectangle = interopWindow.GetInfo().Bounds;
                var formLocation    = windowRectangle.Location;
                var borderSize      = new Size();
                var doesCaptureFit  = false;
                if (!interopWindow.IsMaximized())
                {
                    // Assume using it's own location
                    formLocation = windowRectangle.Location;
                    using (var workingArea = new Region(Screen.PrimaryScreen.Bounds))
                    {
                        // Find the screen where the window is and check if it fits
                        foreach (var screen in Screen.AllScreens)
                        {
                            if (!Equals(screen, Screen.PrimaryScreen))
                            {
                                workingArea.Union(screen.Bounds);
                            }
                        }

                        // If the formLocation is not inside the visible area
                        if (!workingArea.AreRectangleCornersVisisble(windowRectangle))
                        {
                            // If none found we find the biggest screen
                            foreach (var screen in Screen.AllScreens)
                            {
                                var newWindowRectangle = new NativeRect(screen.WorkingArea.Location, windowRectangle.Size);
                                if (workingArea.AreRectangleCornersVisisble(newWindowRectangle))
                                {
                                    formLocation   = screen.Bounds.Location;
                                    doesCaptureFit = true;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            doesCaptureFit = true;
                        }
                    }
                }
                else if (!WindowsVersion.IsWindows8OrLater)
                {
                    //GetClientRect(out windowRectangle);
                    borderSize   = interopWindow.GetInfo().BorderSize;
                    formLocation = new NativePoint(windowRectangle.X - borderSize.Width, windowRectangle.Y - borderSize.Height);
                }

                tempForm.Location = formLocation;
                tempForm.Size     = sourceSize;

                // Prepare rectangle to capture from the screen.
                var captureRectangle = new NativeRect(formLocation.X, formLocation.Y, sourceSize.Width, sourceSize.Height);
                if (interopWindow.IsMaximized())
                {
                    // Correct capture size for maximized window by offsetting the X,Y with the border size
                    // and subtracting the border from the size (2 times, as we move right/down for the capture without resizing)
                    captureRectangle = captureRectangle.Inflate(borderSize.Width, borderSize.Height);
                }
                else
                {
                    // TODO: Also 8.x?
                    if (WindowsVersion.IsWindows10)
                    {
                        captureRectangle = captureRectangle.Inflate(CoreConfiguration.Win10BorderCrop.Width, CoreConfiguration.Win10BorderCrop.Height);
                    }

                    if (autoMode)
                    {
                        // check if the capture fits
                        if (!doesCaptureFit)
                        {
                            // if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
                            using (var thisWindowProcess = Process.GetProcessById(interopWindow.GetProcessId()))
                            {
                                if (!interopWindow.IsApp() && WindowCapture.IsGdiAllowed(thisWindowProcess))
                                {
                                    // we return null which causes the capturing code to try another method.
                                    return(null);
                                }
                            }
                        }
                    }
                }
                // Prepare the displaying of the Thumbnail
                var props = new DwmThumbnailProperties
                {
                    Opacity     = 255,
                    Visible     = true,
                    Destination = new NativeRect(0, 0, sourceSize.Width, sourceSize.Height)
                };
                Dwm.DwmUpdateThumbnailProperties(thumbnailHandle, ref props);
                tempForm.Show();
                tempFormShown = true;

                // Intersect with screen
                captureRectangle = captureRectangle.Intersect(capture.ScreenBounds);

                // Destination bitmap for the capture
                Bitmap capturedBitmap = null;
                // Check if we make a transparent capture
                if (windowCaptureMode == WindowCaptureModes.AeroTransparent)
                {
                    // Use white, later black to capture transparent
                    tempForm.BackColor = Color.White;
                    // Make sure everything is visible
                    tempForm.Refresh();
                    Application.DoEvents();

                    try
                    {
                        using (var whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle))
                        {
                            // Apply a white color
                            tempForm.BackColor = Color.Black;
                            // Make sure everything is visible
                            tempForm.Refresh();
                            if (!interopWindow.IsApp())
                            {
                                // Make sure the application window is active, so the colors & buttons are right
                                // TODO: Await?
                                interopWindow.ToForegroundAsync();
                            }
                            // Make sure all changes are processed and visible
                            Application.DoEvents();
                            using (var blackBitmap = WindowCapture.CaptureRectangle(captureRectangle))
                            {
                                capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Warn().WriteLine(e, "Exception: ");
                        // Some problem occurred, cleanup and make a normal capture
                        if (capturedBitmap != null)
                        {
                            capturedBitmap.Dispose();
                            capturedBitmap = null;
                        }
                    }
                }
                // If no capture up till now, create a normal capture.
                if (capturedBitmap == null)
                {
                    // Remove transparency, this will break the capturing
                    if (!autoMode)
                    {
                        tempForm.BackColor = Color.FromArgb(255, CoreConfiguration.DWMBackgroundColor.R, CoreConfiguration.DWMBackgroundColor.G, CoreConfiguration.DWMBackgroundColor.B);
                    }
                    else
                    {
                        var colorizationColor = Dwm.ColorizationSystemDrawingColor;
                        // Modify by losing the transparency and increasing the intensity (as if the background color is white)
                        colorizationColor  = Color.FromArgb(255, (colorizationColor.R + 255) >> 1, (colorizationColor.G + 255) >> 1, (colorizationColor.B + 255) >> 1);
                        tempForm.BackColor = colorizationColor;
                    }
                    // Make sure everything is visible
                    tempForm.Refresh();
                    if (!interopWindow.IsApp())
                    {
                        // Make sure the application window is active, so the colors & buttons are right
                        interopWindow.ToForegroundAsync();
                    }
                    // Make sure all changes are processed and visible
                    Application.DoEvents();
                    // Capture from the screen
                    capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle);
                }
                if (capturedBitmap != null)
                {
                    // Not needed for Windows 8
                    if (!WindowsVersion.IsWindows8OrLater)
                    {
                        // Only if the Inivalue is set, not maximized and it's not a tool window.
                        if (CoreConfiguration.WindowCaptureRemoveCorners && !interopWindow.IsMaximized() &&
                            !interopWindow.GetInfo().ExtendedStyle.HasFlag(ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW))
                        {
                            // Remove corners
                            if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat))
                            {
                                Log.Debug().WriteLine("Changing pixelformat to Alpha for the RemoveCorners");
                                var tmpBitmap = capturedBitmap.CloneBitmap(PixelFormat.Format32bppArgb) as Bitmap;
                                capturedBitmap.Dispose();
                                capturedBitmap = tmpBitmap;
                            }
                            RemoveCorners(capturedBitmap);
                        }
                    }
                }

                capture.Bitmap = capturedBitmap;
                // Make sure the capture location is the location of the window, not the copy
                capture.Location = interopWindow.GetInfo().Bounds.Location;
            }
            finally
            {
                if (thumbnailHandle != IntPtr.Zero)
                {
                    // Unregister (cleanup), as we are finished we don't need the form or the thumbnail anymore
                    Dwm.DwmUnregisterThumbnail(thumbnailHandle);
                }
                if (tempForm != null)
                {
                    if (tempFormShown)
                    {
                        tempForm.Close();
                    }
                    tempForm.Dispose();
                    tempForm = null;
                }
            }

            return(capture);
        }
Beispiel #13
0
 /// <summary>
 ///     Retrieve if the window is Visible and not cloaked (different desktop)
 /// </summary>
 /// <param name="interopWindow">InteropWindow</param>
 /// <param name="forceUpdate">set to true to make sure the value is updated</param>
 /// <returns>bool true if minimizedIconic (minimized)</returns>
 public static bool IsVisible(this IInteropWindow interopWindow, bool forceUpdate = false)
 {
     if (!interopWindow.IsVisible.HasValue || forceUpdate)
     {
         interopWindow.IsVisible = User32Api.IsWindowVisible(interopWindow.Handle) && !Dwm.IsWindowCloaked(interopWindow.Handle);
     }
     return(interopWindow.IsVisible.Value);
 }