2009-12-07 10 views
3

C'est une question de suivi à this questionEnregistrement d'une capture d'écran d'une fenêtre en utilisant C#, WPF et DWM

La solution au ci-dessus utilise DWM pour afficher une miniature d'une fenêtre active. Si je comprends bien, cela fonctionne en vous permettant de spécifier le handle de fenêtre de l'application que vous voulez afficher et en vous munissant d'un handle de fenêtre et d'un emplacement sur cette fenêtre où windows doit dessiner le contenu de la fenêtre cible.

Y at-il un moyen de rendre la capture d'écran de fenêtre directement à BitmapImage ou Image au lieu de dessiner directement quelque part dans votre fenêtre? (Fondamentalement pour saisir une capture d'écran de la fenêtre - même si elle est couverte par une autre fenêtre - sans utiliser une vignette de mise à jour.)

Merci pour votre aide!

+0

fusion complète. –

Répondre

2

Utilisez Control.DrawToBitmap Method

Image img = myForm.DrawToBitmap(); 
Image img = myPanel.DrawToBitmap(); 
+0

Merci pour votre réponse. Cela ne nécessiterait-il pas que la capture d'écran soit d'abord dessinée sur l'écran puis sauvegardée? Y at-il un moyen de capturer la capture d'écran d'une fenêtre directement à un objet (comme Image) sans avoir à le dessiner sur l'écran en premier? – Evan

+0

DrawToBitmap obtient un bitmap comme vous le faites lorsque vous appuyez sur le bouton PrintScreen (sur le formulaire ou pour le panneau uniquement). Je ne suis pas sûr si le formulaire ou le panneau devrait ou ne pas être vraiment affiché sur l'écran, avec les panneaux visibles est sûrement des travaux, je crois avec le caché devrait fonctionner aussi. Bitmap bm = new Bitmap (wid, hgt); 'dessiner le formulaire en cours à l'image bitmap this.DrawToBitmap (bm, nouveau Rectangle (0, 0, wid, hgt)) – serhio

9

Le Control.DrawToBitmap ne je travaille pas toujours eu recours aux appels d'API natives suivantes qui fournissent des résultats plus cohérents:

La classe Utilities. Appel Utilities.CaptureWindow (Control.Handle) pour capturer un contrôle spécifique:

public static class Utilities 
{ 
    public static Image CaptureScreen() 
    { 
     return CaptureWindow(User32.GetDesktopWindow()); 
    } 

    public static Image CaptureWindow(IntPtr handle) 
    { 

     IntPtr hdcSrc = User32.GetWindowDC(handle); 

     RECT windowRect = new RECT(); 
     User32.GetWindowRect(handle, ref windowRect); 

     int width = windowRect.right - windowRect.left; 
     int height = windowRect.bottom - windowRect.top; 

     IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); 
     IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); 

     IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); 
     Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY); 
     Gdi32.SelectObject(hdcDest, hOld); 
     Gdi32.DeleteDC(hdcDest); 
     User32.ReleaseDC(handle, hdcSrc); 

     Image image = Image.FromHbitmap(hBitmap); 
     Gdi32.DeleteObject(hBitmap); 

     return image; 
    } 
} 

La classe gdi32:

public class Gdi32 
{ 
    [DllImport("gdi32.dll")] 
    public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 
    [DllImport("gdi32.dll")] 
    public static extern bool DeleteDC(IntPtr hDC); 
    [DllImport("gdi32.dll")] 
    public static extern bool DeleteObject(IntPtr hObject); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 
} 

La classe User32:

public static class User32 
{ 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetDesktopWindow(); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr hWnd); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 
    [DllImport("user32.dll")] 
    public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); 
} 

Les constantes utilisées:

public const int SRCCOPY = 13369376; 

T il struct utilisé:

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 

Une méthode conviviale d'extension de commande:

public static class ControlExtensions 
{ 
    public static Image DrawToImage(this Control control) 
    { 
     return Utilities.CaptureWindow(control.Handle); 
    } 
} 
+0

Cela a été utile, mais j'ai posté une question de suivi ici: http://stackoverflow.com/questions/2322217/get-window-screenshots-mais-text-portions-are-transparent –

+0

super, c'est un super code rapide. Mais les contrôles wpf n'a pas de poignée :( – Andreas