Моя программа делает скриншоты других окон приложений, чтобы автоматизировать некоторые задачи на них.Эти окна могут время от времени скрываться за кадром или скрываться другими окнами.
Чтобы уменьшить беспорядок, я удалил любую проверку ошибок из списков кода.Я готовлю скриншоты обоих типов с
// Get size of the target window.
RECT clientRect;
GetClientRect(hwnd, &clientRect);
int width = clientRect.right - clientRect.left;
int height = clientRect.bottom - clientRect.top;
// Create a memory device context.
HDC windowDC = GetDC(hwnd);
HDC memoryDC = CreateCompatibleDC(windowDC);
// Create a bitmap for rendering.
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = width * height * 4;
RGBQUAD* buffer;
HBITMAP bitmap = CreateDIBSection(windowDC, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, 0, 0);
HGDIOBJ previousObject = SelectOBject(memoryDC, bitmap);
, затем снимаю скриншоты либо с
PrintWindow(hwnd, memoryDC, PW_CLIENTONLY);
GdiFlush();
, либо с
UpdateWindow(hwnd);
BitBlt(memoryDC, 0, 0, width, height, windowDC, 0, 0, SRCCOPY);
GdiFlush();
, затем копируюсодержимое буфера для вектора
std::vector<RGBQUAD> pixels;
pixels.resize(width * height, { 0, 0, 0, 0 });
memcpy(&pixels[0], buffer, bitmapInfo.bmiHeader.biSizeImage);
и, наконец, я все очищаю с помощью
ReleaseDC(hwnd, windowDC);
SelectObject(memoryDC, previousObject);
DeleteDC(memoryDC);
DeleteObject(bitmap);
У меня есть три вопроса по поводу кода выше:
- Мне нужно позвонить
GdiFlush()
?Я прочитал документацию и провел некоторые исследования в Google, но я все еще не уверен, имеет ли смысл звонить или нет. - Имеет ли смысл звонок на
UpdateWindow()
прямо перед BitBlt()
?Помогает ли это, чтобы содержимое контекста устройства было «более современным»? - Прав ли я, предполагая, что для
PrintWindow()
вся работа выполняется из целевого приложения (увеличение ЦП целевого приложения)использование), в то время как BitBlt()
полностью выполняется из вызывающего потока (таким образом увеличивая использование ЦП моего собственного приложения)? - При каких обстоятельствах может произойти сбой любой из вышеперечисленных функций?Я знаю, что
BitBlt()
работает только для скрытых окон, если включена Композиция рабочего стола (DWM), но в очень небольшом наборе систем (Windows 8/10) BitBlt()
и PrintWindow()
не работают для окон, для которых они работают.просто отлично в других системах (хотя DWM включен).Хотя я не смог найти никаких примеров того, почему.
Любая информация приветствуется, спасибо.