捕获包含BaloonTip的截图

时间:2017-10-08 19:18:47

标签: c# screenshot

我想通过通知图标自动创建使用我的气球提示截取的屏幕截图,这样可以轻松验证我的应用程序支持的不同语言的外观。问题是屏幕截图中没有气球提示,尽管它在Windows 7的屏幕上显示。

我尝试过Capture screenshot of active window?的解决方案,例如

// 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);

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);
}

但是两个都没有显示气球提示截图。那么,有没有办法以编程方式拍摄包含气球提示的屏幕截图?

奖励信息:在Windows 10上,气球提示被强制进入正常通知系统,并按预期截取此屏幕截图。

1 个答案:

答案 0 :(得分:1)

正如Hans Passant在问题中提到的那样,使用CopyPixelOperation.CaptureBlt是解决方案的关键。

由于它与我已经尝试的解决方案不兼容,我发现了一个类似的问题Capture screenshot Including Semitransparent windows in .NET,它涉及半透明窗口。

所有这些解决方案让我能够从通知图标中截取包含气球提示的屏幕截图,如下所示:

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);
}