2016-07-25 115 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);