如何获取截图以包含调用窗口(在XP上)

时间:2012-04-19 16:58:57

标签: c# screenshot

我的代码需要截图...

Size ssSize;
int ssX, ssY, ssWidth, ssHeight;
Bitmap thisScreenshot;
Graphics gfxScreenshot;

public Image Screenshot()
{
ssX = Screen.PrimaryScreen.Bounds.X;
ssY = Screen.PrimaryScreen.Bounds.Y;
ssWidth = Screen.PrimaryScreen.Bounds.Width;
ssHeight = Screen.PrimaryScreen.Bounds.Height;
ssSize = Screen.PrimaryScreen.Bounds.Size;
thisScreenshot = new Bitmap(ssWidth,ssHeight);
gfxScreenshot = Graphics.FromImage(thisScreenshot);
return((Image)gfxScreenshot.CopyFromScreen(ssX, ssY, 0, 0, ssSize));
}

在W7上,生成的图像包括调用窗口的像素; 但在XP上却没有。我希望图像始终包含像素 调用进程/窗口。我有什么想法强迫这个吗?

UPDATE1: 我已经做了更多的实验,结果我更加困惑...... 我使用了上面的代码并创建了一个完全独立的应用程序,因此它与我最初启动它的应用程序之间没有任何关系。 奇怪的是,我仍然没有在屏幕截图中看到该应用程序的窗口。 所以现在我做截图的过程和我想要包含在屏幕截图中的窗口之间没有任何关系;然而,那个窗口仍未包括在内。 我确实尝试过PRNT-SCRN按钮,其中包括窗口。 请注意,这只是XP上的一个问题。

1 个答案:

答案 0 :(得分:4)

将表单的Opacity属性设置为100,然后右键单击TransparencyKey属性并选择Reset。这可确保您的窗口不再是分层窗口,并且不会从屏幕截图中遗漏。

如果你想保留这些属性,那么你将不得不解决Graphics.CopyFromScreen()中的一个错误。捕获分层窗口需要使用CopyPixelOperation和CaptureBlt操作的重载。但由于参数验证代码中的错误,无法工作。解决方法不是很好但功能正常:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e) {
            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(@"c:\temp\test.png");
            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);
    }
}