Bonjour,

Je débute en langage C et je souhaite réaliser une application qui me permet de faire un screen shot sur un autre PC.
Le principe est le suivant:
- je lance serveur.exe sur un poste
- de mon poste je lance client.exe
- lorsque je clique sur le bouton screen shot, il fait une capture d'écran du poste serveur et l'enregistre dans le meme répertoire qu'ou se trouve client.exe

voici les codes des 2 programmes

Client.exe

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib/gprintf.h>
#include <winsock.h>
 
 
#define IP_SERVEUR	"192.168.51.33"
#define PORT_SERVEUR	4000
 
void Quit_appli(GtkWidget *pButton, gpointer data);
void Connection(GtkWidget *pButton, gpointer data);
void Deconnection(GtkWidget *pButton, gpointer data);
 
static GtkWidget *p_table;
static GtkWidget *p_window;
SOCKET sock;
 
int main(int argc, char **argv)
{
  GtkWidget *p_image_fond;
  GtkWidget *p_menu;
  GtkWidget *pLabel;
  GtkWidget *BtnOk;
  GtkWidget *p_button_connect;
  GtkWidget *p_button_image_connect;
  GtkWidget *p_button_deconnect;
  GtkWidget *p_button_image_deconnect;
  GtkWidget *p_button_quit;
  GtkWidget *p_button_image_quit;
  GList *list = NULL;
  gint i;
 
  /* Initialisation de GTK+ */
  gtk_init (&argc, &argv);
 
  /* Creation de la fenetre */
  p_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_decorated (GTK_WINDOW(p_window), FALSE); /* Fenetre sans bordure */
  gtk_window_set_position(GTK_WINDOW(p_window), GTK_WIN_POS_CENTER);
  g_signal_connect (G_OBJECT (p_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
 
  /* Creation de la table */
  p_table = gtk_table_new (100, 100, FALSE);
  gtk_container_add (GTK_CONTAINER (p_window), p_table);
 
  /* Creation du boutton Quitter */
  p_button_quit = gtk_button_new();
  p_button_image_quit = gtk_image_new_from_stock(GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
  gtk_container_add(GTK_CONTAINER(p_button_quit), p_button_image_quit);
  gtk_table_attach_defaults (GTK_TABLE (p_table), p_button_quit, 90, 97, 90, 97);
  g_signal_connect(G_OBJECT(p_button_quit), "clicked", G_CALLBACK(Quit_appli), (GtkWidget*) p_window);
 
  /* Creation du boutton Connection */
  p_button_connect = gtk_button_new();
  p_button_image_connect = gtk_image_new_from_stock(GTK_STOCK_CLEAR, GTK_ICON_SIZE_BUTTON);
  gtk_container_add(GTK_CONTAINER(p_button_connect), p_button_image_connect);
  gtk_table_attach_defaults (GTK_TABLE (p_table), p_button_connect, 90, 97, 3, 10);
  g_signal_connect(G_OBJECT(p_button_connect), "clicked", G_CALLBACK(Connection), (GtkWidget*) p_window);
 
  /* Creation du boutton Deconnection */
  p_button_deconnect = gtk_button_new();
  p_button_image_deconnect = gtk_image_new_from_stock(GTK_STOCK_PRINT, GTK_ICON_SIZE_BUTTON);
  gtk_container_add(GTK_CONTAINER(p_button_deconnect), p_button_image_deconnect);
  gtk_table_attach_defaults (GTK_TABLE (p_table), p_button_deconnect, 90, 97, 15, 22);
  g_signal_connect(G_OBJECT(p_button_deconnect), "clicked", G_CALLBACK(Deconnection), (GtkWidget*) p_window);
 
  /* Creation de l'arriere plan */
  p_image_fond = gtk_image_new_from_file ("C:/image/gtk.png");
  gtk_table_attach_defaults (GTK_TABLE (p_table), p_image_fond, 0, 100, 0, 100);
 
  /* Affichage de la fenetre */
  gtk_widget_show_all (p_window);
 
  /* Lancement de la boucle evenementielle */
  gtk_main();
 
  return EXIT_SUCCESS;
}
 
 
/* Fonction confirmation  quitter application */
void Quit_appli(GtkWidget* widget, gpointer data)
{
    GtkWidget *pQuestion;
 
    /* Creation de la boite de message */
    pQuestion = gtk_message_dialog_new (GTK_WINDOW(data),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_QUESTION,
        GTK_BUTTONS_YES_NO,
        "Voulez vous vraiment\nquitter ce programme?");
 
    /* Affichage et attente d une reponse */
    switch(gtk_dialog_run(GTK_DIALOG(pQuestion)))
    {
        case GTK_RESPONSE_YES:
            /* OUI -> on quitte l application */
            send(sock, "DECO", 4, 0);
	        closesocket(sock);
            gtk_main_quit();
            break;
        case GTK_RESPONSE_NO:
            /* NON -> on detruit la boite de message */
            gtk_widget_destroy(pQuestion);
            break;
    }
}
 
void Connection(GtkWidget* widget, gpointer data)
{
     WSADATA WSAData;
     SOCKADDR_IN sinfo;
     int Etat;
     int nb = 0;
     int nbr = 0;
     GtkWidget *pAbout;
     GtkWidget *pLabel;
     char buf[4096];
     FILE *bmp;
 
     WSAStartup(MAKEWORD(2,0),&WSAData);
     sock=socket(AF_INET,SOCK_STREAM,0);
     if (sock==INVALID_SOCKET)
        {
        pAbout = gtk_message_dialog_new (GTK_WINDOW(data),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_INFO,
        GTK_BUTTONS_OK,
        "Erreur: Creation socket impossible",
        NULL);
        gtk_dialog_run(GTK_DIALOG(pAbout));
        gtk_widget_destroy(pAbout);
        }
 
     sinfo.sin_addr.s_addr = inet_addr(IP_SERVEUR);
     sinfo.sin_family = AF_INET;
     sinfo.sin_port = htons(PORT_SERVEUR);
 
     Etat=connect(sock,(LPSOCKADDR)&sinfo,sizeof(sinfo));
     if (Etat==SOCKET_ERROR) 
        {
        pAbout = gtk_message_dialog_new (GTK_WINDOW(data),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_INFO,
        GTK_BUTTONS_OK,
        "Erreur: Connection au serveur impossible",
        NULL);
        gtk_dialog_run(GTK_DIALOG(pAbout));
        gtk_widget_destroy(pAbout);
        }
 
     else
     {
        pAbout = gtk_message_dialog_new (GTK_WINDOW(data),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_INFO,
        GTK_BUTTONS_OK,
        "Good: Connection etablie",
        NULL);
        gtk_dialog_run(GTK_DIALOG(pAbout));
        gtk_widget_destroy(pAbout);
     }
 
     send(sock, "begin", 7, 0);
     recv(sock, buf, sizeof(buf), 0);
     send(sock, "begin", 7, 0);
     bmp = fopen("shoots.bmp", "r");
 
     int taille = atoi(buf);
	while(nb < taille)
	{
		nbr = recv(sock, buf, sizeof(buf), 0);
		fwrite(buf, nbr, 4096, bmp);
 
		nb += nbr;
	}
	fclose(bmp);
	HBITMAP bit = (HBITMAP) LoadImage(0,"shoot.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
}
 
void Deconnection(GtkWidget *pButton, gpointer data)
{
     GtkWidget *pAbout1;
 
     send(sock, "DECO", 4, 0);
     closesocket(sock);
     pAbout1 = gtk_message_dialog_new (GTK_WINDOW(data),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_INFO,
        GTK_BUTTONS_OK,
        "Good: Deconnection etablie",
        NULL);
        gtk_dialog_run(GTK_DIALOG(pAbout1));
        gtk_widget_destroy(pAbout1);
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/**************************
 * Includes
 *
 **************************/
 
#include <windows.h>
#include <gl/gl.h>
#include <stdio.h>
#include <stdlib.h>
 
/**************************
 * Fonctions
 *
 **************************/
 
DWORD WINAPI serveur_colonel_connection(LPVOID lpParameter);
SOCKET server_connection(unsigned short portnum);
BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB);
 
 
/***********************/
/* Convertion d'un DDB en DIB */
/***********************/
 
HANDLE DDBToDIB(HBITMAP bitmap, DWORD dwCompression, HPALETTE pPal)
{
 BITMAP  bm;
 BITMAPINFOHEADER  bi;
 LPBITMAPINFOHEADER  lpbi;
 DWORD  dwLen;
 HANDLE  hDIB;
 HANDLE  handle;
 HDC  hDC;
 HPALETTE  hPal;
 
// The function has no arg for bitfields
 if(dwCompression == BI_BITFIELDS)
  return NULL;
 
// If a palette has not been supplied use defaul palette
 hPal = (HPALETTE) pPal;
 if(hPal == NULL)
  hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
 
// Get bitmap information
 GetObject(bitmap, sizeof(bm), (LPSTR)&bm);
 
// Initialize the bitmapinfoheader
 bi.biSize = sizeof(BITMAPINFOHEADER);
 bi.biWidth = bm.bmWidth;
 bi.biHeight = bm.bmHeight;
 bi.biPlanes = 1;
 bi.biBitCount = 8;
 bi.biCompression = dwCompression;
 bi.biSizeImage = 0;
 bi.biXPelsPerMeter = 0;
 bi.biYPelsPerMeter = 0;
 bi.biClrUsed = 0;
 bi.biClrImportant = 0;
 
// Compute the size of the  infoheader and the color table
 int nColors = (1 << bi.biBitCount);
 if(nColors > 256) 
  nColors = 0;
 dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
 
// We need a device context to get the DIB from
 hDC = GetDC(NULL);
 hPal = SelectPalette(hDC,hPal,FALSE);
 RealizePalette(hDC);
 
// Allocate enough memory to hold bitmapinfoheader and color table
 hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
 
 if(!hDIB)
 {
  SelectPalette(hDC,hPal,FALSE);
  ReleaseDC(NULL,hDC);
  return NULL;
 }
 
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 
 *lpbi = bi;
 
// Call GetDIBits with a NULL lpBits param, so the device driver 
// will calculate the biSizeImage field 
 GetDIBits(hDC, (HBITMAP)bitmap, 0L, (DWORD)bi.biHeight,
   (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
 
 bi = *lpbi;
 
// If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
 if(bi.biSizeImage == 0)
 {
  bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
      * bi.biHeight;
 
// If a compression scheme is used the result may infact be larger
// Increase the size to account for this.
  if(dwCompression != BI_RGB)
   bi.biSizeImage = (bi.biSizeImage * 3) / 2;
 }
 
// Realloc the buffer so that it can hold all the bits
 dwLen += bi.biSizeImage;
 
 if(handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
  hDIB = handle;
 
 else
 {
  GlobalFree(hDIB);
 
// Reselect the original palette
  SelectPalette(hDC,hPal,FALSE);
  ReleaseDC(NULL,hDC);
  return NULL;
 }
 
// Get the bitmap bits
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 
// FINALLY get the DIB
 BOOL bGotBits = GetDIBits(hDC, (HBITMAP)bitmap,
      0L, // Start scan line
      (DWORD)bi.biHeight, // # of scan lines
      (LPBYTE)lpbi // address for bitmap bits
      + (bi.biSize + nColors * sizeof(RGBQUAD)),
      (LPBITMAPINFO)lpbi, // address of bitmapinfo
      (DWORD)DIB_RGB_COLORS); // Use RGB for color table
 
 if(!bGotBits)
 {
  GlobalFree(hDIB);
 
  SelectPalette(hDC,hPal,FALSE);
  ReleaseDC(NULL,hDC);
  return NULL;
 }
 
 SelectPalette(hDC,hPal,FALSE);
 ReleaseDC(NULL,hDC);
 return hDIB;
}
 
 
/************************/
/* Ecriture du DIB sur le disque */
/************************/
 
BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB)
{
 BITMAPFILEHEADER hdr;
 LPBITMAPINFOHEADER lpbi;
 
 if (!hDIB)
  return FALSE;
 
 FILE *File;
 File = fopen(szFile, "ab");
 DWORD ff = GetLastError();
 
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 
 int nColors = 1 << lpbi->biBitCount;
 
// Fill in the fields of the file header
 hdr.bfType  = ((WORD) ('M' << 8) | 'B'); 
 hdr.bfSize  = GlobalSize (hDIB) + sizeof( hdr );
 hdr.bfReserved1  = 0;
 hdr.bfReserved2  = 0;
 hdr.bfOffBits  = (DWORD) (sizeof( hdr ) + lpbi->biSize + nColors * sizeof(RGBQUAD));
 
// Write the file header
 fwrite(&hdr, sizeof(hdr), 1, File);
 
// Write the DIB header and the bits
 fwrite(lpbi, GlobalSize(hDIB), 1, File);
 
 fclose(File);
 return TRUE;
}
 
 
/**********************/
/* Création d'un screen shot */
/**********************/
 
DWORD WINAPI serveur_colonel_connection(LPVOID lpParameter)
{
	char buf[4096];
	SOCKET new_sock;
	FILE *bmp;
	new_sock = (SOCKET)lpParameter;
	if(new_sock == INVALID_SOCKET) 
	{
		fprintf(stderr, "Error waiting for new connection!\n");
		exit(1);
	}
	else
	{
		while(1)
		{
                memset(buf, 0, sizeof(buf));
                recv(new_sock, buf, sizeof(buf), 0);
                if (strstr(buf, "DECO") != 0)
                {
                                break;
                }
                remove("shoots.bmp");
                SaveDesktopAsFile("shoots.bmp");
                bmp = fopen("shoots.bmp", "r");
 
                fseek(bmp, 0, SEEK_END);
                int taillei = ftell(bmp);
                fseek(bmp, 0, SEEK_SET);
                itoa(taillei, (char *)buf, 10);
                send(new_sock, buf, strlen(buf), 0);
                recv(new_sock, buf, sizeof(buf), 0);
				if (strstr(buf, "DECO") != 0)
                {
                                break;
                }
                int i;
                i = fread(buf, 4096, 4096, bmp);
                while(i != 0)
                {
                        send(new_sock, buf, i, 0);
                        fread(buf, 4096, 4096, bmp);
                }
                fclose(bmp);
        }
	}
	closesocket(new_sock);
	return(0);
}
 
 
/********************/
/* Connection au serveur */
/********************/
 
SOCKET server_connection(unsigned short portnum)
{
	char myname[256] = "loopback";
	SOCKET s;
	struct sockaddr_in sa;
	struct hostent *hp;
	memset(&sa, 0, sizeof(struct sockaddr_in)); 
	gethostname(myname, sizeof(myname)); 
	hp = gethostbyname(myname); 
	if (hp == NULL) 
		return(INVALID_SOCKET);
	sa.sin_family = hp->h_addrtype; 
	sa.sin_port = htons(portnum); 
	s = socket(AF_INET, SOCK_STREAM, 0); 
	if (s == INVALID_SOCKET)
		return INVALID_SOCKET;
 
	if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
    {
		closesocket(s);
		return(INVALID_SOCKET);
	}
	listen(s, 5);
	return(s);
}
 
 
/**********************************/
/* Sauvegarde du screenshot dans un fichier */
/**********************************/
 
int SaveDesktopAsFile(LPTSTR szFile)
{
 HWND pWnd = GetDesktopWindow();
 HBITMAP bitmap;
 HDC dc = GetDC(pWnd);
 HDC   memDC;
 RECT  rect;
 
 memDC = CreateCompatibleDC(dc);
 GetWindowRect(pWnd, &rect);
 bitmap = CreateCompatibleBitmap(dc,640, 480);
 HBITMAP pOldBitmap = (HBITMAP)SelectObject(memDC, bitmap);
 StretchBlt(memDC, 0, 0,640, 480, dc , 0, 0, rect.right-rect.left, rect.bottom-rect.top, SRCCOPY);
 HPALETTE pal;
 
 UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
 LOGPALETTE *pLP = (LOGPALETTE *) malloc (nSize);
 pLP->palVersion = 0x300;
 
 pLP->palNumEntries = GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
 
 pal = CreatePalette(pLP);
 free (pLP);
 
 HANDLE hDIB = DDBToDIB( bitmap, BI_RLE8, pal );
 
 if( hDIB == NULL )
  return FALSE;
 
 SelectObject(memDC, pOldBitmap);
 WriteDIB(szFile, hDIB);
 
 GlobalFree(hDIB);
 return TRUE;
}
 
 
/**************************
 * Programme Principal
 *
 **************************/
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	WSADATA  wsa;  
	WORD  wVersionRequested;
	HANDLE  ServeurThread;
	SOCKET  ss;
 
	wVersionRequested = MAKEWORD( 2, 0 );
	if (WSAStartup(wVersionRequested , &wsa)!=0)    
	{
		printf("Winsock Initialization failed.\n");      
		return -1;    
	}
 
	if ((ss = server_connection(4000)) == INVALID_SOCKET) 
	{ 
		printf("La connection a échoué !!!");                     
		exit(1);
	}
	for (;;) 
	{ 
		SOCKET new_sock = accept(ss, NULL, NULL);
		ServeurThread = CreateThread (NULL, 0, serveur_colonel_connection, (LPVOID)new_sock, 0, NULL);
	}
	return 0;
}
 
int Ftaille(int A)
{
	lseek(A,0,2);		
	int tf= tell(A);	
	lseek(A,0,0);		
	return tf;		
}
le code client utilise la libraire GTK.

Il y a quelques petites choses qui ne sont pas au point et c'est la que je demande de l'aide.
- le screen shot est réaliser mais il s'enregistre dans le répertoire du serveur.exe et non pas celui du client.exe
- apres avoir fait un screen shot, le programme se fige, on ne peut plus rien faire, ni faire un autre screen shot ni meme quitter l'application.

Quelles modifications doit-je apporter pour remédier a cela?

Merci pour votre aide ++