2010-10-19 7 views
6

J'écris une application de capture d'écran en Qt4 avec C++. J'ai un problème lors du réglage sur deux écrans. Je suis incapable d'obtenir une image avec le deuxième écran. J'ai essayé une application C# et cela va attraper tous les bureaux dans une image et je pourrais extraire à partir de là chaque image de bureau à l'écran. Voici le code C#Capture d'image de bureau à plusieurs écrans en utilisant 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); 
} 

Le code Qt est plus petit, je l'ai testé aussi si les fenêtres natives poignée sur le bureau est différent de Qt desktop0> winId() mais leur sont égaux

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

Je ne suis pas sûr que ce soit un bug dans Qt ou est une fonctionnalité, en utilisant la même poignée de fenêtre, il réessaye seulement le premier bureau alors qu'en fait le bureau est composé de relais à partir des 2 écrans. Une idée consiste à utiliser des appels Windows natifs et enregistrer l'image dans un fichier temporaire et charger un QPixmap à partir de là, mais ce n'est pas simple d'enregistrer un HBITMAP dans un fichier en C++ sans MFC. Conclusion: que penses-tu d'un bug dans Qt? une idée de la façon de contourner ce problème (pas de MFC)

+0

J'ai également trouvé un exemple utilisant GDI http: //www.experts-exchange.com/Microsoft/Développement/Q_26484815.html, regardez en bas, les chiffres sont codés en dur, donc vous devez obtenir les dimensions et modifier le code – simion314

Répondre

3

J'ai récemment remarqué le même problème. J'ai finalement décidé d'abandonner Qt pour prendre des captures d'écran. Une autre situation dans laquelle Qt casse est lorsque vous utilisez le thème Aero de Windows Vista ou Windows 7. Ce thème rend apparemment toutes les données dans un tampon d'arrière-plan, donc toutes les captures d'écran prises par Qt sont toutes noires.

Au lieu d'utiliser Qt je peux vous recommandons d'utiliser la classe ScreenShooter comme décrit à http://www.apriorit.com/our-experience/articles/9-sd-articles/193-multi-monitor-screenshot

+0

Thx, cela pourrait me sauver figting avec tous les HDC, RECT HBITMAP et autres complexes Structures – simion314

+0

Si votre application est open source je voudrais voir le code, il me semble que l'application de capture d'écran que vous avez lié utilise MFC atlimage.h – simion314

4

vous pouvez compter les écrans avec QDesktopWidget::screenCount() (Qt 4.6), puis voyager à travers tous les écrans et faire QPixmap::grabWindow(...)

A propos de « composé de bureau à partir de 2 écrans ". Tout dépend si 2 écrans sont virtuels (tous les écrans sont traités comme un seul écran) ou non.

@Frerich Raabe: cela fonctionne sur Windows 7 car j'utilise un code similaire pour effectuer une capture d'écran.

+0

: grabWindow (...) me retournera le premier écran même si j'utilise le deuxième écran. Êtes-vous sûr que cela fonctionne dans deux moniteurs? – simion314

+0

J'ai récemment implémenté la fonctionnalité d'écran de saisie, et oui cela fonctionnait bien. Quelle est la verrsion de Qt que vous utilisez? –

+0

J'utilise 4.6.3 sur Windows XP SP3, j'ai configuré un double moniteur et je reçois toujours seulement le premier éboulis, et j'ai essayé toutes les possibilités, je relais n'aime pas utiliser win APIDS – simion314

2

Avec un bureau virtuel, la méthode QPixmap::grabWindow semble renvoyer une capture d'écran avec la taille de l'écran principal. Passer dans les dimensions du bureau virtuel complet renvoie une capture d'écran des deux moniteurs;

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

Cependant, pour tester ce comportement sur un système Unix/Mac, mais il fonctionne sous Windows 7.

+0

Travailler comme charme sur mon Ubuntu 10.10! Merci beaucoup de m'avoir montré le chemin. – zeFree

0

Dans une configuration multi-écrans sous Windows, les moniteurs sont généralement réunis en un bureau virtuel. Je dis "habituellement" parce que je ne suis pas tout à fait sûr de ce qui se passe sur toutes les versions de Windows de XP SP0 (25 octobre 2001) à Win8 SP0 (26 octobre 2012). Mais, en tant que bureau virtuel, cela signifie que screen(x) retournera toujours le même widget; d'après ce que j'ai vu c'est le seul et unique QDesktopWidget lui-même. Cependant, screenGeometry(x) renverra des valeurs différentes pour chaque moniteur énuméré.

Vous pouvez saisir le second écran en utilisant le résultat de screenGeometry(x) comme paramètres de QPixmap :: grabWindow; c'est-à-dire:

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

Cela fonctionne pour moi en ce moment, et je suis sur le point de remettre la construction à mon équipe QA.

Questions connexes