【问题标题】:CreateCompatibleBitmap returns Overlapped I/O Operation Is In ProgressCreateCompatibleBitmap 返回重叠的 I/O 操作正在进行中
【发布时间】:2013-01-17 03:25:49
【问题描述】:

这是一个相当标准的使用BitBlt的屏幕截图功能,可以在网上找到:

主要功能:

while(true)
{
    printscreen = GetDesktopImage(X, Y, secMonitorSize.Width, secMonitorSize.Height);
    Thread.Sleep(1000);
}

捕获桌面功能:

public Bitmap GetDesktopImage(int X, int Y, int width, int height)
{
    IntPtr hDC = WIN32_API.GetDC(WIN32_API.GetDesktopWindow());
    IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);
    IntPtr m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, width, height);

    if (m_HBitmap != IntPtr.Zero)
    {
        IntPtr hOld = (IntPtr)WIN32_API.SelectObject(hMemDC, m_HBitmap);
        WIN32_API.BitBlt(hMemDC, 0, 0, width, height, hDC, X, Y, WIN32_API.SRCCOPY | WIN32_API.CAPTURE_BLT);

        WIN32_API.SelectObject(hMemDC, hOld);
        WIN32_API.DeleteDC(hMemDC);
        WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);

        Bitmap printscreen = System.Drawing.Image.FromHbitmap(m_HBitmap);
        WIN32_API.DeleteObject(m_HBitmap);

        return printscreen;
    }

    return null;
}

问题是代码运行正常大约 20 分钟,然后 CreateCompatibleBitmap 将继续返回 0。在 CreateCompatibleBitmap 上使用 setlasterror=true,它会显示错误代码 997(重叠 I/O 操作正在进行中)。

只有赛门铁克在后台运行。任何人都知道如何开始故障排除?

【问题讨论】:

  • 你的逻辑有点搞砸了 - 如果 CreateCompatibleBitmap 成功,你只会删除/释放 DC,而 GetDC/CreateCompatibleDC 可能成功而位图没有。
  • Okie,所以我应该输入“WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);”和“WIN32_API.DeleteDC(hMemDC);”在 if 条件之外?
  • 是的,但您也应该检查它们是否成功。
  • 对不起,我该如何检查? >.

标签: c# winapi screen-capture


【解决方案1】:

GDI 函数不使用 GetLastError(),因此使用 setlasterror=true 会报告早期 API 调用的错误。

试试这个:

public Bitmap GetDesktopImage(int X, int Y, int width, int height)
{
    Bitmap printscreen = null;

    IntPtr hWnd = WIN32_API.GetDesktopWindow();
    IntPtr hDC = WIN32_API.GetDC(hWnd);
    if (hDC != IntPtr.Zero)
    { 
        IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);
        if (hMemDC != IntPtr.Zero)
        {
            IntPtr m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, width, height);
            if (m_HBitmap != IntPtr.Zero)
            {
                IntPtr hOld = (IntPtr)WIN32_API.SelectObject(hMemDC, m_HBitmap);
                WIN32_API.BitBlt(hMemDC, 0, 0, width, height, hDC, X, Y, WIN32_API.SRCCOPY | WIN32_API.CAPTURE_BLT);
                WIN32_API.SelectObject(hMemDC, hOld);

                printscreen = System.Drawing.Image.FromHbitmap(m_HBitmap);
                WIN32_API.DeleteObject(m_HBitmap);
            }

            WIN32_API.DeleteDC(hMemDC);
        }

        WIN32_API.ReleaseDC(hWnd, hDC);
    }

    return printscreen;
}

【讨论】:

  • 首先非常感谢您的努力和回复!我已经实现了你的代码,现在 CreateCompatibleDC 是一个不断返回 0 的代码……hDC 是一个非常大的负数,它 (hDC) 应该是这样的吗?知道如何继续进行故障排除吗?
猜你喜欢
  • 1970-01-01
  • 2015-05-09
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多