[C (ou autre)] imprime ecran

imprime ecran [C (ou autre)] - C - Programmation

Marsh Posté le 05-03-2009 à 18:17:53    

Bonjour à tous.
 
J'ai comme projet cette année la réalisation d'un tamagoshi en écran de veille (à coder en C).
Pour cela j'aurais aimé pouvoir faire un imprimé écran du bureau windows afin d'utiliser cette image comme arriere plan pour mon programme.
 
Mon programme sera codé en C avec la librairie graphique allegro.
 
Auriez-vous des idées pour effectuer cette opération ?
Existe-t-il une fonction du type system("printscreen" ) ou sinon une fonction allegro permetant de faire un imprime ecran du bureau ?
 
Merci d'avance pour votre aide...

Reply

Marsh Posté le 05-03-2009 à 18:17:53   

Reply

Marsh Posté le 05-03-2009 à 18:48:37    

Méthode utilisant l'API win32:
 
    http://opentutorials.thejefffiles. [...] en_Capture
 
C'est du C++, mais relativement trivial à porter en C. La fonction va te renvoyer un BMP, avec un format de pixel natif à la celui de l'écran (donc faire gaffe au mode d'affichage: colormap, rgb, argb, ....).

Reply

Marsh Posté le 05-03-2009 à 18:54:26    

Merci beaucoup pour ta réponse mais je ne connais pas du tout le C++
 
Saurais-tu comment faire ça en C ?

Reply

Marsh Posté le 05-03-2009 à 19:11:37    

$plitbErzing a écrit :

Pour cela j'aurais aimé pouvoir faire un imprimé écran du bureau windows afin d'utiliser cette image comme arriere plan pour mon programme.


Aucun rapport avec le langage C.

 

Tu dégage bien ton bureau, puis tu appuies sur la touche printscreen (ce qui fait un 'copié' de l'écran, puis tu fais un 'collé' dans paintbrush (paint, pbrush ...). Ensuite, tu sauvegardes l'image en jpg, par exemple.

 


Message édité par Emmanuel Delahaye le 05-03-2009 à 19:12:13

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-03-2009 à 19:27:01    

Nan mais justement, je veux que l'imprime ecran se fasse automatiquement, au lancement de mon programme, pour utiliser l'image comme arriere plan du programme.
C'est pour ensuite affiché un personnage annimésur l'image, pour qu'on croit qu'il apparait sur le bureau.
 
Je crois que tpierron m'avais compris ;)

Reply

Marsh Posté le 05-03-2009 à 22:45:07    

Ouais, c'est mon jour de fête:

Code :
  1. #include <windows.h>
  2. #include <stdio.h>
  3. HRESULT CaptureWindow(HWND hWnd, LPBITMAPINFO * pscr, LPVOID * pbits)
  4. {
  5.     // Get the required device contexts
  6.     HDC          hDC;
  7.     HDC          hDCCompatible;
  8.     HBITMAP      hbmpDesktop;
  9.     HBITMAP      hbmpOld;
  10.     LPVOID       data;
  11.     LPBITMAPINFO bitmap;
  12.     if (hWnd == NULL) hDC = CreateDC(TEXT("DISPLAY" ), NULL, NULL, NULL);
  13.     else              hDC = GetDC(hWnd);
  14.     hDCCompatible = CreateCompatibleDC(hDC);
  15.     hbmpDesktop   = CreateCompatibleBitmap(hDC, GetDeviceCaps(hDC, HORZRES), GetDeviceCaps(hDC, VERTRES));
  16.     // Prepare to copy the desktop image
  17.     hbmpOld = (HBITMAP)SelectObject(hDCCompatible, hbmpDesktop);
  18.     // Copy the desktop DC in to hbmpDesktop
  19.     BitBlt(hDCCompatible, 0, 0, GetDeviceCaps(hDC, HORZRES), GetDeviceCaps(hDC, VERTRES), hDC, 0, 0, SRCCOPY);
  20.     SelectObject(hDCCompatible, hbmpOld);
  21.     // Allocate the screenshot of the desktop
  22.     bitmap = *pscr = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
  23.     if (NULL == bitmap)
  24.         return E_OUTOFMEMORY;
  25.     ZeroMemory(bitmap, sizeof(BITMAPINFOHEADER));
  26.     bitmap->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  27.     // Ask for the bitmap information about the desktop
  28.     GetDIBits(hDCCompatible, hbmpDesktop, 0, GetDeviceCaps(hDC, VERTRES), NULL, bitmap, DIB_RGB_COLORS);
  29.     // Allocate the image's data
  30.     data = *pbits = malloc(bitmap->bmiHeader.biSizeImage);
  31.     if (NULL == data)
  32.         return E_OUTOFMEMORY;
  33.     // And finally fill in our bitmap's bits
  34.     GetDIBits(hDCCompatible, hbmpDesktop, 0, GetDeviceCaps(hDC, VERTRES), data, bitmap, DIB_RGB_COLORS);
  35.     // Clean up after ourselves
  36.     DeleteObject(hbmpDesktop);
  37.     DeleteDC(hDCCompatible);
  38.     if (hWnd == NULL)   DeleteDC(hDC);
  39.     else                ReleaseDC(hWnd,hDC);
  40.     return S_OK;
  41. }
  42. int WINAPI WinMain (HINSTANCE hThisInstance,
  43.                      HINSTANCE hPrevInstance,
  44.                      LPSTR lpszArgument,
  45.                      int nCmdShow)
  46. {
  47.     BITMAPFILEHEADER header = {0};
  48.     LPBITMAPINFO     screen = NULL;
  49.     LPVOID           data   = NULL;
  50.     if (CaptureWindow(NULL, &screen, &data) == S_OK)
  51.     {
  52.         /* Pas la peine de faire ca, si tu manipules l'image avec gdi par la suite */
  53.         FILE * out = fopen("capture.bmp", "wb" );
  54.         header.bfType    = 0x4D42;
  55.         header.bfSize    = sizeof header + sizeof (BITMAPINFOHEADER) + screen->bmiHeader.biSizeImage;
  56.         header.bfOffBits = sizeof header + sizeof (BITMAPINFOHEADER);
  57.         if (out)
  58.         {
  59.             screen->bmiHeader.biCompression = BI_RGB;
  60.             fwrite(&header, 1, sizeof header, out);
  61.             fwrite(screen,  1, sizeof (BITMAPINFOHEADER), out);
  62.             fwrite(data,    1, screen->bmiHeader.biSizeImage, out);
  63.             fclose(out);
  64.         }
  65.         else fprintf(stderr, "error writing capture.bmp\n" );
  66.         free(screen);
  67.         free(data);
  68.     }
  69.     return 0;
  70. }


Reply

Marsh Posté le 05-03-2009 à 23:37:16    

Merci beaucoup de ta réponse.
J'ai copier ton code dans CodeBlocks, et au moment de compiler, j'ai plusieurs erreurs.
 
Ci-dessous le rapport de CodeBlocks:
 
Compiling: main.c
Linking console executable: bin\Debug\screenshot.exe
obj\Debug\main.o: In function `CaptureWindow':
C:[...]/main.c:14: undefined reference to `_CreateDCA@16'
C:[...]/main.c:17: undefined reference to `_CreateCompatibleDC@4'
C:[...]/main.c:18: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:18: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:18: undefined reference to `_CreateCompatibleBitmap@12'
C:[...]/main.c:21: undefined reference to `_SelectObject@8'
C:[...]/main.c:24: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:24: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:24: undefined reference to `_BitBlt@36'
C:[...]/main.c:26: undefined reference to `_SelectObject@8'
C:[...]/main.c:37: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:37: undefined reference to `_GetDIBits@28'
C:[...]/main.c:45: undefined reference to `_GetDeviceCaps@8'
C:[...]/main.c:45: undefined reference to `_GetDIBits@28'
C:[...]/main.c:48: undefined reference to `_DeleteObject@4'
C:[...]/main.c:49: undefined reference to `_DeleteDC@4'
C:[...]/main.c:50: undefined reference to `_DeleteDC@4'

Reply

Marsh Posté le 06-03-2009 à 00:21:45    

http://forum.hardware.fr/hfr/Progr [...] 2864_1.htm
 
edit:
codeblocks: project > build options > linker setting
 
Il y aura peut-être d'autres lib à ajouter. Copie tes erreurs dans google.


Message édité par ptitchep le 06-03-2009 à 00:25:13

---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 06-03-2009 à 00:49:01    

Merci beaucoup ça marche :)
 
Par contre il y a juste un tout petit défaut, quand ça fait la capture, ça capture aussi la console dans laquelle le programme s'exécute.
 
Est-il possible d'empêcher l'ouverture de cette fenêtre lors de l'exécution du programme ?

Reply

Marsh Posté le 06-03-2009 à 02:22:49    

$plitbErzing a écrit :


Par contre il y a juste un tout petit défaut, quand ça fait la capture, ça capture aussi la console dans laquelle le programme s'exécute.
Est-il possible d'empêcher l'ouverture de cette fenêtre lors de l'exécution du programme ?


Pour CodeBlocks dans le menu:
Project ---> properties ---> l'onglet "Build Target" ---> dans "Type" tu choisi "GUI Application" à la place de "Console Application"
Comme ça tu n'aura plu la console noire qui s'ouvre au moment de l'exécution.

Reply

Marsh Posté le 06-03-2009 à 02:22:49   

Reply

Marsh Posté le 06-03-2009 à 19:37:06    

Merci c'est bon ça marche :)

Reply

Marsh Posté le 07-03-2009 à 11:49:38    

tpierron a écrit :

Ouais, c'est mon jour de fête:


 
Et bien il aurait mieux valu s'abstenir que faire du mauvais copier-coller...
Memory leaks à la pelle et mauvaise méthode
Voir la méthode officielle et le code classique de Microsoft.
(et on sauvegarde en JPG, jamais en BMP !)
 

Reply

Marsh Posté le 07-03-2009 à 14:51:43    

Pat333 a écrit :

Et bien il aurait mieux valu s'abstenir que faire du mauvais copier-coller...
Memory leaks à la pelle et mauvaise méthode
Voir la méthode officielle et le code classique de Microsoft.

Ben, vas-y explique.
 

Citation :

(et on sauvegarde en JPG, jamais en BMP !)


Dans ton esprit psycho-rigide sans doute. Nan parce que t'as conscience que cette partie était à priori inutile, c'est juste plus convivial d'ouvrir un fichier BMP qu'avoir un dump hexa du contenu de la mémoire.

Reply

Marsh Posté le 07-03-2009 à 14:55:16    

tpierron a écrit :

Citation :

(et on sauvegarde en JPG, jamais en BMP !)


Dans ton esprit psycho-rigide sans doute. Nan parce que t'as conscience que cette partie était à priori inutile, c'est juste plus convivial d'ouvrir un fichier BMP qu'avoir un dump hexa du contenu de la mémoire.


Et de toute façon si on veut compresser, un screenshot ça se compresse pas en jpeg mais en png, faut être complètement con pour sortir du jpeg par défaut :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 11-03-2009 à 18:01:30    

Au fait le programme seul marche, mais dès que j' inclue la librairie allegro (#include <allegro.h> ) il me met une erreur de compilation !
 
C:/../include/wingdi.h:1351: error: conflicting types for 'BITMAP'
C:/../include/allegro/gfx.h:276: error: previous declaration of 'BITMAP' was here
 
Y a t-il un moyen de régler ce problème ?

Reply

Marsh Posté le 11-03-2009 à 18:29:05    

Difficile avec aussi peu d'info. En général l'ordre des fichiers inclus a une importance. Au cas où les headers des deux libs (gdi et allegro) sont effectivement en conflit, compile dans deux fichiers séparés : un dédié à gdi l'autre à allegro. Là, c'est sûr que tu n'auras plus de problème.
 
Edit: ouais, ça voudra donc dire de convertir la structure BITMAPINFO en un autre truc, pour éviter d'inclure les en-têtes liés à gdi. Pas terrible, d'autant que je suis certain que la lib allegro (même si je ne la connais pas) doit avoir pris en compte ce cas de figure. À tout hasard, montre les lignes qui contiennent les #include.


Message édité par tpierron le 11-03-2009 à 18:42:23
Reply

Marsh Posté le 11-03-2009 à 21:36:55    

GDI routines
...
To use these routines, you must include winalleg.h after Allegro headers.  
 
http://alleg.sourceforge.net/stabl [...] eg037.html


---------------
deluser --remove-home ptitchep
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed