如何获得屏幕截图,包括调用窗口(在XP)(How to get screenshot to incl

2019-06-23 18:58发布

我有一些代码需要一个屏幕截图...

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的一个问题。

Answer 1:

窗体的不透明度属性设置为100,然后右键单击TransparencyKey属性,然后选择重置。 这可确保您的窗口不再是一个分层的窗口,并不会从截图中失踪。

如果你想保持这些属性,那么你就必须解决中的错误在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);
    }
}


文章来源: How to get screenshot to include the invoking window (on XP)
标签: c# screenshot