2010-10-19 11 views
6

Estoy escribiendo una aplicación de captura de pantalla en Qt4 con C++. Tengo un problema al sintonizar pantallas duales. No puedo obtener una imagen con la segunda pantalla. Probé una aplicación C# y eso tomará todos los escritorios en una imagen y podría extraer de allí cada imagen de escritorio en pantalla. Este es el código C#Capturar imagen de escritorio de pantallas múltiples usando Qt4

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 

public class TestGrab 
{ 
    [STAThread] 
    static void Main(string[] args) 
    { 
    IntPtr hDC = WindowsNative.GetDC(WindowsNative.GetDesktopWindow()); 
    IntPtr hBitmap = WindowsNative.GetCurrentObject(hDC, 
    WindowsNative.OBJ_BITMAP); 
    System.Drawing.Bitmap imageDesktop = System.Drawing.Image.FromHbitmap(
    hBitmap); 
    imageDesktop.Save(@"c:\zzzzdesktop.png"); 
    } 
} 

public class WindowsNative 
{ 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetDesktopWindow(); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetDC(IntPtr ptr); 

    public const int OBJ_BITMAP = 7; 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr GetCurrentObject(IntPtr hdc, uint 
    uiObjectType); 
} 

El código Qt es más pequeño, también he probado si las ventanas nativas manejan en el escritorio es diferente de la Qt desktop0> winId(), pero ellos son iguales

QPixmap CaptureWinDesktop() 
{ 
    WId desktop=GetDesktopWindow(); 
    WId desktop2=QApplication::desktop()->winId(); 
    if(desktop!=desktop2) 
    { 
     qDebug("sunt fdiferite WId"); 
    } 
    QPixmap entireDesktop= QPixmap::grabWindow(desktop); 
    return entireDesktop; 
} 

No estoy seguro si esto es un error en Qt o si es una característica, usando el mismo identificador de ventana reintenta solo el primer escritorio cuando de hecho el escritorio está compuesto por retransmisión de las 2 pantallas. Una idea es usar llamadas nativas de Windows y guardar la imagen en un archivo temporal y cargar un QPixmap desde allí, pero no es sencillo guardar un HBITMAP en un archivo en C++ sin MFC. Conclusión: ¿qué crees que es un error en Qt? alguna idea de cómo evitarlo (sin MFC)

+0

También encontré un ejemplo usando GDI http: //www.experts-exchange.com/Microsoft/Development/Q_26484815.html, mira en la parte inferior, los números están codificados, por lo que tienes que obtener las dimensiones y modificar el código – simion314

Respuesta

3

Recientemente me di cuenta del mismo problema.

Finalmente decidí eliminar Qt para tomar capturas de pantalla. Otra situación en la que Qt se rompe es cuando se utiliza el tema Aero de Windows Vista o Windows 7. Este tema aparentemente convierte todos los datos en un búfer de fondo, por lo que todas las capturas de pantalla tomadas por Qt son todas negras.

En vez de usar Qt puedo recomendar el uso de la clase ScreenShooter como se describe al http://www.apriorit.com/our-experience/articles/9-sd-articles/193-multi-monitor-screenshot

+0

Thx, esto me podría ahorrar inventos con todo el HDC, RECT HBITMAP y otros complejos structs – simion314

+0

Si su aplicación es de código abierto, me gustaría ver el código, me parece que la aplicación de captura de pantalla que ha vinculado utiliza MFC atlimage.h – simion314

4

puede contar con pantallas con QDesktopWidget::screenCount() (Qt 4.6) y luego viajar a través de todas las pantallas y hacer QPixmap::grabWindow(...)

Acerca de "escritorio integrado de 2 pantallas ". Todo depende si la pantalla 2 es virtual (todas las pantallas son tratadas como una pantalla) o no.

@Frerich Raabe: funciona en Windows 7 ya que estoy usando un código similar para realizar capturas de pantalla.

+0

: grabWindow (...) me devolverá la primera pantalla, incluso si uso la segunda pantalla. ¿Estás seguro de que funciona en monitores duales? – simion314

+0

Estaba implementando recientemente la funcionalidad de pantalla de captura, y sí, funcionaba bien. ¿Qué verrsión de Qt estás usando? –

+0

uso 4.6.3 en Windows XP sp3, configuré monitores duales y siempre obtengo solo la primera pantalla, y probé todas las posibilidades, no me gusta usar APIDS ganadores – simion314

2

Con un escritorio virtual, el método QPixmap::grabWindow parece devolver una captura de pantalla con el tamaño de la pantalla principal. Al pasar las dimensiones del escritorio virtual completo se obtiene una captura de pantalla de ambos monitores;

QDesktopWidget *desktop = QApplication::desktop(); 
    QPixmap screenshot = QPixmap::grabWindow(desktop->winId(), 0, 0, desktop->width(), desktop->height()); 

Sin embargo, para probar este comportamiento en una máquina Unix/Mac, pero funciona bajo Windows 7.

+0

¡Funcionando como un hechizo en mi Ubuntu 10.10! Muchas gracias por mostrarme el camino. – zeFree

0

En una configuración de varios monitores en Windows, los monitores se unen normalmente en un escritorio virtual. Digo "generalmente" porque no estoy del todo seguro de lo que sucede en todas las versiones de Windows XP SP0 (25 de octubre de 2001) a Win8 SP0 (26 de octubre de 2012). Pero, como escritorio virtual, eso significa que screen(x) siempre devolverá el mismo widget; por lo que he visto, este es el único y único QDesktopWidget. Sin embargo, screenGeometry(x) devolverá valores diferentes para cada monitor enumerado.

Puede tomar la segunda pantalla usando el resultado de screenGeometry(x) como los parámetros de QPixmap :: grabWindow; es decir:

QDesktopWidget* desktop = QApplication::desktop(); 
WId wid = desktop->winId(); 
QRect geo = desktop->screenGeometry(indexOfTheMonitorYouWant); 
QPixmap cap = QPixmap::grabWindow(wid, geo.left(), geo.top(), geo.width(), geo.height()); 

Esto funciona para mí en este momento, y estoy a punto de entregar la construcción a mi equipo de control de calidad.

Cuestiones relacionadas