La gestion des redraws des fenêtres est relativement simple sur GEM et répétitive et peut se découper en actions élémentaires comme suit:
On a obtenu un message du système de type WM_REDRAW, dans le buffer on obtient alors la zone totale à redessinner et le numéro de la fenêtre concernée.
Réservation de l'écran pour éviter que 2 applications n'écrivent à l'écran en même temps (wind_update())
Effacement de la souris (graf_mouse())
Recherche du premier rectangle de redessin pour la fenetre (wind_get())
Intersection de ce rectangle avec la zone à dessiner (rc_intersect())
Clipping sur le rectangle calculé par surreté (vs_clip())
Redessin dans le rectangle calculé par le programmeur
Boucle de recherche des autres rectangles de la fenêtre jusqu'a ce qu'il n'y en ai plus
Réapparition de la souris (graf_mouse())
Restitution de l'écran (wind_update())
Comme un exemple vaut mieux qu'un long discours, vous pouvez voir ci dessous un petit exemple en C de gestion de ces redessins.
int area[4], nowhere, x, y, w, h; while(!wind_update(BEG_UPDATE)); /* Réservation de l'écran si wind_update renvoi 0 c'est qu'il y a une autre application en train de faire du resssin, BEG_UPDATE=1 */ graf_mouse(M_OFF,&nowhere); /* suppression de la souris, M_OFF=256 */ if(wind_get(handle,WF_FIRSTXYWH,&x,&y,&w,&h)) /* recherche du premier rectangle, WF_FIRSTXYWH=11 */ { area[0]=x; area[1]=y; area[2]=w; area[3]=h; if(rc_intersect(inside,area))&&(w!=0)&&(h!=0)) /* calcul de l'intersection entre inside le rectangle donné par WM_REDRAW et area, le résultat est recopié dans area */ { vs_clip(vdihandle,area); /* clipping pour le VDI si on l'utilise c'est plus prudent */ /* mettre ici votre procedure de redessin */ } } while((w!=0)&&(h!=0)) { if(wind_get(handle,WF_NEXTXYWH,&x,&y,&w,&h)) /* recherche du prochain rectangle, WF_NEXTXYWH=12 */ { area[0]=x; area[1]=y; area[2]=w; area[3]=h; if(rc_intersect(inside,area))&&(w!=0)&&(h!=0)) /* calcul de l'intersection entre inside le rectangle donné par WM_REDRAW et area, le résultat est recopié dans area */ { vs_clip(vdihandle,area); /* clipping pour le VDI si on l'utilise c'est plus prudent */ /* mettre ici votre procedure de redessin */ } } } graf_mouse(M_ON,&nowhere); /* Réapparition de la souris, M_ON=257 */ wind_update(END_UPDATE); /* Fin de la réservation de l'écran END_UPDATE=0 */
Olivier Landemarre