PrintWindow的好处就在这,只要想截的窗口不是最小化,无论在屏幕外还是只显示一半还是被覆盖,都可以成功截取我们想要的部分。
C#代码如下:(网上代码有些缺陷,略做修改)
public static Bitmap GetWindow(IntPtr hWnd) //hWnd可以是窗口、控件等的handle,因此这种方法截我们想要的部分非常好用。
{
IntPtr hscrdc = GetWindowDC(hWnd);
Control control = Control.FromHandle(hWnd);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
bool re= PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = null;
if(re)
{
bmp = Bitmap.FromHbitmap(hbitmap);
}
DeleteObject(hbitmap);
DeleteDC(hmemdc);//删除用过的对象
ReleaseDC(hWnd, hscrdc);
return bmp;
}
调用非托管函数如下:
[DllImport("gdi32.dll")]
public static extern IntPtr CreateDC(
string lpszDriver, // driver name驱动名
string lpszDevice, // device name设备名
string lpszOutput, // not used; should be NULL
IntPtr lpInitData // optional printer data
);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc); // handle to DC
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(
IntPtr hdc, // handle to DC
int nWidth, // width of bitmap, in pixels
int nHeight // height of bitmap, in pixels
);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(
IntPtr hdc, // handle to DC
IntPtr hgdiobj // handle to object
);
[DllImport("gdi32.dll")]
public static extern int DeleteDC( IntPtr hdc ); // handle to DC
[DllImport("gdi32.dll")]
public static extern IntPtr DeleteObject(IntPtr hObject);
[DllImport("user32.dll")]
public static extern bool PrintWindow(
IntPtr hwnd, // Window to copy,Handle to the window that will be copied.
IntPtr hdcBlt, // HDC to print into,Handle to the device context.
UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values.
);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC( IntPtr hwnd );
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
附:有些平台的截图是全黑的,开启视频加速可能会导致这样的问题,关闭就能正常截图了。