2010-10-19 6 views
6

Ich schreibe eine Screen Capture-Anwendung in Qt4 mit C++. Ich habe ein Problem, wenn ich auf zwei Bildschirme abstimme. Ich kann kein Bild mit dem zweiten Bildschirm erstellen. Ich habe versucht, eine C# -Anwendung und das wird alle Desktops in einem Bild greifen und ich konnte von dort jedes Bildschirm-Desktop-Bild extrahieren. Hier ist der C# -Code istErfassen Sie mehrere Bildschirme Desktop-Bild mit 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); 
} 

Der Code Qt ist kleiner, i testeten auch, ob die native Windows auf dem Desktop Griff unterscheidet sich von der Qt Desktop0> winId(), aber sie sind gleich

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

Ich bin mir nicht sicher, ob dies ein Fehler in Qt ist oder ein Feature ist, mit dem gleichen Fenstergriff versucht es nur den ersten Desktop, wenn in der Tat der Desktop Relais aus den 2 Bildschirmen zusammengesetzt ist. Eine Idee ist, native Windows-Aufrufe zu verwenden und das Bild in einer temporären Datei zu speichern und eine QPixmap von dort zu laden, aber das ist nicht einfach, eine HBITMAP in einer Datei in C++ ohne MFC zu speichern. Fazit: Was denken Sie, ist das ein Fehler in Qt? keine Ahnung, wie man damit umgehen kann (kein MFC)

+0

Auch ich fand ein Beispiel mit GDI http: //www.experts-exchange.com/Microsoft/Entwicklung/Q_26484815.html, schauen Sie auf der Unterseite, sind die Zahlen hart codiert, so müssen Sie die Abmessungen zu bekommen und ändern Sie den Code – simion314

Antwort

3

Ich habe vor kurzem das gleiche Problem bemerkt.

Ich entschied mich schließlich, Qt für die Erstellung von Screenshots fallen zu lassen. Eine andere Situation, in der Qt bricht, ist die Verwendung des Aero-Themes von Windows Vista oder Windows 7. Dieses Thema rendert anscheinend alle Daten in einen Hintergrundpuffer, so dass alle von Qt aufgenommenen Screenshots schwarz sind.

Statt Qt verwenden Ich kann wie beschrieben mit der screen Klasse empfehlen http://www.apriorit.com/our-experience/articles/9-sd-articles/193-multi-monitor-screenshot

+0

Thx, könnte dies retten mich Ficken mit allen HDC, RECT HBITMAP und andere komplexe structs – simion314

+0

Wenn Ihre Anwendung Open Source ist, würde ich gerne den Code sehen, es scheint mir, dass die Screenshot-App, die Sie verlinkt verwendet MFC atlimage.h – simion314

4

Sie Bildschirme mit QDesktopWidget::screenCount() (Qt 4.6) und sich dann durch alle Bildschirme zählen können und tun QPixmap::grabWindow(...)

Über „Desktop zusammengesetzt von 2 Bildschirmen ". Es hängt alles davon ab, ob 2 Bildschirme virtuell sind (alle Bildschirme werden als ein Bildschirm behandelt) oder nicht.

@Frerich Raabe: Es funktioniert auf Windows 7, da ich ähnlichen Code verwenden, um Bildschirm-Grab durchzuführen.

+0

: GrabWindow (...) wird für mich den ersten Bildschirm zurückgeben, auch wenn ich benutze der zweite Bildschirm. Sind Sie sicher, dass es in zwei Monitoren funktioniert? – simion314

+0

Ich habe vor kurzem die Funktionalität des Grab-Screens implementiert, und ja, es hat gut funktioniert. Welche Version von Qt verwendest du? –

+0

Ich benutze 4.6.3 auf Windows XP SP3, ich habe eine Dual-Monitore eingerichtet und ich bekomme immer nur die erste Geröll, und ich versuchte alle Möglichkeiten, ich Relais nicht gerne Win APIDS – simion314

2

Mit einem virtuellen Desktop scheint die Methode QPixmap::grabWindow einen Screenshot mit der Größe des primären Bildschirms zurückzugeben. Das Übergeben der Dimensionen des vollständigen virtuellen Desktops gibt einen Screenshot beider Monitore zurück.

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

Doch auf einem Unix/Mac Box, dieses Verhalten zu testen, aber es funktioniert unter Windows 7.

+0

Arbeiten wie Charme auf meinem Ubuntu 10.10! Vielen Dank, dass Sie mir den Weg gezeigt haben. – zeFree

0

In einem Multi-Monitor-Setup unter Windows werden die Monitore in der Regel in einem virtuellen Desktop verbunden. Ich sage "normalerweise", weil ich nicht ganz sicher bin, was auf allen Windows-Versionen von XP SP0 (25. Oktober 2001) bis Win8 SP0 (26. Oktober 2012) passiert. Aber als virtueller Desktop bedeutet das, dass screen(x) immer dasselbe Widget zurückgibt; von dem, was ich gesehen habe, ist das einzige QDesktopWidget selbst. screenGeometry(x) gibt jedoch unterschiedliche Werte für jeden aufgezählten Monitor zurück.

Sie können den zweiten Bildschirm verwenden, indem Sie das Ergebnis screenGeometry(x) als Parameter für QPixmap :: grabWindow verwenden; dh:

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()); 

Dies ist für mich arbeitet gerade jetzt, und ich bin über die Build-off zu meinem QA-Team zur Hand.