如何获得的截图,包括调用窗口(在XP) [英] How to get screenshot to include the invoking window (on XP)
问题描述
我有一些代码需要一个屏幕截图...
I have code that takes a 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事实并非如此。我想的形象始终包括
调用进程/窗口的像素。任何线索我怎么可以强制使用
On W7, the resulting image includes the pixels of the calling window; but on XP it does not. I would like the image to always include the pixels of the calling process/window. Any clue how I can force this?
UPDATE1:
我做这个更多的实验,并作为一个结果,我M更困惑...
我把上面的代码并创建了一个完全独立的应用程序,以便有这一点,我最初是从启动它的应用程序之间没有任何关系。
奇怪的是,我仍然没有看到的截图该应用程序的窗口。
所以现在我有做的截图和我想包括在截图的窗口过程之间没有任何关系;然而,仍然没有被纳入该窗口。
我也尝试了PRNT-SCRN按钮,并确实包括窗口。
请注意,这仅仅是在XP的一个问题。
UPDATE1: I've done more experimentation with this, and as a result I'm more confused... I took the above code and created a totally separate application so that there is no relationship between this and the application that I was originally launching it from. Strangely enough, I am STILL not seeing the window of that application in the screenshot. So now I have no relationship between the process doing the screenshot and the window that I want included in the screenshot; yet, that window is still not included. I did try the PRNT-SCRN button and that does include the window. Note that this is only a problem on XP.
推荐答案
窗体的不透明度属性设置为100,然后右键单击TransparencyKey属性,然后选择重置。这可以确保你的窗口不再是一个分层的窗口,并不会从截图中丢失。
Set your form's Opacity property to 100 and right-click the TransparencyKey property and select Reset. That ensures that your window is no longer a layered window and won't be missing from the screenshot.
如果你想保持这些属性,那么你就必须上班各地在Graphics.CopyFromScreen一个bug()。使用CopyPixelOperation与CaptureBlt操作过载,需要捕捉分层窗口。但是,将无法正常工作,由于在参数验证代码中的错误。解决方法是不漂亮,但功能:
If you want to keep these properties then you'll have to work around in a bug in Graphics.CopyFromScreen(). The overload that uses CopyPixelOperation with the CaptureBlt operation is required to capture layered windows. But won't work due to a bug in the argument validation code. The workaround isn't pretty but functional:
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);
}
}
这篇关于如何获得的截图,包括调用窗口(在XP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!