 PS 9308




                           FARE KULLANIMI

                                                           Kaan Aslan


Bu ay fare kullanmna deinmek istiyorum. Fareyi destekleyen programlarn
nasl yazldn aklayacam.

Programlarnn fareleri desteklemesi artk birok programc iin kanlmaz
hale gelmitir. zellikle grafik programlar faresiz dnlemez. Fareler
klavyeyle yapamadmz ya da yapmakta glk ektiimiz ilemerde youn
olarak kullanlyorlar. Bunun dnda fare birok programn hzl ve kolay
kullanlmasn da salyor.

Fare kullanmnn ilk adm fare srcsnn yerletirilmesi ilemidir. Bu
srcy yerletirdikten sonra fareye ulamamz salayan 33h kesmesi de
yklenmi oluyor. Biz fare ilemlerini bu kesme sayesinde yrteceiz.

Aadaki rneklerde int86 fonksiyonu kullanlmtr. Bu fonksiyonlara
bakmadan nce int86'y incelemenizi salk veririm.

int86  tane parametreye sahip. Birinci parametresi kesme numaras ikinci
parametresi CPU registerlerine yerletirilecek deerleri ieren union REGS
gstericisi ve nc parametresi de kesmenin icrasndan sonraki CPU
registerlerinin durumunu gsteren union REGS gsterici parametresidir. union
REGS'in tanmlanmas DOS.H'ta yaplmtr.

33h fare kesmesi toplam 35 eit fonksiyondan oluuyor. Ben burada yalnzca en
nemli birka tanesini aklayacam. Ancak dierlerini konuya ilikin bir
dkman inceleyereek bulabilirsiniz. Btn fonksiyonlar AX registerine
ilikin deer yerletirilerek arlyorlar.


1) lk fonksiyonumuz fareyi yeniden balatan mouse_reset() fonksiyonu. Bu
fonksiyonun iki geri dn deeri var. Birincissi AX reegisterindeki deer. Bu
deer eer 0 ise sorun yok, ancak -1 ise o zaman fare srcsnn
yerletirilmedii anlamna geeliyor. BX registeri farenin tu saysdr.
Biliyorsunuz MicroSoft tr fareler iki tulu en ok kullanlan farelerdir.



void mouse_reset(void)
{
 union REGS reg;

 reg.x.ax = 0;         /* Fareyi yeniden balatmak iin */
 int86(0x33, &reg, &reg);

 if((int) reg.x.ax != -1) {
  printf("\nFare srcs ykl deil...");
  exit(1);
 }
 if(reg.x.bx != 2) {     /* Bu ksm koddan kartabilirsiniz */
  printf("\nki tulu fare yok...");
  exit(1);
  }
}


2) kinci fonksiyonumuz farenin okunu gsteren mouse_on fonksiyonu.  AX' e 1
deeri konularak arlyor. Bu fonksiyon ile fare oku grnr hale
getirilebilir. Programlarnzn banda bu fonksiyonu bir kez armalsnz.
Fare oku text modunda dikdrtgen grafik modunda ise sivri bir ok
grnmndedir.


void mouse_on(void)
{
 union REGS reg;
 reg.x.ax = 1;              /* Fare okunu gster */
 int86(0x33, &reg, &reg);
}


3) nc fonksiyonumuz. Fare okunu grnmez yapmakta kullanlacak.


void mouse_off(void)
{
 union REGS reg;
 reg.x.ax = 2;            /* Fare okunu grnmez yap */
 int86(0x33, &reg, &reg);
}


4) Drdnc fonksiyonumuz farenin sa tuuna baslp baslmadn tespit
etmek iin kullanlacak. AX'e 33 deeri yerletiriliyor. Bu fonksiyonun geri
dn deeri BX tedir. BX deeri 2 ise sa tua 1 ise sol tua baslmtr.


right_button(void)
{
 union REGS reg;

 reg.x.ax = 3;        /* basl tuu tespit et */
 int86(0x33, &reg, &reg);
 return(reg.x.bx & 2);
}

5) Beinci fonksiyon sol tua baslp baslmadn kontrol etmek iin.

left_button(void)
{
 union REGS reg;

 reg.x.ax = 3; /* get position and button status */
 int86(0x33, &reg, &reg);
 return(reg.x.bx & 1);
}

6) Altnc fonksiyonumuz yine AX'e 3 deeri konularak elde ediliyor.
Fonksiyonun iki parametresi var. kisi de gsterici Farenin konumu bu iki
parametresine yerletiriliyor. Text modu iin yazlan bu fonksiyonda
deerlerin 8 e blndne dikkat edin. Kesmenin verdii deer 25*8 ve 80*8
biimindedir. Bu fonksiyonun geri dn deeri farenin basld tutur.


int get_mouse(int *row, int *col)
{
 union REGS reg;

 reg.x.ax = 3;      /* Farenin gsterdii yeri tespit iin */
 int86(0x33, &reg, &reg);
 *row = reg.x.dx >> 3;  /* Satr deeri 8'e blnyor. Nasl ? */
 *col = reg.x.cx >> 3;  /* Stun deeri 8'e blnyor, nasl ? */ return

 (reg.x.bx);


}

7) Bu fonksiyonumuz ile yukardaki arasndaki  fark geri dn deerinin
farenin gsterdii pozisyon olmasdr.
Bu fonksiyonun geri dn deeri int'tir. Yksek anlaml byte' satr dk
anlaml byte' stun ierir.

int mouse_pos(void)
{
 union REGS reg;

 reg.x.ax = 3;           /* Farenin gsterdii yeeri tespit etmek iin
 */
 int86(0x33, &reg, &reg);

 return ((reg.x.dx / 8) << 8 | (reg.x.cx / 8));
}


te bir test program. Buradaki dier ekran fonksiyonlarn geen ay
aklamtm. Disket iindeki EKRANBL.LIB BORLANDC iin EKRANM.LIB MicroSoft
iin benim kullandm LARGE model ktphanelerim. lerinde ekran
fonksiyonlar var. Onu dorudan Project'e ekleyebilirsiniz.

Disketinizdeki MTEST1.EXE program:

#include <stdio.h>
#include <dos.h>
#include "key.h"


void main()
{
 int c, row, col;
 char sbuf[64];

 mouse_reset();

 _getvideo();           /* Bana ait */
 clrscr();

 writes(24, 0, " IKI ", REV);     /* Bana ait */
 mouse_on();

 for (;;) {
  c = get_mouse(&row, &col);
  if ((row == 24) && ((col >= 0) && (col <= 9)) && (c == 1))
   break;
  sprintf(sbuf, "Row = %2d   Col = %2d   Key: %d",
   row, col, c);
  writes(24, 40, sbuf, CYAN);
  }
 mouse_off();
}

Yukardaki _getvideo, writes fonksiyonlarn aada bir
kez daha yazyorum. PC World PS haziran saysna baknz.

static int _videobuf = 0xb000;

void _getvideo(void)
{
 union REGS  vregs;

 vregs.h.ah = 0xf;

 int86(0x10,&vregs, &vregs);

 if (vregs.h.al == 2 || vregs.h.al == 3) {
  _videobuf = 0xb800;
  return;
  }

 if (vregs.h.al == 7) {
  _videobuf = 0xb000;
  return;
  }   else {
  printf("\nVideo modunu deeitiriniz...");
  exit(1);
  }
}



}

void _writes(int row, int col, char *str)
{
 CHR far *chp;

 chp = (CHR far *) ((long) _videobuf << 16 | 0L);
 chp += row * 80 + col;

 while (*str != NULL) {
  chp -> chr = *str;
  ++chp;
  ++str;
  }
}

void writes(int row, int col, char *str, int attr)
{
 CHR far *chp;
 chp = (CHR far *) ((long) _videobuf << 16 | 0L);
 chp += row * 80 + col;

 while (*str != NULL) {
  chp -> chr = *str;
  chp -> atr = attr;
  ++chp;
  ++str;
  }

}





Aslnda ben genellikle programlarmda fare ve klavyeyi tarayan tek bir
fonksiyon kullanyorum. Nasl m? zah edeyim...

_getkb fonksiyonu ktphanemde olan klavyeden baslan tuun ASCII ve SCAN
karlklarn veren bir fonksiyon. Siz onu yle yazabilirsiniz. Aslnda bu
fonksiyon BORLAND ve MicroSoft ktphanelerinde bulunan bioskey(0)
fonksiyonudur.


int _getkb(void)
{
  union REGS reg;

  reg.h.ah = 0;

  int86(0x16,&reg,&reg);
  return(reg.x.ax);

}



ya da


#define _getkb() bioskey(0)

ifadesini de kullanabilirsiniz.


Geri dn deeri farenin tularndan birisine baslmamsa klavyeden baslan
karakter, baslmsa o andaki farenin konumu olan getkb fonkssiyonu aadaki
gibidir.


int getkb(void)
{

 while (!kbhit())
  if (left_button() || right_button())
  return mouse_pos();

  return _getkb();
}


Aadaki bu ok basit program fare programlamasyla ilgili size bir fikir
verecektir. Bunun zerine daha fazla bir ey sylememe gerek yok sanyorum.
Program durdurmak iin farenin iki tuuna ayn anda basmalsnz.  Aadaki
program optimize eder ve genelletiriseniz sizin iin ilerletici olacaktr.
Klavye ve fare ile seimi ayn switch iine koyabilir misiniz?

Disketinizdeki MTEST2.EXE program

#include <stdio.h>
#include "key.h"

main()
{
 int mouse_map[32] = {1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,
        3,3,3,3,3,3,3,3};
/* Fare dizisine ilk deer veriliyor */

  char sbuf[5];
  unsigned col;

_getvideo();

mouse_reset();
mouse_on();

clrscr();

_writes(0,0,  "FILE");
_writes(0,12, "SAVE");
_writes(0,24, "RETRIEVE");
_writes(24,0,"Klavye tuunun kodu ya da fare konumu ="); _writes(24,49,"Son
seilen eleman=");


 while (!(right_button() && left_button())) {
  col = getkb();

  if (col > 32) {
        sprintf(sbuf,"%04x",col);
        _writes(20,40,sbuf);
         continue;
        }

  switch (mouse_map[col])
  {
   case 1 : _writes(24,70, "FILE      "); break;
   case 2 : _writes(24,70, "SAVE      "); break;
   case 3 : _writes(24,70, "RETRIEVE  "); break;
   case 0 : sprintf(sbuf,"%04x", col);
            _writes(24,40,sbuf); break;
   }

 }   /* while */

}