Gdi et dessin

cs_Arkko Messages postés 192 Date d'inscription mercredi 26 décembre 2001 Statut Membre Dernière intervention 31 janvier 2007 - 28 oct. 2003 à 00:22
cs_Arkko Messages postés 192 Date d'inscription mercredi 26 décembre 2001 Statut Membre Dernière intervention 31 janvier 2007 - 30 oct. 2003 à 03:12
Je dessine quelque chose sur mon dialog avec gdi (fonction Rectangle) et quand je la reduit et la remet ... le dessin s'efface ... mais le dessin est generer par l'utilisateur (ex. paint ) comment faire pour quil ne s'efface pas
merci
@+ arkko

10 réponses

garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
28 oct. 2003 à 08:45
Il s'efface toujours puisque tu ne le vois plus à l'écran!
En fait à chaque fois que la fenêtre réapparait elle émet WM_PAINT. C'est en captant cet événement que tu dois tout redessiné. Eventuellement tu peux enregistrer ton image dans un buffer à chaque fois que ta fenêtre est masquée et le remettre d'un coup quand elle réapparait (c'est plus ou moins ce qu'on appelle du double-buffering)
0
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
28 oct. 2003 à 12:04
T'es sur que c'est ce que l'on appelle le double buffering ??

Ici il n'y a pas deux buffer, non ?

En win32, tu dois etre capable a tout instant de redessiner une partie de ta fenetre sur demande de Windows. Celui-ci t'envoie un message WM_PAINT a ta procedure :

switch(iMsg)
{
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;

hdc = BeginPaint(hwnd,&ps);
... // tes operations graphiques
// tu genres :
MoveToEx(hdc,0,0,NULL);
LineTo(hdc,50,50);
EndPaint(hwnd,&ps);
return 0;
}
}
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
28 oct. 2003 à 12:14
D'abord j'ai écrit que c'était plus ou moins du double-buffering....et en plus il y a deux buffers : celui qui est utilisé pour affiché à l'écran et celui où l'on écrit virtuellement.
0
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
28 oct. 2003 à 12:27
J'ai bien compris ce que tu as dis, mais je ne comprend pas : il n'y a qu'un buffer : celui dans lequel on ecrit <=> celui qui est afficher, non ?

On n'est pas en OpenGL, ou la effectivement il y a deux buffer.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
28 oct. 2003 à 15:23
La technique du double buffering n'est pas spécifique à OpenGL ! C'est juste un truc qui évite de voir les différentes parties d'un composant graphique se dessiner au fur et à mesure. Le principe c'est qu'au lieu de dessiner à l'écran car partie d'un dessin on le fait dans un écran virtuel (le buffer). Une fois qu'on a terminé de dessiner dans le buffer on remplace l'affichage de l'écran par le buffer d'un seul coup. Ainsi ça ne clignote pas quand on efface des trucs ou quand il y a des animations, ...
0
cs_Arkko Messages postés 192 Date d'inscription mercredi 26 décembre 2001 Statut Membre Dernière intervention 31 janvier 2007
29 oct. 2003 à 00:25
Ouais mais mon programme c'Est un espece de paint (le user dessine) donc ds paint je ne peux pas vriament dessiner des rectangles :) la methode du buffering semble interessente .. pouvez vous me l'explique en profondeur avec du code si possible
merci
0
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
29 oct. 2003 à 09:56
//***********************************************
#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
//***********************************************

int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
)
{
static char szAppName[] = "ExemplePourArkko";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;

wndclass.cbSize = sizeof (wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);

RegisterClassEx(&wndclass);

hwnd = CreateWindow(
szAppName, // nom de la classe
szAppName, // titre de la fenetre
WS_OVERLAPPED | WS_SYSMENU, // style de la fenetre
CW_USEDEFAULT, // position initiale en x
CW_USEDEFAULT, // position initiale en y
512, // largeur initiale
512, // hauteur initiale
NULL, // handle de la fenetre mere
NULL, // handle du menu de la fenetre
hInstance, // handle de l'instance
NULL); // parametres de creation

ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(
HWND hwnd,
UINT iMsg,
WPARAM wParam,
LPARAM lParam
)
{
static int cx,cy;
switch (iMsg)
{
case WM_CREATE:
{
return 0;
}
case WM_SIZE:
{
cx = LOWORD(lParam);
cy = HIWORD(lParam);
break;
}
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;

hdc = BeginPaint(hwnd,&ps);
Rectangle(hdc,cx/4,cy/4,3*cx/4,3*cy/4);
EndPaint(hwnd,&ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage (0);
return 0;
}
}

return DefWindowProc(hwnd,iMsg,wParam,lParam);
}
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
29 oct. 2003 à 14:05
Si tu veux pouvoir redessiner à l'écran à tout momment ce que l'utilisateur à fait, il suffit de stocker son dessin dans un bitmap.

1) Au début d'un nouveau dessin, créer un DC et un bitmap en mémoire compatible avec le DC de la fenêtre (hWnd) où il sera affiché :
HDC hdc = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hdc);
HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, cx, cy);
HBITMAP hOldBmp = SelectObject(hMemDC, hMemBmp);

les variables hMemDC, hMemBmp et hOldBmp doivent être globale. hOldBmp servira pour restaurer l'état du GDI à la fin.

2) Ensuite, quand tu traite les opération de dessin de l'utilisateur, au lieu de dessiner dans le DC de ta fenêtre, utilise celui en mémoire (hMemDC), exactement de la même façon.

3) Quand la fenêtre aura besoin d'être dessinée, (message WM_PAINT), il suffit de recopier ton DC en mémoire :

HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);

BitBlt(hdc, 0, 0, cx, cy, hMemDC, 0, 0);

EndPaint(hWnd,&ps);

4) Enfin, à la fin de l'appli, il faut libérer le DC:
SelectObject(hMemDC, hOldBmp);
DeleteObject(hMemBmp);
DeleteDC();

Un conseille pour éviter un clignotement de l'écran lors des dessins :
- Ne pas effacer le fond de l'écran mais celui du bitmap en mémoire puis le recopier.
- Utiliser InvalidateRect(hWnd, NULL, FALSE);pour mettre à jour l'écran sans que le fond de l'écran soit effacer à haque fois.
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
29 oct. 2003 à 14:06
J'ai oublié un paramètre à la fonction BitBlt :

BitBlt(hdc, 0, 0, cx, cy, hMemDC, 0, 0, SRCCOPY);
0
cs_Arkko Messages postés 192 Date d'inscription mercredi 26 décembre 2001 Statut Membre Dernière intervention 31 janvier 2007
30 oct. 2003 à 03:12
merci :D
0
Rejoignez-nous