C# 根据句柄获取窗体截图 不用Aforge类
时间: 2024-10-08 21:03:24 浏览: 44
在C#中,如果你想要获取Windows窗口的屏幕截图而不使用AForge库,可以利用System.Drawing命名空间下的功能来实现。通常我们会使用`ControlHandle`来获取窗体的句柄,然后通过这个句柄来操作底层的HBITMAP(位图句柄)。以下是一个简单的步骤:
1. 首先,你需要包含必要的命名空间:
```csharp
using System;
using System.Drawing;
using System.Runtime.InteropServices;
```
2. 定义一个结构体来存储控制信息,包括句柄和位置:
```csharp
[StructLayout(LayoutKind.Sequential)]
public struct ControlInfo
{
public IntPtr hWnd;
public Rectangle ClientRectangle;
}
```
3. 使用DllImport引入用于操作窗口句柄的函数:
```csharp
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out Rectangle rect);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int width, int height);
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint nFlags);
```
4. 创建一个方法来获取指定窗体的截图:
```csharp
public Bitmap CaptureFormScreenshot(string windowTitle)
{
ControlInfo info = new ControlInfo();
IntPtr hWnd = FindWindow(null, windowTitle); // 查找窗口句柄
if (hWnd == IntPtr.Zero) throw new ArgumentException($"无法找到标题为'{windowTitle}'的窗口");
GetWindowRect(hWnd, out info.ClientRectangle); // 获取窗口区域
using (var hdcScreen = GetDC(IntPtr.Zero)) // 获取设备上下文
{
var compatibleHdc = CreateCompatibleBitmap(hdcScreen, info.ClientRectangle.Width, info.ClientRectangle.Height);
using (var bmp = new Bitmap(compatibleHdc))
{
using (var hdcBlt = CreateCompatibleDC(hdcScreen))
{
SelectObject(hdcBlt, compatibleHdc);
PrintWindow(hWnd, hdcBlt, PW_CLIENTONLY); // 截取客户区内容到新位图上
var screenshotData = bmp.LockBits(info.ClientRectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(screenshotData.Scan0, byte[], 0, screenshotData.Stride * screenshotData.Height);
bmp.UnlockBits(screenshotData);
return new Bitmap(bmp, info.ClientRectangle.Size);
}
}
}
}
```
阅读全文