Durante la cattura manualmente una finestra con il Print Screen
+ Alt
combinazione di tasti, ottengo il seguente:bitmap PrintWindow differisce da PrintScreen bitmap Key
ma se cerco di farlo a livello di codice utilizzando Windows API, ottengo questo:
Perché la discrepanza? Come ottengo il primo al livello di programmazione?
Ecco il mio codice:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
public Bitmap PrintWindow()
{
Bitmap bmp = new Bitmap(windowRect.Width, windowRect.Height, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
bool success = PrintWindow(windowHandle, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
if (!success)
{
Console.WriteLine("Error copying image");
Console.WriteLine(getLastError());
}
gfxBmp.Dispose();
return bmp;
}
Aggiornamento: Farlo con BitBlt fa la stessa cosa.
Ecco code from CodeProject che restituisce ancora un'immagine in bianco mascherata:
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle,ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,width,height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest,hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
// restore selection
GDI32.SelectObject(hdcDest,hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle,hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
img.Save("SampleImage.png");
return img;
}
Ho provato molte combinazioni di CopyPixelOperation
, (da qualche parte circa 15.000 del 131.000), ma ancora non funziona.
Utilizzo di Windows 8, AMD Radeon HD 6870.
Update 2
Sembra che la finestra è trasparente, permettendo il colore blu della finestra per sanguinare attraverso. Quando cambio il colore della finestra in nero (usando la finestra di dialogo di personalizzazione di Windows), ottengo qualcosa di simile alla seconda finestra. Il confine manca ancora.
Non ho trovato una soluzione, ma è la comprensione del problema.
Quando hai chiamato 'PrintWindow()', come hai prodotto la DC che hai inviato alla chiamata API? – WhozCraig
aggiunto codice al corpo. – Jason
Cosa ottieni se usi 'PixelFormat.Format24bppRgb'? –