在 c# 中使用 win32 从窗口获取位图:我哪里出错了?
Posted
技术标签:
【中文标题】在 c# 中使用 win32 从窗口获取位图:我哪里出错了?【英文标题】:Getting Bitmap from a window using win32 in c#: Where am I going wrong? 【发布时间】: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。有关使用示例,请参阅 ***.com/a/1163781/56778。 【参考方案1】:改变
image = Image.FromHbitmap(mem);
到
image = Image.FromHbitmap(windowImage);
【讨论】:
以上是关于在 c# 中使用 win32 从窗口获取位图:我哪里出错了?的主要内容,如果未能解决你的问题,请参考以下文章