[Back to MOUSE SWAG index] [Back to Main SWAG index] [Original]
{ AUTEUR : AVONTURE Christophe
BUT DE L'UNITE : FOURNIR LES FONCTIONS DE GESTION DE LA SOURIS
DATE DE REDACTION : 8 MARS 1996
DERNIERE MODIF. : 8 MARS 1996 }
UNIT uMouse;
INTERFACE
TYPE
cgCoord = (cgPixel, cgCharacter);
CONST
{ Nombre de Handle actuellement associ� au Handler de la souris }
cgCurrentProc : Byte = 0;
{ Autorise l'appel aux diff�rentes proc�dures cr��es par les Handler ou
interdit leur appel. }
cgEnableMouseProc : Boolean = True;
{ D�finit si les coordonn�es sont � consid�rer comme �tant relatifs � des
pixels ou bien relatifs � des caract�res }
cgCoordonnees : cgCoord = cgPixel;
TYPE
{ Constantes Boutons enfonc�s }
cgMouse_Key = (cgMouse_None, cgMouse_Left, cgMouse_Right, cgMouse_Both);
{ Structure permettant d'associer une proc�dure lorsque le clic de la
souris se fait dans le rectangle d�limit� par
(XMin, YMin) -------------- (XMax, YMin)
: :
: :
(XMin, YMax) -------------- (XMax, YMax) }
TProcedure = PROCEDURE;
TMouseHandle = RECORD
XMin, XMax, YMin, YMax : Word;
Adress_Proc : TProcedure;
END;
{ Lorsque l'utilisateur clic en un certain endroit, si cet endroit est
compris dans le rectangle sp�cifi� ci-dessus, alors il faudra ex�cuter
une certaine proc�dure.
On va pouvoir sp�cifier autant de surfaces diff�rentes. La seule
restriction sera la m�moire disponible.
Ainsi, on pourra dessiner un bouton OK, un bouton CLOSE, ... et leur
associer un �v�nement qui leur est propre.
Cela sera obtenu par la gestion d'un liste cha�n�e vers le haut. }
TpListMouseHandle = ^TListMouseHandle;
TListMouseHandle = RECORD
Next : TpListMouseHandle;
Item : TMouseHandle;
END;
VAR
{ Liste cha�n�e des diff�rents handles associ�s au handler de la souris }
MouseProc : TpListMouseHandle; { Zone de travail }
MouseProcFirst : TpListMouseHandle; { Tout premier �v�nement }
MouseProcOld : TpListMouseHandle; { Sauvegarde de l'ancien �v�nement }
{ True si un gestionnaire de souris est pr�sent }
bMouse_Exist : Boolean;
{ Coordonn�es du pointeur de la souris }
cgMouse_X : Word;
cgMouse_Y : Word;
{ Correspondant du LastKey. Contient la valeur du dernier bouton
enfonc� }
cgMouse_LastButton : cgMouse_Key;
{ Lorsque le clic ne se fait pas dans une des surfaces couvertes par les
diff�rents handlers (voir AddMouseHandler); on peut ex�cuter une
certaine proc�dure. }
hClicNotInArea : Pointer;
PROCEDURE Mouse_Show;
PROCEDURE Mouse_Hide;
PROCEDURE Mouse_GoToXy (X, Y : Word);
PROCEDURE Mouse_Window (XMin, XMax, YMin, YMax : Word);
PROCEDURE Mouse_AddHandler (XMin, XMax, YMin, YMax : Word; Adress : TProcedure);
PROCEDURE Mouse_RemoveHandler;
PROCEDURE Mouse_Handle;
PROCEDURE Mouse_Flush;
FUNCTION Mouse_Init : Boolean;
FUNCTION Mouse_Pressed : cgMouse_Key;
FUNCTION Mouse_InArea (XMin, XMax, YMin, YMax : Word) : Boolean;
FUNCTION Mouse_ReleaseButton (Button : cgMouse_Key) : Boolean;
{ ------------------------------------------------------------------------ }
IMPLEMENTATION
{ Teste si un gestionnaire de souris est pr�sent }
FUNCTION Mouse_Init : Boolean;
BEGIN
ASM
Xor Ax, Ax
Int 33h
Mov Byte Ptr bMouse_Exist, Ah
END;
END;
{ Cache le pointeur de la souris }
PROCEDURE Mouse_Hide; ASSEMBLER;
ASM
Mov Ax, 02h
Int 33h
END;
{ Montre le pointeur de la souris }
PROCEDURE Mouse_Show; ASSEMBLER;
ASM
Mov Ax, 01h
Int 33h
END;
{ Retourne une des constantes �quivalents aux boutons enfonc�s. Retourne 0
si aucun bouton n'a �t� enfonc� }
FUNCTION Mouse_Pressed : cgMouse_Key; ASSEMBLER;
ASM
Mov Ax, 03h
Int 33h
{ Bx contiendra 0 si aucun bouton n'a �t� enfonc�
1 bouton de gauche
2 bouton de droite
3 bouton de gauche et bouton de droite
4 bouton du milieu }
Mov Ax, Bx
Mov cgMouse_X, Cx
Mov cgMouse_Y, Dx
Mov cgMouse_LastButton, Al
END;
{ Positionne le curseur de la souris }
PROCEDURE Mouse_GoToXy (X, Y : Word); ASSEMBLER;
ASM
Mov Ax, 04h
Mov Cx, X
Mov Dx, Y
Int 33h
END;
{ D�finit la fen�tre dans laquelle le curseur de la souris peut �voluer }
PROCEDURE Mouse_Window (XMin, XMax, YMin, YMax : Word); ASSEMBLER;
ASM
Mov Ax, 07h
Mov Cx, XMin
Mov Dx, XMax
Int 33h
Mov Ax, 08h
Mov Cx, YMin
Mov Dx, YMax
Int 33h
END;
{ Teste si le curseur de la souris se trouve dans une certaine surface }
FUNCTION Mouse_InArea (XMin, XMax, YMin, YMax : Word) : Boolean;
BEGIN
IF NOT bMouse_Exist THEN
Mouse_InArea := False
ELSE
BEGIN
{ Les coordonn�es sont-elles � consid�rer comme pixels ou comme
caract�res }
IF cgCoordonnees = cgPixel THEN
BEGIN
IF NOT (cgMouse_X < XMin) AND NOT (cgMouse_X > XMax) AND
NOT (cgMouse_Y < YMin) AND NOT (cgmouse_y > YMax) THEN
Mouse_InArea := True
ELSE
Mouse_InArea := False
END
ELSE
BEGIN
{ Il s'agit de caract�res. Or un caract�re fait 8 pixels de long.
Donc, lorsque l'on programme (0,1,0,1, xxx), il s'agit du
caract�re se trouvant en (0,0) qui se trouve en r�alit� en
0..7,0..15 puisqu'il fait 8 pixels de long sur 16 de haut. }
IF NOT (cgMouse_X Shr 3 < XMin ) AND
NOT (cgMouse_X Shr 3 > XMax ) AND
NOT (cgMouse_Y Shr 3 < YMin ) AND
NOT (cgmouse_y Shr 3 > YMax ) THEN
Mouse_InArea := True
ELSE
Mouse_InArea := False;
END;
END;
END;
{ Ajoute un �v�nement. }
PROCEDURE Mouse_AddHandler (XMin, XMax, YMin, YMax : Word; Adress : TProcedure);
BEGIN
IF bMouse_Exist THEN
BEGIN
{ On peut ajouter un �v�nement pour autant qu'il reste de la m�moire
disponible pour le stockage du pointeur sur la proc�dure et de la
sauvegarde des coordonn�es de la surface d�limit�e pour son action. }
IF MemAvail > SizeOf(TListMouseHandle) THEN
BEGIN
Inc (cgCurrentProc);
IF cgCurrentProc = 1 THEN
BEGIN
{ C'est le tout premier �v�nement. Sauvegarde du pointeur
pour pouvoir ensuite fabriquer la liste. }
New (MouseProc);
MouseProcFirst := MouseProc;
{ Sauvegarde du pointeur courant pour pouvoir fabriquer la
liste. }
MouseProcOld := MouseProc;
{ Etant donn� que le liste se rempli de bas en haut -le
premier introduit est le moins prioritaire, ...-; seul le
premier aura un pointeur vers NIL. Cette m�thode permettra
� un �v�nement de recouvrir une surface d�j� d�limit�e par
un autre objet. }
MouseProc^.Next := NIL;
END
ELSE
BEGIN
{ Ce n'est pas le premier. Il faut que je cr�e le lien avec
le pointeur NEXT de l'�v�nement pr�c�dent. }
MouseProcOld := MouseProc;
New (MouseProc);
MouseProc^.Next := MouseProcOld;
MouseProcFirst := MouseProc;
END;
{ Les liens cr��s, je peux en toute s�curit� sauvegarder les
donn�es. }
MouseProc^.Item.XMin := XMin;
MouseProc^.Item.XMax := XMax;
MouseProc^.Item.YMin := YMin;
MouseProc^.Item.YMax := YMax;
MouseProc^.Item.Adress_Proc := Adress;
END;
END;
END;
{ Cette proc�dure retire le tout dernier �v�nement introduit tout en
conservant la coh�rence de la liste. }
PROCEDURE Mouse_RemoveHandler;
BEGIN
IF bMouse_Exist THEN
BEGIN
IF NOT (MouseProc^.Next = NIL) THEN
BEGIN
MouseProcFirst := MouseProc^.Next;
Dispose (MouseProc);
MouseProc := MouseProcFirst;
Dec (cgCurrentProc);
END;
END;
END;
{ Examine si le clic s'est fait dans une surface d�limit�e par un �v�nement.
Si c'est le cas, alors appel de l'�v�nement en question. }
PROCEDURE Mouse_Handle;
VAR
bFin : Boolean;
bNotFound : Boolean;
BEGIN
IF bMouse_Exist THEN
BEGIN
{ Il doit y avoir un process uniquement si on a associ� des �l�ments au
handler de la souris. ET SEULEMENT SI LES APPELS AUX DIFFERENTES
PROCEDURES SONT AUTORISES OU NON. }
IF cgEnableMouseProc AND (cgCurrentProc > 0) THEN
BEGIN
bFin := False;
{ bNotFound sera mis sur True lorsque le clic s'est fait dans une
surface non couverte par un handler. }
bNotFound := False;
{ Pointe sur le tout premier �v�nement }
MouseProcOld := MouseProcFirst;
REPEAT
IF Mouse_InArea (MouseProcOld^.Item.XMin, MouseProcOld^.Item.XMax,
MouseProcOld^.Item.YMin, MouseProcOld^.Item.YMax) THEN
BEGIN
{ Le clic s'est fait dans une surface � surveiller. Appel
de l'�v�nement ad'hoc. }
MouseProcOld^.Item.Adress_Proc;
bFin := True;
END
ELSE
IF (MouseProcOld^.Next = NIL) THEN
BEGIN
bNotFound := True;
bFin := True
END
ELSE
MouseProcOld := MouseProcOld^.Next;
UNTIL bFin;
{ IF bNotFound THEN
ASM
Call hClicNotInArea;
END;}
END;
END;
END;
{ Retourne TRUE lorsque l'utilisateur maintien le bouton xxx enfonc� et
renvoi FALSE lorsque ce bouton est rel�ch�. }
FUNCTION Mouse_ReleaseButton (Button : cgMouse_Key) : Boolean; ASSEMBLER;
ASM
Mov Ax, 06h
Mov Bx, 01h
Int 33h
END;
{ Cette proc�dure va attendre jusqu'� ce que le dernier bouton enfonc� ne
le soit plus; autrement dit jusqu'� ce que l'utilisateur rel�che ce m�me
bouton. Ce qui aura pour effet de vider le buffer de la souris. }
PROCEDURE Mouse_Flush;
BEGIN
IF bMouse_Exist THEN
REPEAT
UNTIL NOT (Mouse_ReleaseButton(cgMouse_LastButton));
END;
{ Initialisation }
BEGIN
{ Initialise le boolean d'existence d'un gestionnaire de souris }
Mouse_Init;
{ Positionne le curseur de la souris en (0,0) }
Mouse_GotoXy (0,0);
END.
[Back to MOUSE SWAG index] [Back to Main SWAG index] [Original]