home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Pascal / Samples / VIEWS10.ARJ / TP / VIEWS / EMOUSE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-05-05  |  23.3 KB  |  849 lines

  1. {===========================================================================}
  2. {                                                                           }
  3. {                  █████████████  Unit LMouse   █████████████               }
  4. {                  █████████████  Release 1.0   █████████████               }
  5. {                                                                           }
  6. {             █████████████  CREATED BY Dr. LUIS  VACA  █████████████       }        
  7. {                █████████████  All Rights Reserved  █████████████          }
  8. {                                                                           }
  9. {  " Promote Programming ... Register !!!"                                  }
  10. {===========================================================================}
  11.  
  12. Unit EMouse;
  13. INTERFACE
  14.  
  15. TYPE
  16.  
  17.    Point      = Record
  18.             X,Y : Integer;
  19.    END;
  20.  
  21.    Rect       = Record
  22.             A,B : Point;
  23.    END;
  24.  
  25.    AMouse      = Record
  26.              Event : Integer;
  27.              P     : Point;
  28.    END;
  29.  
  30.    AnyKey      = Record
  31.          ScanCode  : Word;
  32.          CharCode  : Char;
  33.          ASCII     : Boolean;
  34.          Extended  : Boolean;
  35.    END;
  36.  
  37.    Eventype = Record
  38.                     Command   : Word;
  39.                     Key       : AnyKey;
  40.                     Mouse     : AMouse;
  41.    END;
  42.  
  43.  
  44.    SystemTime = Record
  45.                 Hour : Word;
  46.                 Min  : Word;
  47.                 Sec  : Word;
  48.                 uec  : Word;
  49.    END;
  50.  
  51.  
  52.  
  53.  
  54.      { KeyS OBTAINED FROM INTERRUPT $16, SERVICES $2 AND $10  }
  55. { NOTE: THIS NUMBERS DO NOT CORRESPOND WITH TP SCAN CODES, THEREFORE IS
  56.  USELESS TO USE TP FUNCTIONS ORD () OR CHR () TO MANIPULATE THIS NUMBERS }
  57.  
  58. CONST
  59.      Sk_ScrollLock    = $10;
  60.      Sk_NumLock        = $20;
  61.      Sk_CapsLock    = $40;
  62.      Sk_InsLock        = $80;
  63.  
  64.      Key_ESC        = $01;
  65.      {       ASCII Keys      }
  66.      Key_A        = $1E;
  67.      Key_B        = $30;
  68.      Key_C        = $2E;
  69.      Key_D        = $20;
  70.      Key_E        = $12;
  71.      Key_F        = $21;
  72.      Key_G        = $22;
  73.      Key_H        = $23;
  74.      Key_I            = $17;
  75.      Key_J        = $24;
  76.      Key_K        = $25;
  77.      Key_L        = $26;
  78.      Key_M        = $32;
  79.      Key_N        = $31;
  80.      Key_O        = $18;
  81.      Key_P        = $19;
  82.      Key_Q        = $10;
  83.      Key_R        = $13;
  84.      Key_S        = $1F;
  85.      Key_T        = $14;
  86.      Key_U        = $16;
  87.      Key_V        = $2F;
  88.      Key_W        = $11;
  89.      Key_x        = $2D;
  90.      Key_Y        = $15;
  91.      Key_Z        = $2C;
  92.  
  93.      {     Number Keys       }
  94.      Key_1        = $02;
  95.      Key_2        = $03;
  96.      Key_3        = $04;
  97.      Key_4        = $05;
  98.      Key_5        = $06;
  99.      Key_6        = $07;
  100.      Key_7        = $08;
  101.      Key_8        = $09;
  102.      Key_9        = $0A;
  103.      Key_0        = $0B;
  104.  
  105.      {       F Keys         }
  106.      Key_F1        = $3B;
  107.      Key_F2        = $3C;
  108.      Key_F3        = $3D;
  109.      Key_F4        = $3E;
  110.      Key_F5        = $3F;
  111.      Key_F6        = $40;
  112.      Key_F7        = $41;
  113.      Key_F8        = $42;
  114.      Key_F9        = $43;
  115.      Key_F10        = $44;
  116.      Key_F11        = 133;
  117.      Key_F12        = 134;
  118.  
  119.      {      Edit Keys        }
  120.      Key_Space        = $39;
  121.      Key_Enter        = $1C;
  122.      Key_Tab        = $0F;
  123.      Key_SysReq        = $54;
  124.      Key_BackSpace    = $0E;
  125.      Key_Ins        = $52;
  126.      Key_Del        = $53;
  127.      Key_CtrlHome       = 123;
  128.      Key_AltSpace       = $A;
  129.  
  130.      {     Arrow Keys        }
  131.      Key_Home        = $47;
  132.      Key_UpArrow    = $48;
  133.      Key_PgUp        = $49;
  134.      Key_LeftArrow    = $4B;
  135.      Key_RightArrow    = $4D;
  136.      Key_DownArrow    = $50;
  137.      Key_End        = $4F;
  138.      Key_PgDn        = $51;
  139.  
  140.      { Keys from center pad }
  141.      Key_NumLock    = $45;
  142.      Key_ScrollLock    = $46;
  143.      Key_Ctrl        = $04;
  144.      Key_Shift          = $02;
  145.      Key_Alt        = $08;
  146.      Key_CapsLock     = $3A;
  147.  
  148.      { Keys from numeric pad }
  149.      Key_Minus        = $0C;
  150.      Key_Equal        = $0D;
  151.      Key_Period        = $34;
  152.      Key_LBracket     = $1A;
  153.      Key_RBracket     = $1B;
  154.      Key_Coma        = $33;
  155.      Key_Semi        = $27;
  156.      Key_Rquote        = $28;
  157.      Key_Lquote        = $29;
  158.      Key_asterisk     = $37;
  159.      Key_GrayMinus    = $4A;
  160.      Key_Center5    = $4C;
  161.      Key_GrayPlus     = $4E;
  162.  
  163.      Key_BackSlash    = $2B;
  164.      Key_ForwSlash    = $35;
  165.  
  166.     {       Shift and number symbols      }
  167.      Key_Number         = Key_Shift + Key_3;
  168.      Key_Dollar         = Key_Shift + Key_4;
  169.      Key_Percent        = Key_Shift + Key_5;
  170.      Key_And            = Key_Shift + Key_7;
  171.      Key_Underline      = Key_Shift + Key_minus;
  172.      Key_Plus           = Key_Shift + Key_equal;
  173.  
  174.  
  175. {################# Mouse CONSTANTS ###################}
  176.  
  177. TYPE
  178.     MaskType = Array[0..1, 0..15] of Word;
  179.  
  180.  
  181. CONST      {############ ALL THE GOODIE Mouse SHAPES ############}
  182.  
  183.    Standard: MaskType =
  184.      (($3FFF,$1FFF,$0FFF,$07FF,$03FF,$01FF,$00FF,$007F,    { <-- Screen Mask }
  185.        $003F,$001F,$01FF,$10FF,$30FF,$F87F,$F87F,$FC7F),
  186.  
  187.       ($0000,$4000,$6000,$7000,$7800,$7C00,$7E00,$7F00,    { <-- Cursor Mask }
  188.        $7F80,$7C00,$6C00,$4600,$0600,$0300,$0300,$0000));
  189.  
  190.    PointingHand: MaskType =
  191.      (($E1FF,$E1FF,$E1FF,$E1FF,$E1ff,$E000,$E000,$E000,   
  192.        $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000),
  193.  
  194.       ($1E00,$1200,$1200,$1200,$1200,$13ff,$1249,$1249,   
  195.        $1249,$9001,$9001,$9001,$8001,$8001,$8001,$FFFF));
  196.  
  197.    HourGlass: MaskType =
  198.      (($0000,$0000,$0000,$0000,$8001,$C003,$E007,$F00F,
  199.        $E007,$C003,$8001,$0000,$0000,$0000,$0000,$FFFF),
  200.  
  201.       ($0000,$7FFE,$6006,$300C,$1818,$0C30,$0660,$03C0,
  202.        $0660,$0C30,$1998,$33CC,$67E6,$7FFE,$0000,$0000));
  203.  
  204.    MaskQUESTION : Masktype =
  205.      (($FFFF,$C00F,$800F,$800F,$878F,$8F8F,$F80F,$F00F,
  206.        $F01F,$F0FF,$F1FF,$F1FF,$F1FF,$F1FF,$F1FF,$FBFF),
  207.  
  208.       ($0000,$0000,$0FE0,$3020,$2020,$0020,$0060,$0380,
  209.        $0600,$0400,$0400,$0400,$0400,$0000,$0400,$0000));
  210.  
  211.    DiagCross: MaskType =
  212.      (($07E0,$0180,$0000,$C003,$F00F,$C003,$0000,$0180,
  213.        $07E0,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  214.  
  215.       ($0000,$700E,$1C38,$0660,$03C0,$0660,$1C38,$700E,
  216.        $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000));
  217.  
  218.    CheckMark: MaskType =
  219.      (($FFF0,$FFE0,$FFC0,$FF03,$0607,$000F,$001F,$C03F,
  220.        $F07F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  221.  
  222.        ($0000,$0006,$000C,$0018,$0030,$0060,$70C0,$1D80,
  223.     $0700,$0000,$0000,$0000,$0000,$0000,$0000,$0000));
  224.  
  225.    MaskCursor : Masktype =
  226.      (($07FF,$07FF,$07FF,$8FFF,$8FFF,$8FFF,$8FFF,$8FFF,
  227.        $8FFF,$8FFF,$8FFF,$07FF,$07FF,$07FF,$FFFF,$FFFF),
  228.  
  229.       ($0000,$7000,$2000,$2000,$2000,$2000,$2000,$2000,
  230.        $2000,$2000,$2000,$2000,$7000,$0000,$0000,$0000));
  231.  
  232.    MaskResizeBack : Masktype =
  233.      (($00FF,$01FF,$03FF,$01FF,$20EF,$704F,$F80F,$FC0F,
  234.         $FE0F,$FC0F,$F80F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  235.  
  236.       ($0000,$7C00,$7800,$5C00,$0E00,$0700,$03A0,$01E0,
  237.        $00E0,$01E0,$0000,$0000,$0000,$0000,$0000,$0000));
  238.  
  239.    MaskResizeForw : Masktype =
  240.      (($F00F,$F80F,$FC0F,$F80F,$704F,$20EF,$01FF,$03FF,
  241.        $07FF,$03FF,$01FF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  242.  
  243.       ($0000,$03E0,$01E0,$03A0,$0700,$0E00,$5C00,$7800,
  244.        $7000,$7800,$0000,$0000,$0000,$0000,$0000,$0000));
  245.  
  246.  
  247.    MaskResizeVert : Masktype =
  248.      (($FE7F,$FC3F,$F81F,$F00F,$E007,$FC3F,$FC3F,$FC3F,
  249.        $FC3F,$FC3F,$FC3F,$E007,$F00F,$F81F,$FC3F,$FE7F),
  250.  
  251.       ($0000,$0180,$03C0,$07E0,$0180,$0180,$0180,$0180,
  252.        $0180,$0180,$0180,$0180,$07E0,$03C0,$0180,$0000));
  253.  
  254.  
  255.    MaskResizeHor : Masktype =
  256.      (($FFFF,$F7EF,$E7E7,$C7E3,$8001,$0000,$0000,$8001,
  257.        $C7E3,$E7E7,$F7EF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  258.  
  259.       ($0000,$0000,$0000,$1008,$300C,$7FFE,$7FFE,$300C,
  260.        $1008,$0000,$0000,$0000,$0000,$0000,$0000,$0000));
  261.  
  262.  
  263.    MaskTCross : Masktype =
  264.      (($FC7F,$F83F,$F01F,$D837,$8C63,$0001,$0001,$0001,
  265.        $8C63,$DC77,$F83F,$F01F,$F83F,$FC7F,$FFFF,$FFFF),
  266.  
  267.       ($0100,$0380,$07C0,$0100,$2108,$610C,$FFFE,$610C,
  268.        $2108,$0100,$0100,$07C0,$0380,$0100,$0000,$0000));
  269.  
  270.  
  271. {############ Mouse AND KeyBOARD FUNCTION INTERRUPTS ############}
  272.  
  273. PROCEDURE GraphicsMouse(Mask: MaskType; X,Y : Integer);
  274. PROCEDURE MouseCursor(Mask : Masktype; X,Y : Integer);
  275. PROCEDURE TextMouse;
  276. PROCEDURE ShowMouse;
  277. PROCEDURE HideMouse;
  278. FUNCTION MouseStatus(VAR X,Y:Integer):Integer;
  279. FUNCTION MouseinR(VAR P: Point; VAR R : Rect) : Boolean;
  280. PROCEDURE ResetMouse;
  281. PROCEDURE MoveMouse(X,Y : Integer);
  282. PROCEDURE MouseInit;
  283. PROCEDURE MouseBox(BX,by,bx1,by1 : Word);
  284. PROCEDURE MouseMinMax(X,Y,x1,y1:Integer);
  285. FUNCTION GetKey(VAR aChar: char; VAR isExtended: Boolean): Word;
  286. FUNCTION GetEvent(VAR E : Eventype): Boolean;
  287. PROCEDURE ClearEvent(VAR E : Eventype);
  288. FUNCTION DoubleClick ( P : point): Boolean;
  289. PROCEDURE Quit(msg : string);
  290. PROCEDURE GetCounter(VAR Counter:SystemTime);
  291. PROCEDURE ResetCounter(VAR Counter:SystemTime);
  292. PROCEDURE GetLap(VAR Counter:SystemTime);
  293. PROCEDURE Beep;
  294. PROCEDURE Wait(n:Integer);
  295. PROCEDURE Bell(tone, duration, rep : Integer);
  296. PROCEDURE TextCursor(OnOff : Boolean);
  297. FUNCTION LastxPress(Button : Byte) : Word;
  298. FUNCTION LastYPress(Button : Byte) : Word;
  299. FUNCTION KBFlag : Word;
  300.  
  301.  
  302.  
  303. CONST
  304.  
  305.      Left_Button_Released   = 4;
  306.      Right_Button_Released  = $10;
  307.      Left_Button_Pressed    = 2;
  308.      Right_Button_Pressed   = 8;
  309.      Mouse_Moving           = 1;
  310.      Mouse_Interrupt     = $33;
  311.  
  312. TYPE
  313.   Mouse_Event_Rec =
  314.     record
  315.       Event          : Word;
  316.       Button_Status  : Word;
  317.       Row            : Word;
  318.       Col            : Word;
  319.     END;
  320.  
  321.  
  322.     Box      =
  323.     record
  324.      X,Y,
  325.      x1,y1 : Word;
  326.     END;
  327.  
  328.  
  329.  
  330. VAR
  331.   Mouse          : Mouse_Event_Rec;
  332.   MouseExists    : Boolean;
  333.   InGraphics     : Boolean;
  334.   HideBox        : Box;
  335.   Event          : Boolean;
  336.  
  337.  
  338. IMPLEMENTATION
  339.  
  340. USES
  341.     CRT, DOS;     {<----- I'M USING TP'S CRT HERE ,THIS TPU CAN NOT BE USED LATTER }
  342.  
  343. {$F+ }
  344.  
  345.  
  346. PROCEDURE Quit(msg : string);
  347. BEGIN
  348.      HideMouse; { HIDE Mouse AND TERMINATE INTERRUPT BEFORE QUITING }
  349.      Clrscr;
  350.      TextMode(LastMode);   { RESTORE SCREEN MODE }
  351.      Writeln (msg);        { QUIT WITH MESSAGE }
  352.      Halt(0);              { TERMINATE PROGRAM }
  353. END;
  354.  
  355.  
  356. {############ SHOW HIDE TExT BLINKING CURSOR ############}
  357. PROCEDURE TextCursor(OnOff : Boolean);
  358. CONST
  359.     HideCursor = 32;  {<----- THIS WILL HIDE THE BLINKING TExT CURSOR }
  360. VAR
  361.    Reg : registers;
  362. Begin
  363.      Reg.AH := $01;
  364.      If OnOff then
  365.      Reg.CH := 1      {<------ THIS RESTORES (SHOWS) THE CURSOR }
  366.      ELSE
  367.      Reg.CH := HideCursor; 
  368.      Reg.CL := 14;
  369.      INTR($10, Reg);
  370. end;
  371.  
  372. {############ MAKE A TONE ############}
  373. PROCEDURE Beep;
  374. BEGIN
  375.   Sound(500); Delay(25); NoSound;
  376. END;
  377.  
  378. {############ MORE SOPHISTICATED SOUND ############}
  379. PROCEDURE Bell(tone, duration, rep : Integer);
  380. VAR
  381.    X : Integer;
  382. BEGIN
  383.      For X:=1 to Rep Do
  384.                        BEGIN
  385.                             Sound(tone);
  386.                             Delay(duration);
  387.                             NoSound;
  388.                        END;
  389. END;
  390.  
  391. {############ REPLACEMENT FOR TP'S DELAY ############}
  392. PROCEDURE Wait(n:Integer);
  393. BEGIN
  394.      Delay(n);
  395. END;
  396.  
  397. {############ RESET A TIME COUNTER ############}
  398. PROCEDURE ResetCounter(VAR Counter:SystemTime);
  399. BEGIN
  400.     Counter.hour:=0;
  401.     Counter.min :=0;
  402.     Counter.sec :=0;
  403.     Counter.uec :=0;
  404. END;
  405.  
  406. {############ START A COUNTER ############}
  407. PROCEDURE GetCounter(VAR Counter:SystemTime);
  408. BEGIN
  409.      Counter.uec := (Counter.uec + 1);
  410.      if Counter.uec > 60 then
  411.                              BEGIN
  412.                                   inc(Counter.sec);
  413.                                   Counter.uec := 0;
  414.                              END;
  415.  
  416.      if Counter.sec > 60 then
  417.                              BEGIN
  418.                                   inc(Counter.min);
  419.                                   Counter.sec := 0;
  420.                              END;
  421.  
  422.      if Counter.min > 60 then
  423.                              BEGIN
  424.                                   inc(Counter.hour);
  425.                                   Counter.min := 0;
  426.                              END;
  427.  
  428.      if Counter.hour > 24 then Counter.hour :=0;
  429.  
  430. END;
  431.  
  432. {############ GET ELAPSED TIME SINCE LAST CALL ############}
  433. PROCEDURE GetLap(VAR Counter:SystemTime);
  434. BEGIN
  435.     GetTime(Counter.hour,Counter.min,Counter.sec,Counter.uec);
  436. END;
  437.  
  438.  
  439. { CHECK FOR SPECIAL KeyS SUCH AS ALT, CNTRL OR SHIFT }
  440. FUNCTION KBFlag : Word;
  441. VAR
  442.   Reg : Registers;
  443. BEGIN
  444.      Reg.AH := $02;
  445.      INTR ($16, Reg);
  446.      KBFlag:= (Reg.AL);      { CHECK Key BUFFER FOR SPECIAL KeyS }
  447. END;
  448.  
  449.  
  450. {############ THIS IS THE HEART OF THE KeyBOARD INTERRUPT ############}
  451. FUNCTION GetKey(VAR aChar: char; VAR isExtended: Boolean): Word;
  452.  
  453.  
  454. CONST
  455.     Key_lShift = $01;
  456.     Key_rShift = $02;
  457. VAR
  458.   Reg      :     Registers;
  459.   ExtKey   :     Word;
  460.   aKey     :     Word;
  461.   Spec     :     Boolean;
  462. BEGIN
  463.      Spec:= FALSE;
  464.      Reg.AH := $10;
  465.      INTR ($16, Reg);
  466.      aKey:= Word(Reg.AH);
  467.      aChar:= Chr(Reg.AL);
  468.      ExtKey := KBFlag;
  469.      If (ExtKey AND Key_Ctrl) <> 0 then
  470.         BEGIN
  471.              aKey  := (aKey + Key_Ctrl);
  472.              Spec  := TRUE;
  473.         END ELSE
  474.      If (ExtKey AND Key_Alt) <> 0 then
  475.         BEGIN
  476.              aKey  := (aKey + Key_Alt);
  477.             Spec   := TRUE;
  478.         END ELSE
  479.      If (ExtKey AND Key_lShift) <> 0 then
  480.         BEGIN
  481.              aKey  := (aKey + Key_Shift);
  482.             Spec   := TRUE;
  483.         END ELSE
  484.      If (ExtKey AND Key_rShift) <> 0 then
  485.         BEGIN
  486.              aKey  := (aKey + Key_Shift);
  487.             Spec   := TRUE;
  488.         END;
  489.      IsExtended:= Spec;
  490.      GetKey:= aKey;
  491. END;
  492.  
  493. {############ THIS IS THE LOOP THAT POOLS Mouse AND KeyBOARD IN ONE PASS ############}
  494. FUNCTION GetEvent(VAR E : Eventype): Boolean;
  495. VAR
  496.    ms,X,Y       : Integer;
  497.    Event        : Boolean;
  498. BEGIN
  499.     E.Command       := 0;
  500.     E.Key.CharCode  := ' ';
  501.     E.Key.ScanCode  := 0;
  502.     E.Key.ASCII     := FALSE;
  503.     E.Key.Extended  := FALSE;
  504.     E.Mouse.Event   := 0;
  505.     E.Mouse.P.X     := 0;
  506.     E.Mouse.P.Y     := 0;
  507.     Event:=FALSE;
  508.     { CHECK Mouse FIRST }
  509.     MS:= Mousestatus(E.Mouse.P.X,E.Mouse.P.Y);
  510.     if (MS <> 0) then  { IF A Mouse Event GET IT }
  511.                          BEGIN
  512.                               { WHICH Mouse Event ? }
  513.                               E.Mouse.Event:=MS;
  514.                               Event:=TRUE;
  515.                          END;
  516.    { CHECK KeyBOARD }
  517.    If KeyPressed then   { IF A Key PRESSED GET IT }
  518.                         BEGIN
  519.                              E.Key.ScanCode := GetKey(E.Key.CharCode, E.Key.Extended);
  520.                              E.Key.ASCII := (E.Key.ScanCode In[Key_1 .. Key_0])
  521.                                          OR (E.Key.ScanCode In[Key_Q .. Key_M])
  522.                                          OR (E.Key.ScanCode = Key_Space)
  523.                                          OR (E.Key.ScanCode = Key_BackSlash)
  524.                                          OR (E.Key.ScanCode = Key_ForwSlash)
  525.                                          OR (E.Key.ScanCode = Key_Number   )
  526.                                          OR (E.Key.ScanCode = Key_Dollar   )
  527.                                          OR (E.Key.ScanCode = Key_Percent  )
  528.                                          OR (E.Key.ScanCode = Key_And      )
  529.                                          OR (E.Key.ScanCode = Key_Underline)
  530.                                          OR (E.Key.ScanCode = Key_Plus     )
  531.                                          OR (E.Key.ScanCode = Key_Minus    )
  532.                                          OR (E.Key.ScanCode = Key_Equal       )
  533.                                          OR (E.Key.ScanCode = Key_Period   )
  534.                                          OR (E.Key.ScanCode = Key_LBracket )
  535.                                          OR (E.Key.ScanCode = Key_RBracket )
  536.                                          OR (E.Key.ScanCode = Key_Coma       )
  537.                                          OR (E.Key.ScanCode = Key_Semi       )
  538.                                          OR (E.Key.ScanCode = Key_Rquote   )
  539.                                          OR (E.Key.ScanCode = Key_Lquote   )
  540.                                          OR (E.Key.ScanCode = Key_asterisk );
  541.                              Event:=TRUE;
  542.                         END;
  543.     GetEvent:= Event;
  544. END;
  545.  
  546. {############ RESET AN Event MESSAGE ############}
  547. PROCEDURE ClearEvent(VAR E : Eventype);
  548. BEGIN
  549.     E.Command       := 0;
  550.     E.Key.ScanCode  := 0;
  551.     E.Key.CharCode  := ' ';
  552.     E.Key.ASCII     := FALSE;
  553.     E.Key.Extended  := FALSE;
  554.     E.Mouse.Event   := 0;
  555.     E.Mouse.P.X     := 0;
  556.     E.Mouse.P.Y     := 0;
  557. END;
  558.  
  559. {############ ALL Mouse INTERRUPTS FOLLOW ############}
  560. { PROGRAMMING IDEAS OBTAINED FROM :
  561.    " MICROSOFT Mouse PROGRAMMERS REFERENCE, THE MICROSOFT PRESS "
  562.  IF YOU WANT TO LEARN MORE ABOUT THE Mouse THIS BOOK IS A MUST }
  563.  
  564. PROCEDURE ResetMouse;
  565. VAR
  566.   Reg : Registers;
  567. BEGIN
  568.   if MemW[$0000:$00CC] = 0 then
  569.     MouseExists := False
  570.   else
  571.     BEGIN
  572.       Reg.AX := 0;
  573.       INTR (Mouse_Interrupt, Reg);
  574.       MouseExists := (Reg.AX <> 0);
  575.     END;
  576. END;
  577.  
  578. {############ INTERRUPT # 1 SHOW THE Mouse ############}
  579. PROCEDURE ShowMouse;
  580. VAR
  581.   Reg : Registers;
  582. BEGIN
  583.   if MouseExists then
  584.     BEGIN
  585.       Reg.AX := 1;
  586.       INTR (Mouse_Interrupt, Reg);
  587.     END;
  588. END;
  589.  
  590. {############ INTERRUPT # 2 HIDE THE Mouse ############}
  591. PROCEDURE HideMouse;
  592. VAR
  593.   Reg : Registers;
  594. BEGIN
  595.   if MouseExists then
  596.     BEGIN
  597.       Reg.AX := 2;
  598.       INTR (Mouse_Interrupt, Reg);
  599.     END;
  600. END;
  601.  
  602. {############ THIS IS THE HEART TO IDENTIFY Mouse EventS ############}
  603. FUNCTION MouseStatus(VAR X,Y:Integer):Integer;
  604. VAR
  605.   status:Word;
  606. BEGIN
  607.      If Mouse.Event <> 0 then
  608.         BEGIN
  609.              Case Mouse.Event of
  610.                   left_button_pressed     : Status := 1;
  611.                   left_button_released    : Status := 2;
  612.                   right_button_pressed    : Status := 3;
  613.                   right_button_released   : Status := 4;
  614.                   Mouse_moving            : Status := 5;
  615.              END
  616.         END   ELSE Status := 0;
  617.      X:=Mouse.Col;
  618.      Y:=Mouse.Row;
  619.      MouseStatus := Status;
  620. END;
  621.  
  622.  
  623. {############ CHECK FOR Mouse POINTER IN RECTANGLE ############}
  624.                 { OR ANY POINT FOR THAT MATTER }
  625. FUNCTION MouseinR(VAR P: Point; VAR R : Rect) : Boolean;
  626. VAR
  627.   stat, X, Y : Integer;
  628. BEGIN
  629.     MouseInR:= (P.X >= R.A.X) and (P.X <= R.B.X) and (P.Y >= R.A.Y) and (P.Y <= R.B.Y);
  630. END;
  631.  
  632. {############ INTERRUPT # 4 MOVE THE Mouse ############}
  633. PROCEDURE MoveMouse(X,Y : Integer);
  634. VAR
  635.   Reg : Registers;
  636. BEGIN
  637.   if MouseExists then
  638.     BEGIN
  639.       Reg.AX := 4;
  640.       Reg.CX :=X;
  641.       Reg.DX :=Y;
  642.       INTR (Mouse_Interrupt, Reg);
  643.       MouseExists := (Reg.AX <> 0);
  644.     END;
  645. END;
  646.  
  647. {############ INTERRUPT # 5 SELF ExPLANATORY ############}
  648. FUNCTION LastxPress(Button : Byte) : Word;
  649. VAR
  650.   Reg : Registers;
  651. BEGIN
  652.     Reg.AX := 5;
  653.     Reg.BX := Button;
  654.         INTR (Mouse_Interrupt, Reg);
  655.     lastxPress := Reg.CX;
  656. END;
  657.  
  658. {############ INTERRUPT # 5 SELF ExPLANATORY ############}
  659. FUNCTION LastYPress(Button : Byte) : Word;
  660. VAR
  661.   Reg : Registers;
  662. BEGIN
  663.     Reg.AX := 5;
  664.     Reg.BX := Button;
  665.         INTR (Mouse_Interrupt, Reg);
  666.     lastYPress := Reg.DX;
  667. END; 
  668.  
  669. {############ SELF ExPLANATORY ############}
  670. PROCEDURE WaitforRelease;
  671. VAR
  672.    MS1 : Integer;
  673.    P   : Point;
  674. BEGIN
  675.      REPEAT
  676.            MS1 := Mousestatus(P.X,P.Y);
  677.      UNTIL (MS1 = 2);
  678. END;
  679.  
  680. {############ GET DOUBLE CLICK ############}
  681. FUNCTION DoubleClick ( P : point): Boolean;
  682. VAR
  683.    MS1, MS2, MS3 : Integer;
  684.    ok : Boolean;
  685. BEGIN
  686.      MS1 := LastxPress(0);
  687.      MS2 := LastYPress(0);
  688.      MS3 := Mousestatus(P.X,P.Y);
  689.      ok := (MS1 = P.X) and (MS2 = P.Y);
  690.      DoubleClick := (ok) and (MS3 = 1);
  691. END;
  692.  
  693. {############ INTERRUPT # 7 RESTRICT Mouse MOVEMENT TO RECTANGLE ############}
  694. PROCEDURE MouseMinMax(X,Y,x1,y1:Integer);
  695. VAR
  696.   Reg : Registers;
  697. BEGIN
  698.   if MouseExists then
  699.     BEGIN
  700.       Reg.AX := 7;
  701.       Reg.CX :=X;
  702.       Reg.DX :=x1;
  703.       INTR (Mouse_Interrupt, Reg);
  704.       Reg.AX := 8;
  705.       Reg.CX :=Y;
  706.       Reg.DX :=y1;
  707.       INTR (Mouse_Interrupt, Reg);
  708.       MouseExists := (Reg.AX <> 0);
  709.     END;
  710. END;
  711.  
  712. {############ INTERRUPT # 9 Mouse CURSOR IN GRAPHICS MODE ############}
  713. PROCEDURE MouseCursor(Mask : Masktype; X,Y : Integer);
  714. VAR
  715.   Reg : Registers;
  716. BEGIN
  717.     Reg.AX := 9;
  718.     Reg.BX := X;   {horizontal hot spot}   { Software cursor = 0 }
  719.     Reg.CX := Y;   {vertical hot spot}
  720.     Reg.DX := Ofs(MasK);     {screen mask}
  721.     Reg.ES := Seg(Mask);     {cursor mask}
  722.     INTR (Mouse_Interrupt, Reg);
  723. END;
  724.  
  725. {############ INTERRUPT # 9 + RESET Mouse DRIVER ############}
  726. PROCEDURE GraphicsMouse(Mask : MaskType; X,Y : Integer);
  727. VAR
  728.   Reg : Registers;
  729. BEGIN
  730.   MouseInit;
  731.   if MouseExists then
  732.   BEGIN
  733.     Reg.AX := 9;
  734.     Reg.BX := X;   {horizontal hot spot}   { Software cursor = 0 }
  735.     Reg.CX := Y;   {vertical hot spot}
  736.     Reg.DX := Ofs(MasK);     {screen mask}
  737.     Reg.ES := Seg(Mask);     {cursor mask}
  738.   END;
  739.     INTR (Mouse_Interrupt, Reg);
  740.     InGraphics := true;
  741. END;
  742.  
  743. {############ INTERRUPT # 10 Mouse CURSOR IN TExT MODE ############}
  744. PROCEDURE TextMouse;
  745. VAR
  746.   Reg : Registers;
  747. BEGIN
  748.   MouseInit;
  749.   if MouseExists then
  750.   BEGIN
  751.        Reg.AX := 10;
  752.        Reg.BX := 0;
  753.        Reg.CX := $FFFF;
  754.        Reg.DX := $7700;
  755.   END;
  756.   INTR (Mouse_Interrupt, Reg);
  757. END;
  758.  
  759. {############ INTERRUPT # 16 HIDE Mouse IF IN BOx ############}
  760.       { THIS IS USED FOR UPDATING REGIONS OF THE SCREEN }
  761. PROCEDURE MouseBox(BX,by,bx1,by1 : Word);
  762. VAR
  763.   Reg : Registers;
  764. BEGIN
  765.   if MouseExists then
  766.   BEGIN
  767.      Reg.AX := 16;
  768.      Reg.ES := seg(HideBox);
  769.      Reg.DX := ofs(HideBox);
  770.      HideBox.X:=BX;
  771.      HideBox.Y:=BY;
  772.      HideBox.x1:=Bx1;
  773.      HideBox.Y1:=BY1;
  774.   END;
  775.     INTR (Mouse_Interrupt, Reg);
  776. END;
  777.  
  778.  
  779.  
  780.  
  781. {############ Mouse INTERRUPT HANDLER TO INTERACT WITH Mouse DRIVER ############}
  782.                    { YOU STILL NEED A Mouse DRIVER INSTALLED }
  783.       { NOTICE THAT I'M USING INTERRUPT $33 TO COMMUNICATE WITH Mouse DRIVER }
  784. PROCEDURE Mouse_Handler
  785.            (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP :Word);
  786. INTERRUPT;
  787.  
  788. BEGIN
  789.   Mouse.Event         := AX;    { INTERRUPT SERVICE TO CALL }
  790.   Mouse.Button_Status := BX;    { THIS RETURNS BUTTON STATUS }
  791.   Mouse.Col           := CX;    { THIS IS Y }
  792.   Mouse.Row           := DX;    { THIS IS X }
  793.   If NOT INGRAPHICS then
  794.                         BEGIN
  795.                         { IF NOT IN GRAPHICS DIVIDE TO OBTAINED TExT COORDINATES }
  796.                              Mouse.Col           := CX div 8;
  797.                              Mouse.Row           := DX div 8;
  798.                         END;
  799.    { DONE IN ASSEMBLY TO INCREASE SPEED }
  800.   InLine ( 
  801.     $8B/$E5/
  802.     $5D/
  803.     $07/
  804.     $1F/
  805.     $5F/
  806.     $5E/
  807.     $5A/
  808.     $59/
  809.     $5B/
  810.     $58/
  811.     $CB );
  812. END; { PROCEDURE Mouse_Handler }
  813.  
  814. {############ INTERRUPT # 12 INSTALL MY OWN INTERRUPT CALL ############}
  815. PROCEDURE Install_Mouse_Interrupt_Handler;
  816. VAR
  817.   Reg : Registers;
  818. BEGIN
  819.   Reg.AX := 12;
  820.   { ANY OF THESE EventS WILL ACTIVATE THE INTERRUPT }
  821.   Reg.CX := Left_Button_Released +
  822.             Right_Button_Released +
  823.             Left_Button_Pressed +
  824.             Right_Button_Pressed +
  825.             Mouse_Moving;
  826.  
  827.   Reg.DX := Ofs(Mouse_Handler);               { KEEP OLD VECTOR TABLE }
  828.   Reg.ES := Seg(Mouse_Handler);
  829.   INTR (Mouse_Interrupt, Reg);
  830. END;
  831.  
  832. {############ INITIALIZE THE Mouse, CHECK IF DRIVER AND Mouse PRESENT ############}
  833. PROCEDURE MouseInit;
  834. BEGIN
  835.   Mouse.Event     := 0;
  836.   MouseExists    := False;
  837.   InGraphics := False;
  838.     ResetMouse;
  839.     if MouseExists then
  840.     BEGIN
  841.       MoveMouse(0,0);
  842.       Install_Mouse_Interrupt_Handler;
  843.     END;
  844. END; { PROCEDURE Initialize_Mouse }
  845. {$F-}
  846. END.
  847.  
  848. {############ END OF EMouse LIBRARY ############}
  849.