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; }