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