Exemplo n.º 1
0
        private Bitmap ScreenshotWindowDWM(IntPtr targetWindow, bool withOpaqueGlass)
        {
            if (!withOpaqueGlass)
            {
                return(Core.ScreenshotWindow(targetWindow));
            }

            Trace.WriteLine(string.Format("Creating screenshot of window {0}: '{1}'...", this.WindowClass, targetWindow), string.Format("Screenshot.ScreenshotWindowDWM [{0}]", System.Threading.Thread.CurrentThread.Name));

            ////todo- don't reposition if there's another monitor
            //var CurrentScreen = Screen.FromHandle(TargetHandle);
            //TargetWindowRect.X = Math.Max(TargetWindowRect.X, CurrentScreen.WorkingArea.Left);
            //TargetWindowRect.Y = Math.Max(TargetWindowRect.Y, CurrentScreen.WorkingArea.Top);

            var DPIScaleFactor    = Helper.GetDPIScaleFactor();
            var WindowBorderWidth = Helper.GetWindowBorderWidth() * DPIScaleFactor;

            var BackingPositionRect = isMaximized ? new Rectangle(TargetRect.Left, TargetRect.Top, TargetRect.Width, TargetRect.Height) : new Rectangle(TargetRect.Left, TargetRect.Top, TargetRect.Width, TargetRect.Height);

            if (Environment.OSVersion.Version.CompareTo(new Version(6, 2)) > 0)
            {
                if (Helper.VisualStyle == Helper.VisualStyles.Aero)
                {
                    BackingPositionRect.X      += isMaximized && DPIScaleFactor == 1 ? 0 : 2;
                    BackingPositionRect.Height -= 2;
                    BackingPositionRect.Width  -= 4;
                }
            }

            var ThumbRect = new Windowing.RECT(0, 0, BackingPositionRect.Width, BackingPositionRect.Height);

            if (Environment.OSVersion.Version.CompareTo(new Version(6, 2)) > 0)
            {
                if (Helper.VisualStyle == Helper.VisualStyles.Aero)
                {
                    ThumbRect.Left   -= 2;
                    ThumbRect.Right  += 2;
                    ThumbRect.Bottom += 2;
                }
            }

            Bitmap screenshot = new Bitmap(1, 1);

            using (var BackingWindow = new DWMBackingForm(Core.GetWindowGlassColor(), BackingPositionRect))
            {
                try
                {
                    IntPtr ThumbHandle;
                    var    ThumbProps = new DWM.DWM_THUMBNAIL_PROPERTIES()
                    {
                        dwFlags  = DWM.DWM_TNP_VISIBLE | DWM.DWM_TNP_RECTDESTINATION | DWM.DWM_TNP_OPACITY,
                        fVisible = true,
                        fSourceClientAreaOnly = true,
                        opacity       = (byte)255,
                        rcDestination = ThumbRect
                    };
                    DWM.DwmRegisterThumbnail(BackingWindow.Handle, targetWindow, out ThumbHandle);
                    DWM.DwmUpdateThumbnailProperties(ThumbHandle, ref ThumbProps);
                    BackingWindow.Disposed += (s, e) => DWM.DwmUnregisterThumbnail(ThumbHandle);

                    BackingWindow.Visible = true;

                    ////Discovered by experimentation
                    //double offset = Math.Floor(7.0 * DPIScaleFactor);
                    //double extra_offset_left = 0;
                    //double extra_offset_top = 0;
                    //switch (Helper.OperatingSystem)
                    //{
                    //    case Helper.OperatingSystems.Win8:
                    //        offset = Math.Floor(9.0 * DPIScaleFactor);
                    //        extra_offset_left = -3.3 * DPIScaleFactor + (Helper.VisualStyle == Helper.VisualStyles.Aero ? -2 : 0);
                    //        extra_offset_top = -3.3 * DPIScaleFactor;
                    //        break;
                    //}

                    CaptureRect = isMaximized ? this.TargetScreen.WorkingArea : BackingPositionRect; //: BackingWindow.RectangleToScreen(ThumbRect);
                    //CaptureRect = isMaximized && Helper.HasNonClientBorder(TargetHandle) ? new Rectangle((int)(BackingPositionRect.Left + WindowBorderWidth + offset + extra_offset_left), (int)(BackingPositionRect.Top + WindowBorderWidth + offset + extra_offset_top), (int)(BackingPositionRect.Width - WindowBorderWidth * 2 - offset * 2 - extra_offset_left * 2 - (2 - Math.Floor(DPIScaleFactor))), (int)(BackingPositionRect.Height - WindowBorderWidth * 2 - offset * 2 - extra_offset_top * 2 - (2 - Math.Floor(DPIScaleFactor)))) : BackingPositionRect;

                    screenshot = Core.ScreenshotArea(CaptureRect);
                    BackingWindow.Close();
                }
                catch (Exception e)
                {
                    //mystery gdi exception when closing the backing form... sometimes...
                }
            }

            Trace.WriteLine("Done.", string.Format("Screenshot.ScreenshotWindowDWM [{0}]", System.Threading.Thread.CurrentThread.Name));

            return(screenshot);
        }
        private Bitmap ScreenshotWindowDWM(IntPtr targetWindow, bool withOpaqueGlass)
        {
            if (!withOpaqueGlass)
                return Core.ScreenshotWindow(targetWindow);

            Trace.WriteLine(string.Format("Creating screenshot of window {0}: '{1}'...", this.WindowClass, targetWindow), string.Format("Screenshot.ScreenshotWindowDWM [{0}]", System.Threading.Thread.CurrentThread.Name));

            ////todo- don't reposition if there's another monitor
            //var CurrentScreen = Screen.FromHandle(TargetHandle);
            //TargetWindowRect.X = Math.Max(TargetWindowRect.X, CurrentScreen.WorkingArea.Left);
            //TargetWindowRect.Y = Math.Max(TargetWindowRect.Y, CurrentScreen.WorkingArea.Top);

            var DPIScaleFactor = Helper.GetDPIScaleFactor();
            var WindowBorderWidth = Helper.GetWindowBorderWidth() * DPIScaleFactor;

            var BackingPositionRect = isMaximized ? new Rectangle(TargetRect.Left, TargetRect.Top, TargetRect.Width, TargetRect.Height) : new Rectangle(TargetRect.Left, TargetRect.Top, TargetRect.Width, TargetRect.Height);
            if (Environment.OSVersion.Version.CompareTo(new Version(6, 2)) > 0)
            {
                if (Helper.VisualStyle == Helper.VisualStyles.Aero)
                {
                    BackingPositionRect.X += isMaximized && DPIScaleFactor == 1 ? 0 : 2;
                    BackingPositionRect.Height -= 2;
                    BackingPositionRect.Width -= 4;
                }
            }

            var ThumbRect = new Windowing.RECT(0, 0, BackingPositionRect.Width, BackingPositionRect.Height);
            if (Environment.OSVersion.Version.CompareTo(new Version(6, 2)) > 0)
            {
                if (Helper.VisualStyle == Helper.VisualStyles.Aero)
                {
                    ThumbRect.Left -= 2;
                    ThumbRect.Right += 2;
                    ThumbRect.Bottom += 2;
                }
            }

            Bitmap screenshot = new Bitmap(1, 1);
            using (var BackingWindow = new DWMBackingForm(Core.GetWindowGlassColor(), BackingPositionRect))
            {
                try
                {
                    IntPtr ThumbHandle;
                    var ThumbProps = new DWM.DWM_THUMBNAIL_PROPERTIES()
                    {
                        dwFlags = DWM.DWM_TNP_VISIBLE | DWM.DWM_TNP_RECTDESTINATION | DWM.DWM_TNP_OPACITY,
                        fVisible = true,
                        fSourceClientAreaOnly = true,
                        opacity = (byte)255,
                        rcDestination = ThumbRect
                    };
                    DWM.DwmRegisterThumbnail(BackingWindow.Handle, targetWindow, out ThumbHandle);
                    DWM.DwmUpdateThumbnailProperties(ThumbHandle, ref ThumbProps);
                    BackingWindow.Disposed += (s, e) => DWM.DwmUnregisterThumbnail(ThumbHandle);

                    BackingWindow.Visible = true;

                    ////Discovered by experimentation
                    //double offset = Math.Floor(7.0 * DPIScaleFactor);
                    //double extra_offset_left = 0;
                    //double extra_offset_top = 0;
                    //switch (Helper.OperatingSystem)
                    //{
                    //    case Helper.OperatingSystems.Win8:
                    //        offset = Math.Floor(9.0 * DPIScaleFactor);
                    //        extra_offset_left = -3.3 * DPIScaleFactor + (Helper.VisualStyle == Helper.VisualStyles.Aero ? -2 : 0);
                    //        extra_offset_top = -3.3 * DPIScaleFactor;
                    //        break;
                    //}

                    CaptureRect = isMaximized ? this.TargetScreen.WorkingArea : BackingPositionRect; //: BackingWindow.RectangleToScreen(ThumbRect);
                    //CaptureRect = isMaximized && Helper.HasNonClientBorder(TargetHandle) ? new Rectangle((int)(BackingPositionRect.Left + WindowBorderWidth + offset + extra_offset_left), (int)(BackingPositionRect.Top + WindowBorderWidth + offset + extra_offset_top), (int)(BackingPositionRect.Width - WindowBorderWidth * 2 - offset * 2 - extra_offset_left * 2 - (2 - Math.Floor(DPIScaleFactor))), (int)(BackingPositionRect.Height - WindowBorderWidth * 2 - offset * 2 - extra_offset_top * 2 - (2 - Math.Floor(DPIScaleFactor)))) : BackingPositionRect;

                    screenshot = Core.ScreenshotArea(CaptureRect);
                    BackingWindow.Close();
                }
                catch (Exception e)
                {
                    //mystery gdi exception when closing the backing form... sometimes...
                }
            }

            Trace.WriteLine("Done.", string.Format("Screenshot.ScreenshotWindowDWM [{0}]", System.Threading.Thread.CurrentThread.Name));

            return screenshot;
        }