¿Copiar contenido de una ventana oculta o recortada en XP?

4 minutos de lectura

Necesito copiar el contenido de una ventana (BitBlt) que está oculta, a otra ventana. El problema es que una vez que oculto la ventana de origen, el contexto del dispositivo que obtuve ya no se pinta.

Lo que necesitas es el ImprimirVentana función que está disponible en Win32 API desde Windows XP. Si necesita que funcione con versiones anteriores de Windows, puede probar WM_IMPRIMIRaunque nunca he sido capaz de hacerlo funcionar.

hay un buen articulo aquí que muestra cómo usar PrintWindow, y aquí está el fragmento de código relevante de ese artículo:

// Takes a snapshot of the window hwnd, stored in the memory device context hdcMem
HDC hdc = GetWindowDC(hwnd);
if (hdc)
{
    HDC hdcMem = CreateCompatibleDC(hdc);
    if (hdcMem)
    {
        RECT rc;
        GetWindowRect(hwnd, &rc);

        HBITMAP hbitmap = CreateCompatibleBitmap(hdc, RECTWIDTH(rc), RECTHEIGHT(rc));
        if (hbitmap)
        {
            SelectObject(hdcMem, hbitmap);

            PrintWindow(hwnd, hdcMem, 0);

            DeleteObject(hbitmap);
        }
        DeleteObject(hdcMem);
    }
    ReleaseDC(hwnd, hdc);
}

Debería tener algún código de Python que use wxPython para lograr lo mismo. Déjame una nota si lo quieres.

  • Siempre me he preguntado si PrintWindow() usa su propia lógica, o si solo publica un WM_PRINT en la ventana dada. MSDN parece ser vago en ese punto. Es hora de un programa de prueba para comprobar que…

    – DavidK

    28 de octubre de 2008 a las 10:47

  • Utiliza su propia lógica, no WM_PRINT.

    – Mauricio Flanagan

    26 de febrero de 2009 a las 14:06

  • @DavidK: La versión actual de la documentación dice claramente que WM_PRINT o WM_PRINTCLIENT se ha enviado.

    – Ben Voigt

    9 de noviembre de 2013 a las 17:01

  • PrintWindow tiene la ventaja de que también imprime la ventana si está tapada por otra ventana o incluso fuera del monitor. Pero el precio que paga es que muchas aplicaciones que no son de Microsoft no manejan WM_PRINTCLIENT y termina con un mapa de bits en blanco. Otro problema que persiste es que PrintWindow solo copia la parte en el mapa de bits que se ve en la pantalla. Si su ventana tiene una barra de desplazamiento y muestra su contenido solo parcialmente, este código no es útil.

    – Elmue

    3 de junio de 2014 a las 3:43

  • ¿Cómo obtener la parte de la ventana que está oculta en la barra de desplazamiento?

    – Acaz Souza

    15/10/2014 a las 17:20

Copie el mapa de bits de origen en un mapa de bits de memoria antes de cerrar/ocultar la ventana.

Podrías intentar enviar un WM_PRINT mensaje a la ventana. Para muchas ventanas (incluidas todas las ventanas estándar y los controles comunes), esto hará que se pinte en el DC suministrado.

Además, si pasa un HDC como wparam de un mensaje WM_PAINT, muchas ventanas (como los controles comunes) pintarán en ese DC en lugar de en la pantalla.

¿Tal vez pueda activar una operación de redibujado en la ventana con InvalidateRect?

Desafortunadamente, creo que vas a tener problemas reales para que esto funcione de manera confiable. No dice exactamente lo que está haciendo, pero asumo que, dado el identificador de la ventana, está agarrando el contexto del dispositivo asociado con la ventana llamando a GetWindowDC() y luego usando el contexto del dispositivo resultante.

Esto funcionará bien en XP cuando la ventana esté visible. Sin embargo, en Vista, si la composición de escritorio está habilitada, ni siquiera funcionará correctamente: obtendrá 0 de GetWindowDC(). Fundamentalmente, capturar contextos de dispositivos de ventana no funcionará de manera confiable.

Si la ventana desde la que intenta copiar es parte de su propia aplicación, le sugiero que modifique su código para admitir el mensaje WM___PRINT: esto actúa como WM_PAINT, pero le permite proporcionar un contexto de dispositivo para dibujar.

Si la ventana no es de su aplicación, básicamente no tiene suerte: si la ventana está oculta, la imagen de lo que mostraría si fuera visible no existe en ninguna parte.

La función PrintWindow no parece funcionar en una ventana oculta, solo en las visibles.

avatar de usuario
jon brillante

Al abordar las cosas desde una perspectiva diferente, ¿estás seguro de que eso es realmente lo que quieres hacer? Por ejemplo, ¿no desea usar CreateCompatibleDC y CreateCompatibleBitmap para crear su superficie de dibujo invisible, dibujar sobre eso y luego usar BitBlt?

Un poco más de información sobre los antecedentes de lo que está haciendo podría permitirle a alguien encontrar una solución o algún pensamiento lateral…

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad