Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2471 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Capturer le contenu d'une fenetre - Win32

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Capturer le contenu d'une fenetre - Win32

n°1172875
red factio​n
Posté le 08-08-2005 à 23:27:24  profilanswer
 

je cherche a capturer le contenu d'une fenetre de n'importe quelle application meme si celle si est cachée ou partiellement recouverte
 
j'ai deja essaye plusieurs pistes ....

Code :
  1. Bitblt(getDC(0),....) => ne fonctionne pa si la fenetre est recouverte ou cachee
  2. PrintWindow => impeccable, juste ce qu'il me faut .... sauf que cette fct n'est disponible que sous WinXP et Win Server 2003 :(
  3. SendMessage(hwnd,WM_PRINT,hdc,.....) (sense etre lequivalent du PrintWindow sous 2000) => je n'ai jamais reussi a obtenir un resultat correct, cela me donne un rectangle noir a chaque fois :S


 Winplosion le fait sans prob que se soit sous xp ou 2000 :o


Message édité par red faction le 09-08-2005 à 17:00:15
mood
Publicité
Posté le 08-08-2005 à 23:27:24  profilanswer
 

n°1172951
HelloWorld
Salut tout le monde!
Posté le 09-08-2005 à 10:18:20  profilanswer
 

C'est assez coton, mais y'a un bon article sur le sujet:
http://www.fengyuan.com/article/wmprint.html


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1173447
red factio​n
Posté le 09-08-2005 à 17:05:35  profilanswer
 

oui, je connais cet article mais cela fonctionne uniquement lorsque que c l'appli elle meme qui lance le WM_PRINT
 
javai essaye ceci mais sans succes  
 

Code :
  1. void PrintWindow(HWND hWnd)
  2. {
  3.     HDC hDCMem = CreateCompatibleDC(NULL);
  4.     RECT rect;
  5.     GetWindowRect(hWnd, & rect);
  6.     HBITMAP hBmp = NULL;
  7.     {
  8.         HDC hDC = GetDC(hWnd);
  9.         hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
  10.         ReleaseDC(hWnd, hDC);
  11.     }
  12.     HGDIOBJ hOld = SelectObject(hDCMem, hBmp);
  13.     SendMessage(hWnd, WM_PRINT, (WPARAM) hDCMem, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);
  14.     SelectObject(hDCMem, hOld);
  15.     DeleteObject(hDCMem);
  16.     OpenClipboard(hWnd);
  17.     EmptyClipboard();
  18.     SetClipboardData(CF_BITMAP, hBmp);
  19.     CloseClipboard();
  20. }


 
en passant PrintWindow(FindWindow(NULL,"WM_PRINT" ));
avec leur prog (ou nimporte quel autre dailleur), ca ne fonctionne jamais :( (teste sous WinXP SP2)
 
qd je paste le bitmap jobtient un rectangle noir  [:red faction]

n°1173873
HelloWorld
Salut tout le monde!
Posté le 10-08-2005 à 13:52:25  profilanswer
 

C'est loin d'être aussi simple. Tu peux pas filer un HDC comme ça. C'est un objet GDI, et les objets GDI sont spécifiques à chaque process, ne sont pas partageables.
Selon ton approche, tu peux pas aller plus loin que blitter la fenêtre dans ton HDC, mais si elle est cachee, t'auras pas son contenu.
Relis bien l'article, plusieurs fois, car c'est de la haute voltige. Y'a du subclassing et du thunking.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1173909
red factio​n
Posté le 10-08-2005 à 14:32:58  profilanswer
 

la seule chose que je fourni ici c le handle de la fenetre et non un hdc
lexemple repris ici (void PrintWindow...) proviens du site jai juste fait un copier-coller
 
qd a leur histoire d'injection de code c uniquement si la fenetre nest pa capable de traiter ce genre de message hors ici l'utilitaire fourni sur le site le fait  
 
ou alors jai rien compris a ce que tu viens de me dire


Message édité par red faction le 10-08-2005 à 14:34:43
n°1174129
HelloWorld
Salut tout le monde!
Posté le 10-08-2005 à 17:44:17  profilanswer
 

Code :
  1. SendMessage(hWnd, WM_PRINT, (WPARAM) hDCMem


hDCMem, c'est un HDC.
L'utilitaire fournit sur le site ne traite pas WM_PRINT.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1174223
red factio​n
Posté le 10-08-2005 à 21:40:03  profilanswer
 

edit : reflexion en cours   :whistle:


Message édité par red faction le 10-08-2005 à 21:42:30
n°1174320
karlkox
Posté le 11-08-2005 à 04:52:16  profilanswer
 

Code :
  1. #include <windows.h>
  2. /*  Declare Windows procedure  */
  3. LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  4. void ImportDialog(HWND parent, HWND child)
  5. {
  6. int width, heigth;
  7. RECT r;
  8. GetWindowRect(parent, &r);
  9. width = r.right - r.left;
  10. heigth = r.bottom - r.top;   
  11. MoveWindow(parent, 0, GetSystemMetrics(SM_CYCAPTION), width, heigth, 0);   
  12. SetWindowPos(child, 0, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  13. LONG OldParent = GetWindowLong(child, GWL_HWNDPARENT);
  14. SetParent(child, parent);
  15. }
  16. void ExportDialog(HWND parent, HWND child)
  17. {
  18. SetParent(child, parent);   
  19. }
  20. /*  Make the class name into a global variable  */
  21. char szClassName[ ] = "WindowsApp";
  22. int WINAPI WinMain (HINSTANCE hThisInstance,
  23.                     HINSTANCE hPrevInstance,
  24.                     LPSTR lpszArgument,
  25.                     int nFunsterStil)
  26. {
  27.     HWND hwnd;               /* This is the handle for our window */
  28.     MSG messages;            /* Here messages to the application are saved */
  29.     WNDCLASSEX wincl;        /* Data structure for the windowclass */
  30.     /* The Window structure */
  31.     wincl.hInstance = hThisInstance;
  32.     wincl.lpszClassName = szClassName;
  33.     wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
  34.     wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
  35.     wincl.cbSize = sizeof (WNDCLASSEX);
  36.     /* Use default icon and mouse-pointer */
  37.     wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  38.     wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  39.     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  40.     wincl.lpszMenuName = NULL;                 /* No menu */
  41.     wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
  42.     wincl.cbWndExtra = 0;                      /* structure or the window instance */
  43.     /* Use Windows's default color as the background of the window */
  44.     wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  45.     /* Register the window class, and if it fails quit the program */
  46.     if (!RegisterClassEx (&wincl))
  47.         return 0;
  48.     /* The class is registered, let's create the program*/
  49.     hwnd = CreateWindowEx (
  50.            0,                   /* Extended possibilites for variation */
  51.            szClassName,         /* Classname */
  52.            "Windows App",       /* Title Text */
  53.            WS_OVERLAPPEDWINDOW, /* default window */
  54.            CW_USEDEFAULT,       /* Windows decides the position */
  55.            CW_USEDEFAULT,       /* where the window ends up on the screen */
  56.            1024,                 /* The programs width */
  57.            768,                 /* and height in pixels */
  58.            HWND_DESKTOP,        /* The window is a child-window to desktop */
  59.            NULL,                /* No menu */
  60.            hThisInstance,       /* Program Instance handler */
  61.            NULL                 /* No Window Creation data */
  62.            );
  63.     /* Make the window visible on the screen */
  64.     ShowWindow (hwnd, nFunsterStil);
  65.     HWND child = FindWindow("{E7076D1C-A7BF-4f39-B771-BCBE88F2A2A8}", "foobar2000 v0.9 beta 5" );
  66.     if (child != NULL)
  67.         ImportDialog(hwnd, child);
  68.     else
  69.         MessageBox(hwnd, "Can't find foobar2000 v0.9 beta5 :(", "Error !", MB_OK);
  70.     /* Run the message loop. It will run until GetMessage() returns 0 */
  71.     while (GetMessage (&messages, NULL, 0, 0))
  72.     {
  73.         /* Translate virtual-key messages into character messages */
  74.         TranslateMessage(&messages);
  75.         /* Send message to WindowProcedure */
  76.         DispatchMessage(&messages);
  77.     }
  78.     /* The program return-value is 0 - The value that PostQuitMessage() gave */
  79.     return messages.wParam;
  80. }
  81. /*  This function is called by the Windows function DispatchMessage()  */
  82. LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  83. {
  84.     switch (message)                  /* handle the messages */
  85.     {
  86.         case WM_DESTROY:
  87.             PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
  88.             break;
  89.         default:                      /* for messages that we don't deal with */
  90.             return DefWindowProc (hwnd, message, wParam, lParam);
  91.     }
  92.     return 0;
  93. }


 
Il y a un petit problème de rafraichissement, mais bon, la flemme de corriger (go to WM_PAINT  :p )

n°1174933
red factio​n
Posté le 11-08-2005 à 22:09:48  profilanswer
 

ok merci beacoup jvais regarder a ca  :)


Message édité par red faction le 11-08-2005 à 22:14:44
n°1175061
HelloWorld
Salut tout le monde!
Posté le 12-08-2005 à 10:33:09  profilanswer
 

Personnelement je vois pas trop le rapport...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le 12-08-2005 à 10:33:09  profilanswer
 

n°1175119
karlkox
Posté le 12-08-2005 à 11:49:55  profilanswer
 

Le mot capturer à deux sens d'un point de vue gestion des fenêtres sous windows, j'ai pris l'une des deux, la mauvaise apparamment.  :ange:


Message édité par karlkox le 12-08-2005 à 12:06:27
n°1175178
HelloWorld
Salut tout le monde!
Posté le 12-08-2005 à 13:50:28  profilanswer
 

Ah ok.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1175453
red factio​n
Posté le 12-08-2005 à 19:25:40  profilanswer
 

me suis demandé si tu t'etais pa trompé de topic au début , puis bon jme suis dit que le fait de changer le parent d'une fenetre permeterait peut etre de la capturer apres :sarcastic:


Message édité par red faction le 17-08-2005 à 23:00:34
n°1175485
karlkox
Posté le 12-08-2005 à 20:58:45  profilanswer
 

J'ai lu en diagonal et j'avais la tête dans le c.. (cf l'heure du post), je vais voir si je peut trouver un début de solution pour me rattraper  :ange:

n°1178356
ChristianS​_
Posté le 17-08-2005 à 22:25:21  profilanswer
 

Y'a un projet qui a l'air abandonné qui peut faire ça :
 
http://expire.free.fr/board/index. [...] wtopic=114
 
( demo video là : http://www.logiccubed.com/cgi-bin/ [...] 1100311193 )
 
Le code permet de récupérer directement la zone memoire utilisé pour le dessin des fenetres.
Je n'ai testé que sous XP, ça fonctionne bien mais le code semble spécifique à la machine ( faut executé un prog : infofetch.exe qui crée un fichier contenant des infos graphiques pour l'execution )
L'exemple fournit est tres simple.

n°1178502
HelloWorld
Salut tout le monde!
Posté le 18-08-2005 à 09:49:17  profilanswer
 

En plus simple y'a la fonction PrintWindow.
Mais c'est dispo qu'à partir de XP...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1178507
HelloWorld
Salut tout le monde!
Posté le 18-08-2005 à 09:56:02  profilanswer
 

D'ailleurs il en parle dans son Readme dans le lien que tu donnes, et dit qu'il s'est mis en tête de la coder sous Win2K.
Son soft c'est l'artillerie lourde : il a codé un driver.  
J'avais lu des dissussions sur la théorie, mais je conaissais pas de soft non comercial qui l'ai mise en pratique. C'est beaucoup de courage :jap:
Dommage qu'il donne pas le code source :/


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1179196
karlkox
Posté le 18-08-2005 à 22:12:19  profilanswer
 

J'ai commencé à faire un truc mais par manque de temps, je vous propose cette idée qui me parait assez simple en fait : chercher l'appli que l'on souhaite screenshoter (FindWindow), faire une capture du bureau, récupérer sa position (GetWindowRect), le mettre en avant plan (j'ai une fonction à vous proposer si vous voulez) et recadrer l'image du bureau suivant les positions précédemment récupérées. (BitBlt)


Message édité par karlkox le 18-08-2005 à 22:13:06
n°1179240
HelloWorld
Salut tout le monde!
Posté le 18-08-2005 à 23:28:16  profilanswer
 

Tu peux par cette même méthode faire une screenshot de la fenêtre voulue uniquement (le bureau est une fenêtre en fait).
Le problème ici c'est d'arriver à capturer le contenu d'une fenêtre partiellement / totalement cachée...

n°1179253
karlkox
Posté le 18-08-2005 à 23:51:06  profilanswer
 

Bah, c'est ce que j'ai tenté d'expliquer : tu fais un screenshot du bureau (oui, je sais que le bureau est une fenêtre) mais en ayant mis en avant plan la fenêtre de l'application que tu souhaites screenshoter, donc la, tu as une image de ton bureau avec la fenêtre en avant plan.
Si ton bureau est en 1024x768 et que la position de la fenêtre que tu as mis en avant plan est à 500, 80, il suffit de créér une deuxième image en ne blittant que la portion de cette fenêtre d'où l'utilité de préalablement récupérer la position de la fenêtre.
Si c'est pas clair la [:airforceone]


Message édité par karlkox le 19-08-2005 à 09:07:11
n°1179268
red factio​n
Posté le 19-08-2005 à 00:34:03  profilanswer
 

moi jai tjs rien compris :D

n°1179339
karlkox
Posté le 19-08-2005 à 09:09:12  profilanswer
 

[:bertie wooster]

n°1179359
HelloWorld
Salut tout le monde!
Posté le 19-08-2005 à 09:40:32  profilanswer
 

Citation :

ayant mis en avant plan la fenêtre de l'application que tu souhaites screenshoter


sauf que sa question c'est comment le faire sans mettre en avant plan.
Sinon c'est beaucoup plus simple. Pas besoin de prendre le bureau en screenshot, tu blit le DC de la fenêtre directement, de la même manière que tu blit le DC du bureau.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1179436
karlkox
Posté le 19-08-2005 à 11:03:50  profilanswer
 

J'ai relu toute la discussion et je ne vois nul part red faction disant qu'il veut le faire sans mettre la fenêtre en avant plan, il a juste dit toutes les fenêtres, même lorsqu'elles sont en arrière plan, rien ne nous empêche d'utiliser l'avant plan pour récupérer la fenêtre.
Bref, je vais voire s'il est possible de le faire comme tu l'as compris :)

n°1179615
HelloWorld
Salut tout le monde!
Posté le 19-08-2005 à 14:27:42  profilanswer
 

Moui, c'est vrai, il suffit de mettre au premier plan.
Pour le "comme j'ai dit", c'est simplement comme tu l'a dit, mais en utilisant le HDC de la fenêtre (GetWindowDC(hWnd)) au lieu du bureau (GetDC(NULL)).
Tant qu'on y est, pour les fenêtres video etc... :
http://www.codeproject.com/dialog/screencap.asp


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1180040
red factio​n
Posté le 20-08-2005 à 00:18:54  profilanswer
 

bon jvous montre qd mm a quoi ca va servir
 
http://membres.lycos.fr/manga4free/test.jpg
 
l'idée c de remplacer le alt-tab actuel par une version 3d
le screenshot quon voit ici ne correspond pas vraiment au programme,dans la version actuelle les fenetre rangees les une derriere les autres, ici juste un screen shot fait lors d'un test   :o  

n°1191301
red factio​n
Posté le 03-09-2005 à 19:47:58  profilanswer
 

bon apparament ya pa vraiment moyen de faire qqch
 
soit lorsque je veux afficher tout les fenetre je les passe en avant plan (vu que yen a une vingtaine + certaines cachees bonjour leffet tout pourri)
 
ou alors je stoque chaque nouvelle fenetre ouverte dans un bitmap lorsque lutilisateur louvre la premiere fois (nivo ram ca risque detre drole)

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Capturer le contenu d'une fenetre - Win32

 

Sujets relatifs
Redimensionner une fenetre selon la resolution ?Redimensionner une fenetre selon la resolution
Api Win32 : CreateRemoteThread[resolu] fermer une fenetre a partir d'un bouton d'un onglet
div avec comme contenu url[wxwidget] Dessiner un bouton sur une fenetre.
creer une fenetre lisible sans la barre defilement en basD'un fenetre a une autre
contenu d'un sitefenetre gtk ne s'ouvre pas
Plus de sujets relatifs à : Capturer le contenu d'une fenetre - Win32


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR