win81截图工具-(win8系统截图工具)

路由设置 次浏览手机阅读
win81截图工具 (win8系统截图工具) 前言

Windows 上面,屏幕截图通常被调用 win32 api 完成的,如果 C# 要实现截图功能,需要封装相关功能 api。在 Windows 上,主图形接口有 GDI 和 DirectX。GDI 界面更灵活,可以截取指定的窗口,即使窗口被屏蔽或位于显示区外,但兼容性较低,无法截取 DX 接口输出的图片。DirectX 它是一个高性能的图形接口(当然,还有其他功能,与本文无关,忽略),主要用作游戏图形接口,灵活性低,不能指定特定的窗口(或只是我不能),但兼容性高,可以根据情况截取任何输出到屏幕的内容。

正文

使用了以下代码 C# 8.0 只能使用新功能 VS 2019 如果需要在旧版本中编译, VS 使用时,需要自行改造。

GDI

简单地用静态类包装 GDI 并调用接口截图。

1 public static class CaptureWindow 2{ 3 #region 类 4 /// <summary> 5 /// Helper class containing User32 API functions 6 /// </summary> 7 private class User32 8{ 9[StructLayout(LayoutKind.Sequential)]10 public struct RECT 11{ 12 public int left; 13 public int top; 14 public int right; 15 public int bottom; 16 }17[DllImport("user32.dll")]18 public static extern IntPtr GetDesktopWindow(); 19[DllImport("user32.dll")]20 public static extern IntPtr GetWindowDC(IntPtr hWnd); 21[DllImport("user32.dll")]22 public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); 23[DllImport("user32.dll")]24 public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 25 26[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Unicode)]27 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 28 }29 30 private class Gdi32 31{ 32 33 public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter 34[DllImport("gdi32.dll")]35 public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, 36 int nWidth, int nHeight, IntPtr hObjectSource, 37 int nXSrc, int nYSrc, int dwRop); 38[DllImport("gdi32.dll")]39 public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, 40 int nHeight); 41[DllImport("gdi32.dll")]42 public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 43[DllImport("gdi32.dll")]44 public static extern bool DeleteDC(IntPtr hDC); 45[DllImport("gdi32.dll")]46 public static extern bool DeleteObject(IntPtr hObject); 47[DllImport("gdi32.dll")]48 public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 49 }50 #endregion 51 52 /// <summary> 53 /// 根据句柄截图 54 /// </summary> 55 /// <param name="hWnd">句柄</param> 56 /// <returns></returns> 57 public static Image ByHwnd(IntPtr hWnd) 58{ 59 // get te hDC of the target window 60 IntPtr hdcSrc = User32.GetWindowDC(hWnd); 61 // get the size 62 User32.RECT windowRect = new User32.RECT(); 63 User32.GetWindowRect(hWnd, ref windowRect); 64 int width = windowRect.right - windowRect.left; 65 int height = windowRect.bottom - windowRect.top; 66 // create a device context we can copy to 67 IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); 68 // create a bitmap we can copy it to, 69 // using GetDeviceCaps to get the width/height 70 IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); 71 // select the bitmap object 72 IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); 73 // bitblt over 74 Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.SRCCOPY); 75 // restore selection 76 Gdi32.SelectObject(hdcDest, hOld); 77 // clean up 78 Gdi32.DeleteDC(hdcDest); 79 User32.ReleaseDC(hWnd, hdcSrc); 80 // get a .NET image object for it 81 Image img = Image.FromHbitmap(hBitmap); 82 // free up the Bitmap object 83 Gdi32.DeleteObject(hBitmap); 84 return img; 85 }86 87 /// <summary> 88 /// 根据窗口名称截图 89 /// </summary> 90 /// <param name="windowName">窗口名称</param> 91 /// <returns></returns> 92 public static Image ByName(string windowName) 93{ 94 IntPtr handle = User32.FindWindow(null, windowName); 95 IntPtr hdcSrc = User32.GetWindowDC(handle); 96 User32.RECT windowRect = new User32.RECT(); 97 User32.GetWindowRect(handle, ref windowRect); 98 int width = windowRect.right - windowRect.left; 99 int height = windowRect.bottom - windowRect.

喜欢 ()