我的应用程序需要以编程方式截取缩放窗口的屏幕截图。我使用标准 Windows API 调用实现了这一点:
Hdc hdcWindow = GetWindowDC(hwnd);
Hdc hdcMemDC = CreateCompatibleDC(hdcWindow);
var windowRect = new Rect();
GetWindowRect(hwnd, ref windowRect);
int width = windowRect.Right - windowRect.Left;
int height = windowRect.Bottom - windowRect.Top;
var hbmScreen = CreateCompatibleBitmap(hdcWindow, width, height);
var hOld = SelectObject(hdcMemDC, hbmScreen);
//tried this
BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
//also tried this
PrintWindow(hwnd, hdcMemDC, 0);
//and this
// Send WM_PRINT message to the window to have it print to the memory dc
SendMessage(hwnd, WM_PRINT, hdcMemDC, (IntPtr)(PRF_CHILDREN | PRF_CLIENT | PRF_NONCLIENT));
//get the bitmap
var bmp = System.Drawing.Bitmap.FromHbitmap(hbmScreen);
//clean up
SelectObject(hdcMemDC, hOld);
DeleteObject(hbmScreen);
DeleteDC(hdcMemDC);
ReleaseDC(hwnd, hdcWindow);
return bmp;
发生的情况是,我确实获得了缩放窗口的屏幕截图,但我没有获得视频,而是获得了窗口框架,但窗口客户区是当时后面的任何内容:
在本例中,我碰巧让 Visual Studio 在“缩放”窗口后面运行,因此您可以看到标题栏和“缩放”控件,但您看到的不是视频,而是 VS 窗口。我每次都会得到这个图像,直到我重新启动新的 Zoom 会话。
我认为 Zoom 的窗口化可能做了一些非标准的事情,那么我怎样才能截取它的屏幕截图?
它不是尝试捕获窗口本身,而是捕获整个桌面窗口,然后将其裁剪到缩放窗口的位置和大小,这可以通过普通方法获得。这样做已经足够满足我此时的需求了。