前言windows 上 , 屏幕截图一般是调用 win32 api 完成的 , 如果 C# 想实现截图功能 , 就需要封装相关 api 。在 Windows 上 , 主要图形接口有 GDI 和 DirectX 。GDI 接口比较灵活 , 可以截取指定窗口 , 哪怕窗口被遮挡或位于显示区域外 , 但兼容性较低 , 无法截取 DX 接口输出的画面 。DirectX 是高性能图形接口(当然还有其他功能 , 与本文无关 , 忽略不计) , 主要作为游戏图形接口使用 , 灵活性较低 , 无法指定截取特定窗口(或者只是我不会吧) , 但是兼容性较高 , 可以截取任何输出到屏幕的内容 , 根据情况使用 。
正文以下代码使用了 C# 8.0 的新功能 , 只能使用 VS 2019 编译 , 如果需要在老版本 VS 使用 , 需要自行改造 。
GDI用静态类简单封装 GDI 接口并调用接口截图 。
1public static class CaptureWindow2{3#region 类4/// <summary>5/// Helper class containing User32 API functions6/// </summary>7private class User328{9[StructLayout(LayoutKind.Sequential)] 10public struct RECT 11{ 12public int left; 13public int top; 14public int right; 15public int bottom; 16} 17[DllImport("user32.dll")] 18public static extern IntPtr GetDesktopWindow(); 19[DllImport("user32.dll")] 20public static extern IntPtr GetWindowDC(IntPtr hWnd); 21[DllImport("user32.dll")] 22public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); 23[DllImport("user32.dll")] 24public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 2526[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Unicode)] 27public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 28} 2930private class Gdi32 31{ 3233public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter 34[DllImport("gdi32.dll")] 35public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, 36int nWidth, int nHeight, IntPtr hObjectSource, 37int nXSrc, int nYSrc, int dwRop); 38[DllImport("gdi32.dll")] 39public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, 40int nHeight); 41[DllImport("gdi32.dll")] 42public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 43[DllImport("gdi32.dll")] 44public static extern bool DeleteDC(IntPtr hDC); 45[DllImport("gdi32.dll")] 46public static extern bool DeleteObject(IntPtr hObject); 47[DllImport("gdi32.dll")] 48public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 49} 50#endregion 5152/// <summary> 53/// 根据句柄截图 54/// </summary> 55/// <param name="hWnd">句柄</param> 56/// <returns></returns> 57public static Image ByHwnd(IntPtr hWnd) 58{ 59// get te hDC of the target window 60IntPtr hdcSrc = https://www.isolves.com/it/rj/czxt/windows/2022-06-06/User32.GetWindowDC(hWnd); 61// get the size 62User32.RECT windowRect = new User32.RECT(); 63User32.GetWindowRect(hWnd, ref windowRect); 64int width = windowRect.right - windowRect.left; 65int height = windowRect.bottom - windowRect.top; 66// create a device context we can copy to 67IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); 68// create a bitmap we can copy it to, 69// using GetDeviceCaps to get the width/height 70IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); 71// select the bitmap object 72IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); 73// bitblt over 74Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.SRCCOPY); 75// restore selection 76Gdi32.SelectObject(hdcDest, hOld); 77// clean up 78Gdi32.DeleteDC(hdcDest); 79User32.ReleaseDC(hWnd, hdcSrc); 80// get a .NET image object for it 81Image img = Image.FromHbitmap(hBitmap); 82// free up the Bitmap object 83Gdi32.DeleteObject(hBitmap); 84return img; 85} 8687///
Direct3D【Windows GDI 窗口与 Direct3D 屏幕截图】
推荐阅读
- 苹果|本届苹果WWDC 可能是Windows电脑被黑最惨一次:老外直呼过分
- Windows操作系统|Win11年度版本22H2特性曝光:回滚系统更方便
- 饵料|把早口鱼钓好并不难。上鱼窗口期你明确吗?打窝与抽窝哪个效果好
- 魅族|魅族PANDAER首款掌机来了:全球首款超轻薄OLED Windows掌机
- 微软|微软神速!Windows 11的2023年更新确认 暗藏重磅功能
- 新装windows10无法找到网络适配器的驱动程序-window10无法找到网络适配器的驱动程序怎么办-
- 微软|Windows 11 2023年重大更新代号定了:毫不意外
- Windows操作系统|Steam 5月硬件调查出炉:Win11份额首破20%
- 微软|UWP日渐式微!微软Windows商店还有前途吗
- 梅毒窗口期