2016-07-25 116 views
2

我试图捕捉使用我总是PrintWindowPrintWindow闪烁

​​

的问题是,在这个特定的游戏进程窗口得到空白的真快,当它调用Printwindow功能使用方法的窗口,所以有时保存的图像完全是白色的。

所以我试图用的BitBlt:

Bitmap bmp = new Bitmap(rc.right, rc.bottom, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
Graphics gfxBmp = Graphics.FromImage(bmp); 
IntPtr dest = gfxBmp.GetHdc(); 
IntPtr source = GetWindowDC(hwnd); 

BitBlt(dest, 0, 0, rc.width, rc.height, source, 0, 0, 13369376); 
bmp.Save("test.png"); 

但是,使用保存的图像上面的代码完全是黑色的。

有什么办法可以防止PrintWindow使流程窗口轻弹“白色层”?如果BitBtl无法解决这个问题,对吗?但是我的代码有什么问题?

谢谢

+0

这是WPF的winforms吗?在winforms中,你可以画一个图像,最后只是重画最后的图像到屏幕上,从本质上缓冲图形。在WPF中,你可以做同样的事情,但取决于你尝试做什么有不同的方法。像BitMapCahcedBrush让你直接从硬件渲染。 – noone392

+1

@noone392:问题是询问有关捕获另一个应用程序的窗口内容。 – IInspectable

+0

你能否使用其他工具成功截取屏幕截图,例如截取工具? – andlabs

回答

1

你可以尝试使用这段代码,它是为我工作。如果您仍然看到黑色图像,可能需要使用DWM解决方案。

public Bitmap CaptureWindowImage(IntPtr hWnd) 
    { 
     IntPtr hWndDc = GetDC(hWnd); 
     IntPtr hMemDc = CreateCompatibleDC(hWndDc); 
     IntPtr hBitmap = CreateCompatibleBitmap(hWndDc, window.Rectangle.Width, window.Rectangle.Height); 
     SelectObject(hMemDc, hBitmap); 

     BitBlt(hMemDc, 0, 0, window.Rectangle.Width, window.Rectangle.Height, hWndDc, 0, 0, TernaryRasterOperations.SRCCOPY); 
     Bitmap bitmap = Bitmap.FromHbitmap(hBitmap); 

     DeleteObject(hBitmap); 
     ReleaseDC(window.hWnd, hWndDc); 
     ReleaseDC(IntPtr.Zero, hMemDc); 

     return bitmap; 
    } 

    private enum TernaryRasterOperations : uint 
    { 
     /// <summary>dest = source</summary> 
     SRCCOPY = 0x00CC0020, 
     /// <summary>dest = source OR dest</summary> 
     SRCPAINT = 0x00EE0086, 
     /// <summary>dest = source AND dest</summary> 
     SRCAND = 0x008800C6, 
     /// <summary>dest = source XOR dest</summary> 
     SRCINVERT = 0x00660046, 
     /// <summary>dest = source AND (NOT dest)</summary> 
     SRCERASE = 0x00440328, 
     /// <summary>dest = (NOT source)</summary> 
     NOTSRCCOPY = 0x00330008, 
     /// <summary>dest = (NOT src) AND (NOT dest)</summary> 
     NOTSRCERASE = 0x001100A6, 
     /// <summary>dest = (source AND pattern)</summary> 
     MERGECOPY = 0x00C000CA, 
     /// <summary>dest = (NOT source) OR dest</summary> 
     MERGEPAINT = 0x00BB0226, 
     /// <summary>dest = pattern</summary> 
     PATCOPY = 0x00F00021, 
     /// <summary>dest = DPSnoo</summary> 
     PATPAINT = 0x00FB0A09, 
     /// <summary>dest = pattern XOR dest</summary> 
     PATINVERT = 0x005A0049, 
     /// <summary>dest = (NOT dest)</summary> 
     DSTINVERT = 0x00550009, 
     /// <summary>dest = BLACK</summary> 
     BLACKNESS = 0x00000042, 
     /// <summary>dest = WHITE</summary> 
     WHITENESS = 0x00FF0062 
    } 

    [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)] 
    static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 

    [DllImport("gdi32.dll")] 
    private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); 

    [DllImport("gdi32.dll", SetLastError = true)] 
    private static extern IntPtr CreateCompatibleDC(IntPtr hdc); 

    [DllImport("gdi32.dll")] 
    private static extern bool DeleteObject(IntPtr hObject); 

    [DllImport("gdi32.dll")] 
    private static extern IntPtr CreateBitmap(int nWidth, int nHeight, uint cPlanes, uint cBitsPerPel, IntPtr lpvBits); 

    [DllImport("user32.dll")] 
    private static extern IntPtr GetDC(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 

    [DllImport("gdi32.dll")] 
    private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);