navegador limpiar imagenes evitar cache borrar c++ windows qt screen-capture

c++ - limpiar - BitBlt ignora CAPTUREBLT y parece que siempre captura una copia en caché del objetivo



evitar cache html (2)

Su confusión acerca de BitBlt con comportamiento CAPTUREBLT proviene del hecho de que la documentación oficial de BitBlt no es clara y engañosa.

Se afirma que
"CAPTUREBLT: incluye todas las ventanas que están superpuestas en la parte superior de la ventana en la imagen resultante. De forma predeterminada, la imagen solo contiene su ventana".

Lo que realmente significa (al menos para cualquier sistema operativo Windows sin Aero habilitado) "CAPTUREBLT - Incluye ventanas en capas (!) (Vea WS_EX_LAYERED estilo de ventana extendida) que se superponen a su ventana. Las ventanas no superpuestas que se superponen a su ventana nunca se incluyen."

Windows sin WS_EX_LAYERED estilo de ventana extendida que se superpone a su ventana no se incluye con o sin indicador CAPTUREBLT (al menos para cualquier sistema operativo Windows sin Aero habilitado).

Los desarrolladores de QT también malinterpretaron la documentación de BitBlt / CAPTUREBLT, por lo que la documentación de QT es realmente incorrecta sobre el comportamiento de QPixmap :: grabWindow en la plataforma WIN32 sin Aero habilitado.

AÑADIR:

Si desea capturar su ventana tal como está en la pantalla, debe capturar todo el escritorio con el indicador CAPTUREBLT y luego extraer el rectángulo con su ventana. (Los desarrolladores de QT deberían hacer lo mismo). Funcionará correctamente en ambos casos: con y sin Aero habilitado / disponible.

Estoy tratando de capturar capturas de pantalla usando la función BitBlt. Sin embargo, cada vez que capturo una captura de pantalla, el área que no es cliente NUNCA cambia independientemente de lo que haga. Es como si estuviese recibiendo una copia en caché. El área del cliente se captura correctamente.

Si cierro y luego vuelvo a abrir la ventana, y tomo una captura de pantalla, el área que no es cliente se capturará tal como está. Las capturas subsiguientes después de mover / cambiar el tamaño de la ventana no tienen ningún efecto en la captura de pantalla capturada. Nuevamente, el área del cliente será correcta.

Además, la bandera CAPTUREBLT parece no hacer absolutamente nada. Noto que no hay cambios con o sin él. Aquí está mi código de captura:

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; }

La mayor parte de este código proviene de la función QWidget :: grabWindow de Qt, ya que quería hacer algunos cambios para que fuera más flexible. La documentación de Qt indica que:

La función grabWindow () toma los píxeles de la pantalla, no de la ventana, es decir, si hay otra ventana parcial o totalmente sobre la que captas, también obtienes píxeles de la ventana superior.

Sin embargo, experimento exactamente lo contrario ... independientemente de la bandera de CAPTUREBLT. He intentado todo lo que puedo pensar ... nada funciona. ¿Algunas ideas?


Capturo toda la pantalla y obtengo los mismos resultados ... :(

const uint SRCCOPY = 0x00CC0020; //SRCCOPY const uint CAPTUREBLT = 0x00CC0020 | 0x40000000; //CAPTUREBLT bool dv = BitBlt(hCaptureDC, 0, 0, Bounds.Width, Bounds.Height, hDesktopDC, Bounds.Left, Bounds.Top, _with_tooltips ? CAPTUREBLT : SRCCOPY);