Я пытаюсь сделать снимки экрана с помощью функции BitBlt. Однако каждый раз, когда я делаю снимок экрана, область, не относящаяся к клиенту, НИКОГДА не меняется, независимо от того, что я делаю. Как будто он получает какую-то кешированную копию. Клиентская область захвачена правильно.
Если я закрою, а затем снова открою окно и сделаю снимок экрана, область, не являющаяся клиентом, будет захвачена как есть. Любые последующие захваты после перемещения / изменения размера окна не влияют на захваченный снимок экрана. Опять же, клиентская область будет правильной.
Кроме того, флаг CAPTUREBLT, похоже, абсолютно ничего не делает. Я не замечаю никаких изменений с этим или без него. Вот мой код захвата:
QPixmap WindowManagerUtils::grabWindow(WId windowId, GrabWindowFlags flags, int x, int y, int w, int h)
{
RECT r;
switch (flags)
{
case WindowManagerUtils::GrabWindowRect:
GetWindowRect(windowId, &r);
break;
case WindowManagerUtils::GrabClientRect:
GetClientRect(windowId, &r);
break;
case WindowManagerUtils::GrabScreenWindow:
GetWindowRect(windowId, &r);
return QPixmap::grabWindow(QApplication::desktop()->winId(), r.left, r.top, r.right - r.left, r.bottom - r.top);
case WindowManagerUtils::GrabScreenClient:
GetClientRect(windowId, &r);
return QPixmap::grabWindow(QApplication::desktop()->winId(), r.left, r.top, r.right - r.left, r.bottom - r.top);
default:
return QPixmap();
}
if (w < 0)
{
w = r.right - r.left;
}
if (h < 0)
{
h = r.bottom - r.top;
}
#ifdef Q_WS_WINCE_WM
if (qt_wince_is_pocket_pc())
{
QWidget *widget = QWidget::find(winId);
if (qobject_cast<QDesktopWidget*>(widget))
{
RECT rect = {0,0,0,0};
AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0);
int magicNumber = qt_wince_is_high_dpi() ? 4 : 2;
y += rect.top - magicNumber;
}
}
#endif
// Before we start creating objects, let's make CERTAIN of the following so we don't have a mess
Q_ASSERT(flags == WindowManagerUtils::GrabWindowRect || flags == WindowManagerUtils::GrabClientRect);
// Create and setup bitmap
HDC display_dc = NULL;
if (flags == WindowManagerUtils::GrabWindowRect)
{
display_dc = GetWindowDC(NULL);
}
else if (flags == WindowManagerUtils::GrabClientRect)
{
display_dc = GetDC(NULL);
}
HDC bitmap_dc = CreateCompatibleDC(display_dc);
HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h);
HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
// copy data
HDC window_dc = NULL;
if (flags == WindowManagerUtils::GrabWindowRect)
{
window_dc = GetWindowDC(windowId);
}
else if (flags == WindowManagerUtils::GrabClientRect)
{
window_dc = GetDC(windowId);
}
DWORD ropFlags = SRCCOPY;
#ifndef Q_WS_WINCE
ropFlags = ropFlags | CAPTUREBLT;
#endif
BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, ropFlags);
// clean up all but bitmap
ReleaseDC(windowId, window_dc);
SelectObject(bitmap_dc, null_bitmap);
DeleteDC(bitmap_dc);
QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap);
DeleteObject(bitmap);
ReleaseDC(NULL, display_dc);
return pixmap;
}
Большая часть этого кода взята из функции Qt QWidget :: grabWindow, так как я хотел внести некоторые изменения, чтобы она была более гибкой. Документация Qt гласит:
Функция grabWindow () захватывает пиксели
с экрана, а не из окна,
т.е. если есть другое окно
частично или полностью над той, которую вы
захватить, вы получите пиксели от
вышележащее окно тоже.
Однако, я испытываю противоположное ... независимо от флага CAPTUREBLT. Я перепробовал все, что мог придумать ... ничего не работает. Есть идеи?