我使用此代码在后台捕获进程窗口:
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上仍然可以工作。
当我在 Windows 10 Pro v16299.X 中使用此方法时,它仅返回白色图像或返回模拟器“加载屏幕”,而不是运行内容。在 Windows 7 上,如果我删除 Aero 模式,它会执行相同的操作,捕获“加载屏幕”,因此看起来透明度在新的 Windows 10 Pro 更新中的工作方式发生了变化。
我已经尝试了一切,尝试安装一些模块以强制 Aero 模式在 Windows 10 上工作,尝试 PrintWindow 在后台捕获屏幕,但仍然相同。
你知道会发生什么吗?或者一个可能的解决方案?或者最后一个 Windows 10 专业版中发生了什么变化可能会破坏该代码?
谢谢!
最佳答案
对我来说,这适用于 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);
}
关于c# - BitBlt 屏幕捕获在 Windows 10 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47801997/