

                  Mausprogrammierung in Pascal
                  ----------------------------

Ah, da seit ihr ja endlich... sicherlich habt ihr gerade den
Artikel ber die Mausprogrammierung 'Allgemein' gelesen und
wollt nun wissen, wie man das in Pascal macht, stimmt's? Nein!?!
Na dann eben nicht! (Schmoll...:-))

Nun ja, dann wollen wir mal:

Da sich in Pascal die berall beliebte UNIT-Form so schn macht,
werde auch ich hier eine Unit zum Besten geben.

Unterscheiden mu ich hier am Anfang mal direkt in der Program-
mierungsart: Alle, die noch kein Turbo Pascal 6 besitzen, mssen
weiterhin mit der Unit DOS arbeiten, um so Zugriff auf die Regis-
ter zu erhalten. Alle anderen (> TP6) knnen und sollten den in-
tegrierten Assembler benutzen.

Zum Programmieren:
  TP5 und kleiner:


   USES DOS;

   VAR Regs : Registers;

   PROCEDURE ResetMouse;
   BEGIN
    WITH Regs DO BEGIN
     AX := 0;      {AX mit 0 laden --> MouseTreiber zurcksetzen}
     INTR($33,Regs); {Interrupt 33h aufrufen}
    END;
   END;

  TP6 und hher:


   PROCEDURE ResetMouse; ASSEMBLER;
   ASM
    MOV AX,0       {AX mit 0 laden --> MouseTreiber zurcksetzen}
    INT 33h        {Interrupt 33h aufrufen}
   END;

Das sei hier zum Anfang ersteinmal gesagt. Im folgenden Text wer-
de ich mich nur auf TP6 beziehen (also Assembler-Code), doch soll-
te die Anpassung an TP5 nicht allzu schwer sein (siehe oben).


UNIT Maus;

INTERFACE

 PROCEDURE InitMouse;
 PROCEDURE ShowCursor;
 PROCEDURE HideCursor;
 PROCEDURE SetMousePos(x,y:WORD);
 FUNCTION XPos : WORD;
 FUNCTION YPos : WORD;
 FUNCTION LeftButtonPressed : BOOLEAN;
 FUNCTION RightButtonPressed : BOOLEAN;
 PROCEDURE WaitForLeftButtonRelease;
 PROCEDURE WaitForRightButtonRelease;
 PROCEDURE SetXYRange(MinX,MaxX,MinY,MaxY : WORD);

IMPLEMENTATION

PROCEDURE InitMouse; ASSEMBLER;
ASM
 XOR AX,AX                   {AX auf 0}
 INT 33h                     {Aufruf: Interrupt 33h}
END;

PROCEDURE ShowCursor; ASSEMBLER;
ASM
 MOV AX,1
 INT 33h
END;

PROCEDURE HideCursor; ASSEMBLER;
ASM
 MOV AX,2
 INT 33h
END;

PROCEDURE SetMousePos(x,y:WORD); ASSEMBLER;
ASM
 MOV AX,4
 MOV CX,x                    {X-Koordinate nach CX}
 MOV DX,y                    {Y-Koordinate nach DX}
 INT 33h
END;

FUNCTION XPos : WORD; ASSEMBLER;
ASM
 MOV AX,3
 INT 33h
 MOV AX,CX     {FUNCTION-Wert geht durch's AX-Register zurck!}
END;

FUNCTION YPos : WORD; ASSEMBLER;
ASM
 MOV AX,3
 INT 33h
 MOV AX,DX     {FUNCTION-Wert geht durch's AX-Register zurck!}
END;

FUNCTION LeftButtonPressed : BOOLEAN; ASSEMBLER;
ASM
 MOV AX,3
 INT 33h
 MOV AX,BX     {Zustand der Maustasten nach AX}
 AND AX,1      {Prfe, ob Bit 0 (Linke Maustaste) gesetzt ist}
               {FUNCTION-Wert geht durch's AX-Register zurck!}
END;

FUNCTION RightButtonPressed : BOOLEAN; ASSEMBLER;
ASM
 MOV AX,3
 INT 33h
 MOV AX,BX     {Zustand der Maustasten nach AX}
 AND AX,2      {Prfe, ob Bit 1 (Rechte Maustaste) gesetzt ist}
               {FUNCTION-Wert geht durch's AX-Register zurck!}
END;

PROCEDURE WaitForLeftButtonRelease; ASSEMBLER;
ASM
 @Warte:
  Call LeftButtonPressed  {Ruft LeftButtonPressed auf}
  JNZ @Warte              {Schleife solange, bis linker Knopf
                           nicht gedrckt ist}
END;

PROCEDURE WaitForRightButtonRelease; ASSEMBLER;
ASM
 @Warte:
  Call RightButtonPressed  {Ruft RightButtonPressed auf}
  JNZ @Warte               {Schleife solange, bis rechter Knopf
                            nicht gedrckt ist}
END;

PROCEDURE SetXYRange(MinX,MaxX,MinY,MaxY : WORD); ASSEMBLER;
ASM
 MOV AX,7
 MOV CX,MinX
 MOV DX,MaxX
 INT 33h           {Legt X-Bereich fest}
 MOV AX,8;
 MOV CX,MinY
 MOV DX,MaxY
 INT 33h           {Legt Y-Bereich fest}
END;

BEGIN
END.


Wie man sieht, habe ich gar nicht alle Funktionen benutzt, die
ich zuvor ('Mausprogrammierung') vorgestellt habe.
In dieser Unit habe ich nur die Funktionen implementiert, die
ich auch schon manchmal benutzt habe. Die Abfrage des mittleren
Knopfes habe ich mir zum Beispiel gespart, da dieser eigentlich
nie (nicht nur eigentlich nie, sondern berhaupt nie...) benutzt
wird. Die Funktionen 07h und 08h habe ich in eine Prozedur ge-
packt, da zumindest ich eigentlich immer beide gleichzeitige ver-
ndere. Sollte man aber z.B. nur den horizontalen Bereich ndern
wollen, so kann man die Prozedur immer noch trennen (SetXRange/
SetYRange).

So, zum Abschlu sei noch gesagt, da Ihr den ganzen Dri da oben
zum Glck nicht abschreiben braucht!
Der QuellCode der Unit, sowie ein kleines Beispielprog befindet
sich (wie auch alle anderen Beispiele und QuellCode-Verffentlich-
ungen) im Verzeichnis 'Sources'.

So weit, So gut...  Das war's dann (fr's erste) mit der Maus in
Pascal/Assembler. Sollten noch irgendwelche Fragen dazu bestehen:
Schreibt ruhig! Es wird alles beantwortet.

                                                 Kemil

