Jak na myš v Pascalu

Zdroj: SOOM.cz [ISSN 1804-7270]
Autor: Drekin
Datum: 1.7.2004
Hodnocení/Hlasovalo: 2.27/11

Zde si povíme jak v Pascalu používat myš a nejen to

V tomto článku se naučíme jak v Pascalu zacházet s myší a nejen to. Naleznete zde pár užitečných procedur pro zlepšení vašich programů a také zabrousíme trochu do tajů vkládaného assembleru.

Pro zvládnutí článku předpokládám základní znalost Pascalu (no, kdybyste neměli znalosti Pascalu asi byste se nepokoušeli ovládat v něm myš:-). Částečná znalost assembleru jistě nebude na škodu, ale není bezpodmínečně nutná.

No a teď rovnou k problému. Jak na myš v Pascalu? Bez vkládaného assembleru to asi nepůjde. Pokud nevíte, co to je Assembler, je to nízkoúrovňový programovací jazyk, tzn. žádné příkazy, jen přímé instrukce procesoru. V Pascalu se assemblerové vsuvky ohraničují ASM a END. Ale teď už rovnou k programu, jedná o jednoduchý prográmek, který se ukončuje klikem myší na tlačítko KONEC:

program priklad_mys(input,output);
uses crt;
var konec:byte;
    mx,my:word; (*proměnné pro souřadnice myši*)
(*nejdříve deklarujeme vkládaným assemblerem základní procedury nejen pro práci s myší*)

procedure onmc; (*zobrazení kurzoru myši*)
   begin
      asm (*bez vkládaného assembleru to nepůjde*)
         mov ax,01h (*01h - číslo funkce myši pro zobrazení kurzoru*)
         int 33h (*int 33h - přerušení pro funkce myši*)
      end
   end;
procedure offmc; (*skrytí kurzoru myši*)
   begin
      asm
         mov ax,02h (*02h - číslo funkce myši pro skrytí kurzoru*)
         int 33h
      end
   end;
procedure poziclk(c:word;var x,y:word); (*zjištění souřadnic posledního kliku*)
   var x1,y1:word; (*pomocné proměnné souřadnic, přímo mně to nějak nešlo*)
   begin
      asm
         mov ax,05h (*05h - číslo funkce pro zjištění souřadnic kliku*)
         mov bx,c (*c - proměnná označující tlačítko, se kterým pracujeme; 0 - levé, 1 - pravé, 2 - prostřední
         int 33h
         mov x1,cx (*do proměnné x1 uložíme x-ovou souřadnici myši*)
         mov y1,dx (*do proměnné y1 uložíme y-ovou souřadnici myši*)
      end;
      x:=x1; (*a nyní už souřadnice uložíme naposledy*)
      y:=y1
   end;
procedure upclk(c:word;var x:word); (*zjištění jestli bylo od posledního volání procedury puštěno tlačítko c*)
   var x1:word;
   begin
      asm
         mov ax,06h (*číslo funkce*)
         mov bx,c
         int 33h
         mov x1,bx (*do x1 se uloží počet uvolnění tlačítka od posledního volání*)
      end;
      x:=x1
   end;
procedure hidecurs; (*skrytí textového kurzoru - jen estetický doplněk*)
   begin
      asm
         mov ah,01h
         mov cx,2000h (*hodnota skrytého kurzoru*)
         int 10h (*přerušení pro grafiku*)
      end
   end;
procedure waitretrace; (*předejde nechutnému blikání obrazovky*)
   begin
      asm
         mov dx,03DAh
     @1: in al,dx
         test al,8
         jz @1
      end
   end;
(*tuhle proceduru budeme volat kdykoliv budeme chtít, aby uživatel reagoval myší, třeba stiskl tlačítko*)
procedure mys;
   var upclick:word;
   begin
      onmc;
      repeat
         poziclk(0,mx,my);
         upclk(0,upclick)
      until upclick=1; (*zjišťuje souřadnice posledního kliku, dokud není jasné, že uživatel opravdu klikl*)
      offmc
   end;
(*a teď konečně vlastní program, pokud se vám zdá, že ta deklarace procedur je moc dlouhá nebo složitá viz níže*)
begin
   clrscr;
   hidecurs;
   repeat
      waitretrace;
      textcolor(0);
      textbackground(12);
      gotoxy(5,5);
      write('Konec'); (*a uděláme si tlačítko*)
      mys;
      mx:=mx div 8+1; (*získané souřadnice jsou grafické a my je musíme takto převést na textové*)
      my:=my div 8+1;
      if (mx>=5) and (mx<=9) and (my=5) then konec:=1 (*no a pokud jsou souřadnice na tlačítku, tak se program ukončí*)
   until konec=1
end.

Pokud se vám tento zdrojový kód zdá zbytečně dlouhý, rozvleklý či neefektivní, pak je to jen dobře. Daný program, se dá řešit lépe a hlavně by mohl být kratší. Toto množství procedur je zde jen pro snazší pochopení. Následující kód je o mnoho kratší:

program priklad_mys(input,output);
uses crt;
var konec:byte;
    mx,my,upclick:word;
begin
   clrscr;
   asm
      mov ah,01h
      mov cx,2000h
      int 10h
   end;
   repeat
      asm
         mov dx,03DAh
     @1: in al,dx
         test al,8
         jz @1
      end;
      textcolor(0);
      textbackground(12);
      gotoxy(5,5);
      write('Konec');
      asm
         mov ax,01h
         int 33h
      end;
      repeat
         asm
            mov ax,05h
            mov bx,0
            int 33h
            mov mx,cx
            mov my,dx
            mov ax,06h
            mov bx,0
            int 33h
            mov upclick,bx
         end
      until upclick=1;
      asm
         mov ax,02h
         int 33h
      end;
      mx:=mx div 8+1;
      my:=my div 8+1;
      if (mx>=5) and (mx<=9) and (my=5) then konec:=1
   until konec=1
end.

Tento program byl o mnoho kratší, ale asi nejlepším způsobem, zvláště pokud chcete používat myš ve více programech, je nadefinovat si tyto procedury do externího souboru (tedy vytvořit unitu). Pokud nevíte, jak se unity dělají či z jiného důvodu nechce unitu tvořit, můžete si stáhnout unitu MCU (mouse control unit) i s popisem jednotlivých procedur a samozřejmě se zdrojovým kódem.

Pokud by vás zajímali i jiné funkce je dobré použít program sysman či athelp. Sám jsem s těmito programy velice spokojen. Pokud máte jiné dotazy, připomínky apod. zeptejte se mě na drekin@gmail.com

Drekin