public ImageCaptureWindow(System.Drawing.Rectangle rect, AreaSelection areaSelection) { InitializeComponent(); MouseUp += OnMouseUp; MouseDown += OnMouseDown; MouseMove += OnMouseMove; Loaded += OnMainWindowLoaded; _scalor = DpiUtilities.GetVirtualPixelScale(this); _areaSelection = areaSelection; var monitors = _areaSelection.GetMonitorsInformation(); _screenShotImage = new ScreenshotImage(); _screenScalor = DpiUtilities.GetScreenScalingFactor(); _screenShotImage.SnapShot(rect, _screenScalor); WindowStartupLocation = WindowStartupLocation.Manual; SourceInitialized += (sender, e) => { IntPtr hWnd = new WindowInteropHelper(this).Handle; NativeMethods.SetWindowPos(hWnd, (IntPtr)NativeMethods.SetWindowPosInsertAfter.HWND_TOP, rect.Left, rect.Top, rect.Width, rect.Height, 0); }; var bmDesktopSource = ScreenCapture.GetBitmapSource(_screenShotImage.ScreenSnapshotImage); BackgroundImage.Fill = new ImageBrush(bmDesktopSource); // MagnifierBackgroundImage.Source = bmDesktopSource; }
private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { NativeMethods.MINMAXINFO mmi = (NativeMethods.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(NativeMethods.MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor System.IntPtr monitor = NativeMethods.GetMonitorFromWindow(hwnd); // MinHeight and MinWidth need to be scaled from Virtual Pixels back to Logical Pixels DpiScale dpiScale = VirtualPixelScale; if (monitor != System.IntPtr.Zero) { NativeMethods.MONITORINFO monitorInfo = new NativeMethods.MONITORINFO(); NativeMethods.GetMonitorInfo(monitor, monitorInfo); NativeMethods.RECT rcWorkArea = monitorInfo.rcWork; NativeMethods.RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = DoubleToInt32(Math.Abs(rcWorkArea.right - rcWorkArea.left)); mmi.ptMaxSize.y = DoubleToInt32(Math.Abs(rcWorkArea.bottom - rcWorkArea.top)); // After much research, it appears that the MaxTrackSize is used for secondary monitors // while MaxSize is used for the primary monitor. mmi.ptMaxTrackSize.x = DoubleToInt32(Math.Abs(rcWorkArea.right - rcWorkArea.left)); mmi.ptMaxTrackSize.y = DoubleToInt32(Math.Abs(rcWorkArea.bottom - rcWorkArea.top)); mmi.ptMinTrackSize.x = GetMinWidthInScreenPixels(dpiScale); mmi.ptMinTrackSize.y = GetMinHeightInScreenPixels(dpiScale); } Marshal.StructureToPtr(mmi, lParam, true); }
private BitmapSource GetCapturedImage() { var rect = _areaSelection.GetSelectedArea(); // decide which monitor the selected area belongs to by checking the mid point of the selected area var x = (rect.left + rect.width / 2); var y = (rect.top + rect.height / 2); var hMonitor = NativeMethods.MonitorFromPoint(new NativeMethods.POINT() { x = x, y = y }, 0); var curMon = _areaSelection.ScreenProps.GetMonitorInformation(hMonitor); var monitorScalingX = curMon.dpiX / 96 / _screenScalor; var monitorScalingY = curMon.dpiY / 96 / _screenScalor; var dpiScaler = new DpiScale(monitorScalingX, monitorScalingY); var capturedImage = _screenShotImage.GetCaptureImage(rect, dpiScaler); // Copies to clipboard based on user setting if (UserSettings.CopyToClipboardAfterSnip) { System.Windows.Clipboard.SetImage(capturedImage); } return(capturedImage); }
private void RecalculateSystemScale() { DpiUtilities.GetSystemEffectiveDpi(out _systemDpiX, out _systemDpiY); SystemScale = DpiUtilities.CalculateScale(_systemDpiX, _systemDpiY, 96, 96); #if (DEBUG) System.Diagnostics.Debug.WriteLine("System DPI = " + _systemDpiX.ToString()); #endif }
/// <summary> /// Detect if the tools are docked at the edge of the screen /// </summary> /// <param name="scale"></param> /// <param name="screen"></param> /// <returns></returns> private DockState ToolsDockState(DpiScale scale, System.Windows.Forms.Screen screen) { if ((int)Math.Round(Top * scale.Y) <= screen.WorkingArea.Top) { return(DockState.Top); } else if ((int)Math.Round(Left * scale.X) <= screen.WorkingArea.Left) { return(DockState.Left); } else if ((int)Math.Round((Left + ActualWidth) * scale.X) >= screen.WorkingArea.Right) { return(DockState.Right); } else if ((int)Math.Round((Top + ActualHeight) * scale.Y) >= screen.WorkingArea.Bottom) { return(DockState.Bottom); } return(DockState.Middle); }
private int GetMinHeightInScreenPixels(DpiScale dpiScale) { double value = double.IsNaN(VirtualMinHeight) ? SystemParameters.MinimumWindowHeight : VirtualMinHeight; return(DoubleToInt32(value * dpiScale.Y)); }
private int GetMinWidthInScreenPixels(DpiScale dpiScale) { double value = double.IsNaN(VirtualMinWidth) ? SystemParameters.MinimumWindowWidth : VirtualMinWidth; return(DoubleToInt32(value * dpiScale.X)); }
/// <summary> /// Gets the working area in virtual pixels (Left, Top, Width, Height). /// </summary> /// <param name="window">The window.</param> /// <returns></returns> public static Tuple <double, double, double, double> GetWorkingAreaInVirtualPixels(Window window, DpiScale dpiScale) { var workingArea = GetWorkingArea(window); return(new Tuple <double, double, double, double>(workingArea.Item1 / dpiScale.X, workingArea.Item2 / dpiScale.Y, workingArea.Item3 / dpiScale.X, workingArea.Item4 / dpiScale.Y)); }