public static List <DisplayInfo> GetDisplays() { var list = new List <DisplayInfo>(); try { User32.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, (IntPtr hMonitor, IntPtr hdcMonitor, ref NativeRect lprcMonitor, IntPtr dwData) => { var mi = new MonitorInfoEx(); mi.Init(); mi.size = Marshal.SizeOf(mi); mi.size = 72; var success = User32.GetMonitorInfo(hMonitor, ref mi); if (success) { var di = new DisplayInfo(); di.MonitorArea = mi.monitor; di.WorkArea = mi.work; di.PrimaryDisplay = (mi.flags & 1) != 0; di.LogicalScreenHeight = GDI32.GetDeviceCaps(hMonitor, (int)GDI32.DeviceCap.VERTRES); di.PhysicalScreenHeight = GDI32.GetDeviceCaps(hMonitor, (int)GDI32.DeviceCap.DESKTOPVERTRES); // TransformToPixels(0, 0, out var x, out var y); uint dpiX; uint dpiY; try { ShCore.GetDpiForMonitor( hMonitor, MonitorDpiType.MDT_EFFECTIVE_DPI, out dpiX, out dpiY ); } catch { dpiX = 96; dpiY = 96; } di.scaleFactor2 = dpiX / 96f; list.Add(di); } else { Logger.Debug("Getting monitor info failed"); } return(true); }, IntPtr.Zero); AddAdditionalInfos(list); } catch (Exception e) { Logger.Exception(e); } return(list); }
private float GetScalingFactor() { Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr desktop = g.GetHdc(); int LogicalScreenHeight = GDI32.GetDeviceCaps(desktop, (int)GDI32.DeviceCap.VERTRES); int PhysicalScreenHeight = GDI32.GetDeviceCaps(desktop, (int)GDI32.DeviceCap.DESKTOPVERTRES); float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight; return(ScreenScalingFactor); // 1.25 = 125% }
// screen caputre method 1 functions public void CaptureScreen(string fileName, ImageFormat imageFormat) { int hdcSrc = User32.GetWindowDC(User32.GetDesktopWindow()), hdcDest = GDI32.CreateCompatibleDC(hdcSrc), hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, GDI32.GetDeviceCaps(hdcSrc, 8), GDI32.GetDeviceCaps(hdcSrc, 10)); GDI32.SelectObject(hdcDest, hBitmap); GDI32.BitBlt(hdcDest, 0, 0, GDI32.GetDeviceCaps(hdcSrc, 8), GDI32.GetDeviceCaps(hdcSrc, 10), hdcSrc, 0, 0, 0x00CC0020); SaveImageAs(hBitmap, fileName, imageFormat); Cleanup(hBitmap, hdcSrc, hdcDest); }
private static void TransformToPixels(double unitX, double unitY, out int pixelX, out int pixelY) { var hDc = User32.GetDC(IntPtr.Zero); if (hDc != IntPtr.Zero) { var dpiX = GDI32.GetDeviceCaps(hDc, (int)GDI32.DeviceCap.VERTRES); var dpiY = GDI32.GetDeviceCaps(hDc, (int)GDI32.DeviceCap.DESKTOPVERTRES); User32.ReleaseDC(IntPtr.Zero, hDc); pixelX = (int)(((double)dpiX / 96) * unitX); pixelY = (int)(((double)dpiY / 96) * unitY); } else { throw new ArgumentNullException("Failed to get DC."); } }
/// スクリーンキャプチャした結果をbyte[]に格納する /// @param[out] dpiX X軸方向のDPI /// @param[out] dpiY Y軸方向のDPI /// @return スクリーンキャプチャした結果のbyte[] public byte[] ExecuteByGetDIBits(out int dpiX, out int dpiY) { // Windowチェック if (!Common.Utilities.IsWindowValid(this.Window)) { dpiX = 96; dpiY = 96; return null; } // 結果を格納するためのbyte配列 var result = new byte[this.Size]; var bitmapInfo = this.BitmapInfo; // BitBlt var window = this.Window; var windowDC = User32.GetDC(window); dpiX = GDI32.GetDeviceCaps(windowDC, GDI32.LOGPIXELSX); dpiY = GDI32.GetDeviceCaps(windowDC, GDI32.LOGPIXELSY); var capturedDC = GDI32.CreateCompatibleDC(windowDC); var capturedBitmap = GDI32.CreateCompatibleBitmap(windowDC, this.ClippingWidth, this.ClippingHeight); { var originalBitmap = GDI32.SelectObject(capturedDC, capturedBitmap); GDI32.BitBlt(capturedDC, 0, 0, this.ClippingWidth, this.ClippingHeight, windowDC, this.ClippingX, this.ClippingY, this.ShowLayeredWindow ? GDI32.SRCCOPY | GDI32.CAPTUREBLT : GDI32.SRCCOPY); GDI32.GetDIBits(capturedDC, capturedBitmap, 0, (uint)this.ClippingHeight, result, ref bitmapInfo, GDI32.DIB_RGB_COLORS); GDI32.SelectObject(capturedDC, originalBitmap); } GDI32.DeleteObject(capturedBitmap); GDI32.DeleteDC(capturedDC); User32.ReleaseDC(window, windowDC); /// @todo(me) マウスカーソルの合成・・・?いるか? if (this.ShowCursor) { // nop } return result; }
/* Author: Perry Lee * Submission: Capture Screen (Add Screenshot Capability to Programs) * Date of Submission: 12/29/03 */ public static void CaptureWindow(IntPtr hwnd, int winx, int winy, Stream str, ImageFormat imageFormat) { int hdcSrc = 0; Graphics g = Graphics.FromHwnd(hwnd); hdcSrc = (int)g.GetHdc(); if (hdcSrc != 0) { int hdcDest = GDI32.CreateCompatibleDC(hdcSrc), hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, GDI32.GetDeviceCaps(hdcSrc, 8), GDI32.GetDeviceCaps(hdcSrc, 10)); GDI32.SelectObject(hdcDest, hBitmap); GDI32.BitBlt(hdcDest, 0, 0, GDI32.GetDeviceCaps(hdcSrc, 8), GDI32.GetDeviceCaps(hdcSrc, 10), hdcSrc, winx, winy, 0x00CC0020); SaveImageAs(hBitmap, str, imageFormat); Cleanup(hBitmap, hdcSrc, hdcDest); } if (g != null) { g.Dispose(); } }
internal Screen(IntPtr monitor, IntPtr hdc) { currentDesktopChangedCount = -1; workingArea = Rectangle.Empty; IntPtr screenDC = hdc; if (!multiMonitorSupport || monitor == (IntPtr)PRIMARY_MONITOR) { // Single monitor system // if (User32.GetSystemMetrics(80) != 0) { bounds = new Rectangle(User32.GetSystemMetrics(76), User32.GetSystemMetrics(77), User32.GetSystemMetrics(78), User32.GetSystemMetrics(79)); } else { Size size = new Size(User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)); bounds = new Rectangle(0, 0, size.Width, size.Height); } //bounds = SystemInformation.VirtualScreen; primary = true; deviceName = "DISPLAY"; } else { // MultiMonitor System // We call the 'A' version of GetMonitorInfoA() because // the 'W' version just never fills out the struct properly on Win2K. // var info = new User32.MonitorInfoEx(); info.Init(); User32.GetMonitorInfo(monitor, ref info); bounds = Rectangle.FromLTRB(info.Monitor.Left, info.Monitor.Top, info.Monitor.Right, info.Monitor.Bottom); primary = ((info.Flags & MONITORINFOF_PRIMARY) != 0); /*int count = info.DeviceName.Length; * while (count > 0 && info.DeviceName[count - 1] == (char)0) { * count--; * } * * deviceName = new string(info.szDevice); * deviceName = deviceName.TrimEnd((char)0);*/ deviceName = info.DeviceName; if (hdc == IntPtr.Zero) { screenDC = GDI32.CreateDC(deviceName, null, null, new HandleRef()); } } hmonitor = monitor; this.bitDepth = GDI32.GetDeviceCaps(new HandleRef(null, screenDC).Handle, 12); this.bitDepth *= GDI32.GetDeviceCaps(new HandleRef(null, screenDC).Handle, 14); if (hdc != screenDC) { GDI32.DeleteDC(new HandleRef(null, screenDC).Handle); } }
private void AddCustomProperties() { if (_map.Contains(PropertyTag.PixelUnit) == false) { System.Drawing.Size screenDPI = User32.GetScreenResolution(); _map.Add(PropertyTag.PixelUnit, PropertyItemFactory.CreateInstance(PropertyTag.PixelUnit, (byte)0x2)); // 1 : pixel per cm -- 2 : pixel per inch if (_map.Contains(PropertyTag.XResolution) && _map.Contains(PropertyTag.YResolution)) { int dpiX = ((PropertyItem)_map[PropertyTag.XResolution]).Value[0]; int dpiY = ((PropertyItem)_map[PropertyTag.YResolution]).Value[0]; _map.Add(PropertyTag.PixelPerUnitX, PropertyItemFactory.CreateInstance(PropertyTag.PixelPerUnitX, dpiX)); _map.Add(PropertyTag.PixelPerUnitY, PropertyItemFactory.CreateInstance(PropertyTag.PixelPerUnitY, dpiY)); } else { _map.Add(PropertyTag.PixelPerUnitX, PropertyItemFactory.CreateInstance(PropertyTag.PixelPerUnitX, screenDPI.Width)); _map.Add(PropertyTag.PixelPerUnitY, PropertyItemFactory.CreateInstance(PropertyTag.PixelPerUnitY, screenDPI.Height)); } } if (_map.Contains(PropertyTag.SoftwareUsed) == false) { _map.Add(PropertyTag.SoftwareUsed, PropertyItemFactory.CreateInstance(PropertyTag.SoftwareUsed, SOFTWAREUSED)); } if (_map.Contains(PropertyTag.HostComputer) == false) { _map.Add(PropertyTag.HostComputer, PropertyItemFactory.CreateInstance(PropertyTag.HostComputer, HOSTCOMPUTER)); } if (_map.Contains(PropertyTag.Artist) == false) { _map.Add(PropertyTag.Artist, PropertyItemFactory.CreateInstance(PropertyTag.Artist, ARTISTNAME)); } if (_map.Contains(PropertyTag.Copyright) == false) { _map.Add(PropertyTag.Copyright, PropertyItemFactory.CreateInstance(PropertyTag.Copyright, COPYRIGHT)); } // HACK : Store original color depth info into the ImageDescription tag // Reason : // * GDI+ cannot store BitsPerSample and SamplesPerPixel for PNG images) // * Cannot store custom PropertyImtem in PNG (as least not using GDI+) if (_map.Contains(PropertyTag.ImageDescription) == false) { IntPtr screenDC = IntPtr.Zero; try { screenDC = User32.GetDC(IntPtr.Zero); if (screenDC == IntPtr.Zero) { throw new System.Runtime.InteropServices.ExternalException("Native call to 'GetDC' API failed"); } int originalBpp = GDI32.GetDeviceCaps(screenDC, (int)GDI32.GetDeviceCapsIndex.BITSPIXEL); if (originalBpp == 0) { throw new System.Runtime.InteropServices.ExternalException("Native call to 'GetDeviceCaps(BitsPixel)' API failed"); } PixelFormat pixelFormat = PixelFormat.Undefined; switch (originalBpp) { // case 64: pixelFormat = PixelFormat.Format64bppArgb; break; // case 48: pixelFormat = PixelFormat.Format48bppRgb; break; case 32: pixelFormat = PixelFormat.Format32bppArgb; break; case 24: pixelFormat = PixelFormat.Format24bppRgb; break; case 16: pixelFormat = PixelFormat.Format16bppRgb565; break; case 15: pixelFormat = PixelFormat.Format16bppRgb555; break; // case 8: pixelFormat = PixelFormat.Format8bppIndexed; break; // case 4: pixelFormat = PixelFormat.Format4bppIndexed; break; // case 1: pixelFormat = PixelFormat.Format1bppIndexed; break; default: throw new NotSupportedException("This Color Depth ( " + originalBpp.ToString() + " bits per pixel) is not supported"); } string description = "OriginalPixelFormat=" + ((int)pixelFormat).ToString(); _map.Add(PropertyTag.ImageDescription, PropertyItemFactory.CreateInstance(PropertyTag.ImageDescription, description)); } finally { if (screenDC != IntPtr.Zero) { User32.ReleaseDC(IntPtr.Zero, screenDC); screenDC = IntPtr.Zero; } } } }