2017-10-08 11 views
0

Je voulais automatiser la création de captures d'écran prises avec mon astuce ballon à partir d'une icône de notification, de sorte que pourrait facilement valider l'apparence des différentes langues que mon application prend en charge. Le problème est que la pointe du ballon est absente de la capture d'écran bien qu'elle soit affichée sur l'écran sous Windows 7.capture capture d'écran qui comprend BaloonTip

J'ai essayé avec les solutions de Capture screenshot of active window?, par ex.

// From http://www.developerfusion.com/code/4630/capture-a-screen-shot/ 
var sc = new ScreenCapture(); 
trayIcon.ShowBalloonTip(10000, "My Title", "My message", ToolTipIcon.Info); 
Thread.Sleep(2000); // Just to make sure that the balloon tip is shown 
sc.CaptureScreenToFile("MyScreenshot.png", ImageFormat.Png); 

et

Rectangle bounds = Screen.GetBounds(Point.Empty); 
using(Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) 
{ 
    using(Graphics g = Graphics.FromImage(bitmap)) 
    { 
     trayIcon.ShowBalloonTip(10000, "My Title", "My message", ToolTipIcon.Info); 
     Thread.Sleep(2000); // Just to make sure that the balloon tip is shown 
     g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); 
    } 
    bitmap.Save("MyScreenshot.png", ImageFormat.Png); 
} 

Mais les deux prennent des captures d'écran sans montrer la pointe du ballon. Alors, existe-t-il un moyen de prendre une capture d'écran par programme qui inclut des conseils de ballon?

Informations sur le bonus: Sur Windows 10, la bulle est forcée dans le système de notification normal et la capture d'écran de ce travail fonctionne comme prévu.

+1

Vous devez ajouter CopyPixelOperation.CaptureBlt de sorte que vous pourrez également capturer fenêtres en couches. –

+0

@HansPassant Cela a fonctionné! Avec votre suggestion, j'ai été en mesure de trouver cette réponse https://stackoverflow.com/questions/3072349/capture-screenshot-including-semitransparent-windows-in-net qui résout mon problème. –

Répondre

1

Comme le mentionne Hans Passant dans une commuté à la question, l'utilisation de CopyPixelOperation.CaptureBlt est la clé de la solution.

Comme cela n'a pas fonctionné avec les solutions que j'ai déjà essayées j'ai trouvé une question similaire Capture screenshot Including Semitransparent windows in .NET, qui traite des fenêtres semi-transparentes.

All-in-toutes les solutions qui me permet de prendre une capture d'écran qui comprend la pointe du ballon à partir d'une icône de notification ressemble à ceci:

class ScreenCapture 
{ 
    public void CaptureScreenToFile(string fileName) 
    { 
     Size sz = Screen.PrimaryScreen.Bounds.Size; 
     IntPtr hDesk = GetDesktopWindow(); 
     IntPtr hSrce = GetWindowDC(hDesk); 
     IntPtr hDest = CreateCompatibleDC(hSrce); 
     IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height); 
     IntPtr hOldBmp = SelectObject(hDest, hBmp); 
     bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); 
     Bitmap bmp = Bitmap.FromHbitmap(hBmp); 
     SelectObject(hDest, hOldBmp); 
     DeleteObject(hBmp); 
     DeleteDC(hDest); 
     ReleaseDC(hDesk, hSrce); 
     bmp.Save(fileName); 
     bmp.Dispose(); 
    } 

    // P/Invoke declarations 
    [DllImport("gdi32.dll")] 
    static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int 
     wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop); 
    [DllImport("user32.dll")] 
    static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc); 
    [DllImport("gdi32.dll")] 
    static extern IntPtr DeleteDC(IntPtr hDc); 
    [DllImport("gdi32.dll")] 
    static extern IntPtr DeleteObject(IntPtr hDc); 
    [DllImport("gdi32.dll")] 
    static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); 
    [DllImport("gdi32.dll")] 
    static extern IntPtr CreateCompatibleDC(IntPtr hdc); 
    [DllImport("gdi32.dll")] 
    static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetDesktopWindow(); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr ptr); 
}