bonjour,
est-il possible de générer un fichier image (.bmp, .jpg, ...) à partir d'une CDialog, c'est à dire de faire une "capture d'écran" du contenu de la CDialog?
merci
bonjour,
est-il possible de générer un fichier image (.bmp, .jpg, ...) à partir d'une CDialog, c'est à dire de faire une "capture d'écran" du contenu de la CDialog?
merci
tu fais un CDC en mémoire, tu y attache un CBitmap et tu fais un BitBlt avec le DC de ta CDialog
Regarde ce post, c'est le même principe mais dnas lautre sens :
http://www.developpez.net/forums/vie...=memdc+cbitmap
à quel moment je précise le nom du fichier dans lequel je veux enregistrer?
si t'est sous VC 6, ben il faut le coder :
regarde :
http://www.codeguru.com/Cpp/G-M/bitm...cle.php/c1697/
Sinon, sous .NET u peut utiliser un objet CPicture je crois....
merci
malheureusement, je n'arrive pas à faire marcher ce code, et je ne le comprend pas tres bien...
cette fonction prend un argument de type HANDLE, qu'est ce que je dois lui passer? moi j'ai un CDC* ...
je rappelle l'entete de la fonction:
pour le 2eme paramètre (hDIB) je passe un CDC*
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
mais ca plante sur, alors j'ai remplacé ceci par
Code : Sélectionner tout - Visualiser dans une fenêtre à part GlobalSize(hDIB)Dans ce cas, l'image crée ne fait que 18o et je ne peut pas l'ouvrir...
Code : Sélectionner tout - Visualiser dans une fenêtre à part sizeof(hDIB)
hDib n'est pas un pointeur sur un CDC mais sur HBITMAP
Tu peut l'obtenir à partir d'un CBitmap associé à un MemDC comme expliqué dans le lien que je t'ai donné.
GlobalSize ne doit pas être remplacé par sizeof car il te renvoi la taille de ton handle + les bits de l'image, alors que sizeof ne te renvoi que la taille du handle.
HBITMAP ou pointeur sur HBITMAP?
avec un pointeur sur HBITMAP ca ne fait pas d'erreur mais l'image créée ne peut pas etre ouverte.
avec un HBITMAP ca bloque sur
je suppose que le cast ne se fait pas bien
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount;
HBITMAP, autant pour moi...Envoyé par meli0207
Tu as une messagebox qui te dis que tu n'as pas le droit d'aceder au fichier ?Envoyé par meli0207
car apparement il manque la fermeture du fichier dans le code du lien
rajoute :
avant
Code : Sélectionner tout - Visualiser dans une fenêtre à part file.Close();
Code : Sélectionner tout - Visualiser dans une fenêtre à part return TRUE;
ca ne marche toujours pas.
je n'ai pas la boite d'erreur que tu dis, mais un message "aucun apercu n'est disponible"
Bon ben en fait c'est pas clair mais il faut utiliser plusieurs méthode de différents articles de codeguru.
En fait il existe une foncion qui écrit directement une CDialog dans un fichier, pour ça utilise la Fonction WriteWindowToDIB passe this dans le param CWnd*
Moi je les ai mis dnas ma classe outils et ça marche :
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 /*******************************************************************************/ //LPTSTR szFile : DestFile //HANDLE hDIB : Handle sur un DIB /*******************************************************************************/ BOOL COutils::WriteDIB( LPTSTR szFile, HANDLE hDIB) { BITMAPFILEHEADER hdr; LPBITMAPINFOHEADER lpbi; if (!hDIB) return FALSE; CFile file; if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) ) return FALSE; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount; // Fill in the fields of the file header hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM" 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 file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits file.Write( lpbi, GlobalSize(hDIB) ); file.Close(); return TRUE; }
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 /*******************************************************************************/ //WriteWindowToDIB //LPTSTR DestFile //Pointeur sur un CWnd /*******************************************************************************/ BOOL COutils::WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd ) { CBitmap bitmap; CWindowDC dc(pWnd); CDC memDC; CRect rect; memDC.CreateCompatibleDC(&dc); pWnd->GetWindowRect(rect); bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() ); CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY); // Create logical palette if device support a palette CPalette pal; if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry ); // Create the palette pal.CreatePalette( pLP ); delete[] pLP; } memDC.SelectObject(pOldBitmap); // Convert the bitmap to a DIB HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal ); if( hDIB == NULL ) return FALSE; // Write it to file WriteDIB( szFile, hDIB ); // Free the memory allocated by DDBToDIB for the DIB GlobalFree( hDIB ); return TRUE; }
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 /*******************************************************************************/ // DDBToDIB - Creates a DIB from a DDB // bitmap - Device dependent bitmap // dwCompression - Type of compression - see BITMAPINFOHEADER // pPal - Logical palette /*******************************************************************************/ HANDLE COutils::DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal ) { BITMAP bm; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; DWORD dwLen; HANDLE hDIB; HANDLE handle; HDC hDC; HPALETTE hPal; ASSERT( bitmap.GetSafeHandle() ); // 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->GetSafeHandle(); if (hPal==NULL) hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; 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.GetSafeHandle(), 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.GetSafeHandle(), 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; }
avec cette méthode, l'image créée a une taille plus raisonnable (650Ko) mais lorsque j'essaie de l'ouvrir, j'ai un message "le dessin a échoué"
chez moi ça marche !!!
tu utilise WriteWindowToDIB ?
oui j'utilise WriteWindowToDIB
voici mon code :
ce que j'appelle panel, c'est la CDialog en question
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 void CInterface3Dlg::OnButton3() { MemDC = new CDC(); MemDC->CreateCompatibleDC(panel->dc); CBitmap *Bmp = new CBitmap(); Bmp->CreateCompatibleBitmap(panel->dc,200,200); //Attacher le BMP au CDC; HBITMAP OldBMP = (HBITMAP) MemDC->SelectObject((HBITMAP)Bmp->GetSafeHandle()); MemDC->BitBlt(0,0, 500, 500, panel->dc, 0, 0, SRCCOPY); WriteWindowToDIB("test.bmp", panel); MessageBox("fini"); }
J'ai repris tes 3 fonctions, j'ai juste enlevé COutils::
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager