BitBlt 屏幕截图在 Windows 10 上不起作用 [英] BitBlt screen capture not working on Windows 10

查看:51
本文介绍了BitBlt 屏幕截图在 Windows 10 上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码在后台捕获进程窗口:

I'm using this code to capture a process window in the background:

IntPtr = Process.GetProcessByName("memu")[0].MainWindowHandle;
RECT rc;
GetClientRect(hwnd, out rc);

IntPtr hdcFrom = GetDC(hwnd);
IntPtr hdcTo = CreateCompatibleDC(hdcFrom);

int Width = rc.right;
int Height = rc.bottom;

Bitmap bmp = null;

IntPtr hBitmap = CreateCompatibleBitmap(hdcFrom, Width, Height);
if (hBitmap != IntPtr.Zero) {
   IntPtr hLocalBitmap = SelectObject(hdcTo, hBitmap);

   BitBlt(hdcTo, 0, 0, Width, Height, hdcFrom, 0, 0, CopyPixelOperation.SourceCopy);
   SelectObject(hdcTo, hLocalBitmap);

   DeleteDC(hdcTo);
   ReleaseDC(hwnd, hdcFrom);

   bmp = Image.FromHbitmap(hBitmap);
   DeleteObject(hBitmap);
   return bmp;
}

此代码是捕获一个名为 MEmu 的 Android 模拟器,它使用 DirectX 来呈现内容.但是在 Windows 10 更新到版本 16299 后,此代码停止工作(之前它可以正常工作),它仍然可以在启用 Aero 模式的 Windows 7 上工作.

This code is capture an Android emulator called MEmu, it is using DirectX to render the content. But this code stopped to work after Windows 10 updated to version 16299 (it was working normally before), it still working on Windows 7 with Aero mode enabled.

当我在 Windows 10 Pro v16299.X 中使用此方法时,它只会返回白色图像,或者返回模拟器加载屏幕",而不是运行内容.在 Windows 7 上,如果我删除 Aero 模式,它的行为会相同,捕获加载屏幕",因此看起来新 Windows 10 专业版更新中透明度的工作方式发生了某种变化.

When I use this method in the Windows 10 Pro v16299.X it simply return a white image or it returns the emulator "loading screen", not the running content. On Windows 7, if I remove the Aero mode it will act the same, capturing the "loading screen", so looks like somehow the way the transparency works in the new windows 10 pro update changed.

我已经尝试了所有方法,尝试安装一些模块以强制 Aero 模式在 Windows 10 上运行,尝试 PrintWindow 在后台捕获屏幕,但仍然相同.

I've tried everything, tried install some modules to force Aero Mode to work on Windows 10, tried PrintWindow to capture the screen in the background, but still the same.

任何想法可能会发生什么?还是可能的解决方案?或者在最新的 Windows 10 Pro 版本中发生了哪些可能破坏该代码的变化?

Any ideas what could be happening? Or a possible solution? Or what changed in this last Windows 10 Pro version that could break that code?

谢谢!

推荐答案

对我来说,这适用于 Windows 10 11.02.2021:

For me this is working on Windows 10 11.02.2021:

static void hflipAndSwapRandB(unsigned char* data, int w, int h, int dim)
    {
        int y = 0;
        int x = 0;
        int d;
        unsigned char swap = 0;
        int hh = h / 2;
        for (y = 0; y < hh; y++)
        {
            for (x = 0; x < w; x++)
            {
                for (d = 0; d < dim; d++)
                {
                    swap = data[y * dim * w + dim * x + d];
                    data[y * dim * w + dim * x + d] = data[(h - 1 - y) * dim * w + dim * x + dim - 1 - d];
                    data[(h - 1 - y) * dim * w + dim * x + dim - 1 - d] = swap;
                }
            }
        }
    }

static void copyScreen(unsigned char* pixels_out, int x, int y, int width, int height)
{
    HDC hScreenDC = GetDC(GetDesktopWindow());
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    if (width == -1 || height == -1)
    {
        width = GetDeviceCaps(hScreenDC, HORZRES);
        height = GetDeviceCaps(hScreenDC, VERTRES);
    }

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, x, y, width, height, hScreenDC, x, y, SRCCOPY);
    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
    BITMAPINFOHEADER   bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = width-x;
    bi.biHeight = height-y;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
    GetDIBits(hMemoryDC, hBitmap, 0, height-y, pixels_out, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
    hflipAndSwapRandB(pixels_out, width, height, 3);

    DeleteDC(hMemoryDC);
    DeleteDC(hScreenDC);
    DeleteObject(hBitmap);
}

这篇关于BitBlt 屏幕截图在 Windows 10 上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆