【发布时间】:2014-06-19 08:06:15
【问题描述】:
我需要检索与某个程序关联的所有窗口的屏幕截图。现在我只是想让它在主窗口中工作。
在image = Image.FromHbitmap(mem); 之后,我得到的错误是“GDI+ 中发生一般错误”。我正在尝试按照本教程进行操作
http://www.dreamincode.net/forums/topic/34831-taking-a-screen-shot-in-c%23/
我认为我的指针搞砸了,特别是在这三行:
IntPtr oldBmp = (IntPtr)Win32Stuff.SelectObject(mem, windowImage);
Win32Stuff.BitBlt(mem, 0, 0, windowwidth, windowheight, windowDC, 0, 0, 13369376);
Win32Stuff.SelectObject(mem, oldBmp);
如果我理解正确,oldBmp 和 mem 指向 windowImage,然后 mem 指向 BitBlt 的输出,那么我没有得到现在 mem 指向 oldBmp 的这一行。我尝试将其注释掉,看看这是不是搞砸了,但我得到了同样的一般错误。
这里是完整的代码:
public static class Win32Stuff
{
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("user32.dll", EntryPoint = "GetWindowDC")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("gdi32", EntryPoint = "CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32", EntryPoint = "CreateCompatibleBitmap")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
[DllImport("gdi32", EntryPoint = "SelectObject")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32", EntryPoint = "BitBlt")]
public static extern bool BitBlt(IntPtr hDestDC, int X, int Y, int nWidth, int nHeight, IntPtr hSrcDC, int SrcX, int SrcY, int Rop);
[DllImport("gdi32", EntryPoint = "DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDC);
}
public static void getScreenShot()
{
int windowwidth;
int windowheight;
Bitmap image;
IntPtr windowHandle = Process.GetProcessesByName("firefox")[0].MainWindowHandle;
IntPtr windowDC = Win32Stuff.GetWindowDC(windowHandle);
IntPtr mem = Win32Stuff.CreateCompatibleDC(windowDC);
//need to change this
windowheight = 1920;
windowwidth = 1920;
IntPtr windowImage = Win32Stuff.CreateCompatibleBitmap(windowDC, windowwidth, windowheight);
IntPtr oldBmp = (IntPtr)Win32Stuff.SelectObject(mem, windowImage);
Win32Stuff.BitBlt(mem, 0, 0, windowwidth, windowheight, windowDC, 0, 0, 13369376);
//Win32Stuff.SelectObject(mem, oldBmp);
image = Image.FromHbitmap(mem);
Win32Stuff.DeleteDC(mem);
Win32Stuff.ReleaseDC(windowHandle, mem);
}
我怎样才能看到具体的错误是什么,为什么Image.FromHbitmap() 不能从我的指针输出 GDI 位图?
【问题讨论】:
-
调用API GetLastError() 看看是什么错误
-
所以我像这样调用 GetLastError() `try { image = Image.FromHbitmap(mem); } 捕捉(异常){ uint 错误 = Win32Stuff.GetLastError(); }`,我得到的错误是 5,我认为缓冲区不足。
-
5 被拒绝访问。您正在编写 GUI 应用程序吗?还是后端服务?
-
它将进入一个 GUI 应用程序的客户端。尽管在我为测试而制作的独立控制台应用程序中运行此代码,但我得到了该错误。我还没有在程序中测试过
-
这篇文章展示了如何获取整个屏幕,或者任何窗口。 developerfusion.com/code/4630/capture-a-screen-shot。有关使用示例,请参阅 stackoverflow.com/a/1163781/56778。
标签: c# winapi screenshot gdi user32