home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / basic / mlib30 / mlibsam6.bas < prev    next >
Encoding:
BASIC Source File  |  1994-02-21  |  73.9 KB  |  2,293 lines

  1.  DEFINT A-Z
  2.  '============================= MLIBSAM6.BAS ================================
  3.  '             Copyright (C) 1994 Terry Venn. All rights reserved.
  4.  '
  5.  '                  THIS SAMPLE PROGRAM IS PROVIDED AS IS.
  6.  '
  7.  ' You may modify/use this code in any way you wish, provided that you agree
  8.  ' that Terry Venn has no warranties, obligations or liabilities for any code
  9.  ' contained in this sample program.
  10.  '
  11.  ' QB refers to: QuickBasic 4.5
  12.  ' VBDOS refers to: Visual Basic for DOS
  13.  '
  14.  ' MLIBSAM6.BAS is a mouse event-driven sample program that you can use to
  15.  ' test, and see exactly how the mouse event routines are used. The code is
  16.  ' written in a straight forward, simple to understand manner. You will see
  17.  ' that using the handler's routines gives you more mouse-power, and
  18.  ' simplifies writing code as well.
  19.  '
  20.  ' You may notice that inside the QB environment, the mouse may not respond
  21.  ' when a program is running and is stopped before normal termination due to
  22.  ' an error, or breakpoints, etc.. The reason for this is that our mouse
  23.  ' handler is still active, and must be disabled, giving mouse control back
  24.  ' to QB. To give control back to QB, type: END in the Immediate window and
  25.  ' press Enter, or if possible, restart your program and let it run to normal
  26.  ' termination. The MLIB mouse event handler is automatically disabled when
  27.  ' your program terminates. Once compiled, and outside the QB environment,
  28.  ' our handler is on its own, and this will no longer pose a problem.
  29.  '
  30.  ' To run this sample program from inside the QB environment, start the QB
  31.  ' editor by typing: QB/L MLIBN
  32.  '
  33.  ' To run this sample program from inside the VBDOS environment, start the
  34.  ' editor by typing: VBDOS/L MLIBF
  35.  '
  36.  ' To run this sample program, the following files must be loaded along with
  37.  ' MLIBSAM6.BAS:
  38.  '
  39.  ' MLIB.BI      - MLIB mouse library include file.
  40.  ' MLIBSAM4.BAS - Menu support routines.
  41.  ' MLIBTOOL.BAS - Event handler BASIC support routines.
  42.  '
  43.  ' Mouse event routines:
  44.  '
  45.  ' InMouseHandler(Command)
  46.  '                           Mouse event handler (simular to a TSR program).
  47.  '                           Once installed it immediately becomes active,
  48.  '                           responding to mouse events. You can specify
  49.  '                           which events will be trapped by using the
  50.  '                           optional BASIC routines contained in the file:
  51.  '                           MLIBTOOL.BAS. These events are then stored in
  52.  '                           the event buffer for later use (simular to the
  53.  '                           way keyboard data is stored in the type-ahead
  54.  '                           buffer). The InMouse() function is used to
  55.  '                           retrieve these events when needed. The event
  56.  '                           buffer can hold a maximum of eight events.
  57.  '
  58.  '                           Controlling the event handler:
  59.  '
  60.  '                           Commands-CONST:  Value:  Description:
  61.  '                           ═══════════════  ══════  ═══════════════════════
  62.  '                           EventInstall     1       Installs handler.
  63.  '                           EventEnable      2       Enables handler.
  64.  '                           EventDisable     4       Disables handler.
  65.  '                           ClearBuffer      8       Clears event buffer.
  66.  '                           ────────────────────────────────────────────────
  67.  '
  68.  '                           NOTE: You need to install the handler only once
  69.  '                                 in your code. Once installed it cannot be
  70.  '                                 deinstalled from within your code, the
  71.  '                                 handler will remove itself upon (normal or
  72.  '                                 abnormal) program termination.
  73.  '
  74.  ' Event% = InMouse(MouseX%, MouseY%)
  75.  '
  76.  '                           Returns mouse events. You would poll this
  77.  '                           function for mouse events the same way you would
  78.  '                           poll INKEY$ for keyboard events.
  79.  '
  80.  '                           Argument:  Description:
  81.  '                           ═════════  ═════════════════════════════════════
  82.  '                           Event%     Bit-field returning mouse and shift-
  83.  '                                      state information (see: Event bit-
  84.  '                                      field below).
  85.  '                           MouseX%    Returns horizontal pointer position,
  86.  '                                      WHEN, the event occurred.
  87.  '                           MouseY%    Returns vertical pointer position,
  88.  '                                      WHEN, the event occurred.
  89.  '
  90.  '                                      NOTE: When the event buffer is empty,
  91.  '                                      MouseX, and MouseY%, return the cur-
  92.  '                                      rent pointer position.
  93.  '                           ────────────────────────────────────────────────
  94.  '
  95.  '                           Event bit-field:     Represents (when set):
  96.  '                           ════════════════════ ═══════════════════════════
  97.  '                           00000000 00000000─── Mouse pointer moved.
  98.  '                           └┼┘│││││ ││││││└──── Left button pressed.
  99.  '                            │ │││││ │││││└───── Left button released.
  100.  '                            │ │││││ ││││└────── Right button pressed.
  101.  '                            │ │││││ │││└─────── Right button released.
  102.  '                            │ │││││ ││└──────── Center button pressed.
  103.  '                            │ │││││ │└───────── Center button released.
  104.  '                            │ │││││ └────────── Left button double-click.
  105.  '                            │ ││││└──────────── Right button double-click.
  106.  '                            │ │││└───────────── Center button double-click.
  107.  '                            │ ││└────────────── Shift key down.
  108.  '                            │ │└─────────────── Ctrl key down.
  109.  '                            │ └──────────────── Alt key down.
  110.  '                            └────────────────── Unused.
  111.  '                           ────────────────────────────────────────────────
  112.  '
  113.  ' Segment% = InMouseAddress(Offset%)
  114.  '
  115.  '                           Returns address to the handler's data block.
  116.  '                           This routine is used to change or read the
  117.  '                           handler's default settings. For further
  118.  '                           information, look through the mouse toolkit
  119.  '                           file: MLIBTOOL.BAS.
  120.  '
  121.  '                           Argument:  Description:
  122.  '                           ═════════  ═════════════════════════════════════
  123.  '                           Segment%   Returns the segment part of address.
  124.  '                           Offset%    Returns the offset part of address.
  125.  '                           ────────────────────────────────────────────────
  126.  '
  127.  ' The following are extra routines included with MLIB. They offer greater
  128.  ' speed and/or do things BASIC cannot do.
  129.  '
  130.  ' Value% = GetWord (Segment%, Offset%)
  131.  '
  132.  '                           Returns two bytes from specified memory location
  133.  '                           (simular to BASIC's PEEK function).
  134.  '
  135.  ' PutWord (Segment%, Offset%, Value%)
  136.  '
  137.  '                           Writes two bytes to specified memory location
  138.  '                           (simular to BASIC's POKE statement).
  139.  '
  140.  ' Value% = CvsBin% (BinaryString$)
  141.  '
  142.  '                           Returns the decimal value of the binary string
  143.  '                           representation.
  144.  '     
  145.  '                           BinaryString$ - Must be 16 bytes in length.
  146.  '                                           "0000000000000001" would return
  147.  '                                           the decimal value 1.
  148.  '
  149.  ' BinaryString$ = CviBin$ (Value%)
  150.  '
  151.  '                           Returns a 16 byte string that represents the
  152.  '                           binary value of the passed argument.
  153.  '
  154.  '                           Value% - A value of 1 would return
  155.  '                                    "0000000000000001"
  156.  '
  157.  ' QuickBasic and Visual Basic are trademarks of Microsoft Corporation.
  158.  '===========================================================================
  159.  ' $INCLUDE: 'MLIB.BI'
  160.  
  161.  DECLARE SUB DetectMouse ()
  162.  DECLARE SUB DoodlePad ()
  163.  DECLARE SUB ScreenDisable ()
  164.  DECLARE SUB SaveScreen ()
  165.  DECLARE SUB SaveMenuItems ()
  166.  DECLARE SUB Help ()
  167.  DECLARE SUB ShowBoxes ()
  168.  DECLARE SUB DrawShiftKeys (R%, C%, Action%)
  169.  DECLARE SUB DrawMouse (R%, C%, Action%)
  170.  DECLARE SUB DecodeMouseEvent (MouseEvent%, MouseRow%, MouseCol%, UserDelay%)
  171.  DECLARE SUB TheMainLoop ()
  172.  DECLARE SUB Calculator ()
  173.  DECLARE SUB DrawButtonUp (R%, C%, Wide%, High%, Title$)
  174.  DECLARE SUB DrawButtonDown (R%, C%, Wide%, High%)
  175.  DECLARE FUNCTION MouseOnButton% (X%, MouseRow%, MouseCol%)
  176.  
  177.  ' Text button.
  178.  TYPE ButtonType
  179.       R AS INTEGER
  180.       C AS INTEGER
  181.       W AS INTEGER
  182.       H AS INTEGER
  183.       T AS STRING * 4
  184.  END TYPE
  185.  
  186.  ' Menu.
  187.  TYPE BoxType
  188.       C AS INTEGER ' Column.
  189.       R AS INTEGER ' Row.
  190.       W AS INTEGER ' Width.
  191.       H AS INTEGER ' Height.
  192.  END TYPE
  193.  
  194.  DECLARE SUB DrawBox (R%, C%, Wide%, High%, Title$)
  195.  DECLARE SUB MouseCheck (NewItem%, MouseRow%, MouseCol%)
  196.  DECLARE SUB KeyBoardCheck (Kbd$, ChosenItem%)
  197.  DECLARE SUB ShowMenu (Row%, Col%, Title$)
  198.  DECLARE SUB MouseStatus (MousePress%, MouseCol%, MouseRow%)
  199.  TYPE MenuType
  200.       mnuCol    AS INTEGER
  201.       mnuRow    AS INTEGER
  202.  END TYPE
  203.  CONST TRUE = -1, FALSE = 0
  204.  COMMON SHARED /Menu/ Menu()           AS MenuType ' Menu control array.
  205.  COMMON SHARED /Menu/ MenuItem()       AS STRING   ' Menu item array.
  206.  COMMON SHARED /Menu/ MinItem          AS INTEGER  ' First menu item.
  207.  COMMON SHARED /Menu/ MaxItem          AS INTEGER  ' Last menu item.
  208.  COMMON SHARED /Menu/ LongestMenuItem  AS INTEGER  ' Longest menu item.
  209.  COMMON SHARED /Menu/ LastItem         AS INTEGER  ' Last item hilighted.
  210.  COMMON SHARED /Menu/ NewItem          AS INTEGER  ' Currently hilighted item.
  211.  COMMON SHARED /Menu/ MenuForeColor    AS INTEGER  ' Menu foreground color.
  212.  COMMON SHARED /Menu/ MenuBackColor    AS INTEGER  ' Menu background color.
  213.  COMMON SHARED /Menu/ FrameForeColor   AS INTEGER  ' Box
  214.  COMMON SHARED /Menu/ FrameBackColor   AS INTEGER  ' colors.
  215.  COMMON SHARED /Menu/ BoxForeColor     AS INTEGER  ' "
  216.  COMMON SHARED /Menu/ BoxBackColor     AS INTEGER  ' "
  217.  COMMON SHARED /Menu/ TitleForeColor   AS INTEGER  ' "
  218.  COMMON SHARED /Menu/ TitleBackColor   AS INTEGER  ' "
  219.  
  220.  DIM SHARED Box(1 TO 5) AS BoxType              ' Dialog box.
  221.  DIM SHARED ScreenBuf AS STRING * 4000          ' Display buffer.
  222.  DIM SHARED CurMouseRow AS STRING * 2           ' Current pointer
  223.  DIM SHARED CurMouseCol AS STRING * 2           ' position.
  224.  DIM SHARED MouseButtons AS INTEGER             ' Number of mouse buttons.
  225.  
  226.  DIM SHARED TButton(1 TO 21) AS ButtonType      ' Calculator
  227.  DIM SHARED DecResult AS STRING * 26            ' data.
  228.  DIM SHARED HexResult AS STRING * 26
  229.  DIM SHARED BinResult AS STRING * 26
  230.  
  231.  WIDTH 80, 25
  232.  
  233.  CLS
  234.  
  235.  CALL ShowBoxes
  236.  
  237.  CALL TheMainLoop
  238.  
  239.  COLOR 7, 0
  240.  SCREEN 0, 0, 0
  241.  CLS
  242.  END
  243.  
  244.  ' Calculator button data.
  245.  DATA 2,36,5,3,"7", 2,41,5,3,"8", 2,46,5,3,"9", 2,52,10,3,"C", 5,36,5,3,"4"
  246.  DATA 5,41,5,3,"5", 5,46,5,3,"6", 5,52,10,3,"CE", 8,36,5,3,"1", 8,41,5,3,"2"
  247.  DATA 8,46,5,3,"3", 8,52,5,3,"+", 8,57,5,3,"-", 11,7,7,3,"Not", 11,14,7,3,"And"
  248.  DATA 11,21,7,3,"Or", 11,28,7,3,"Xor", 11,36,5,3,"0", 11,41,10,3,"="
  249.  DATA 11,52,5,3,"*", 11,57,5,3,"\"
  250.  
  251. '
  252. ' Display a simple calculator that can handle integers only (-32768 to 32767).
  253. '
  254. ' Supports mouse and keyboard.
  255. '
  256. SUB Calculator
  257.  
  258.  CALL HidePointer
  259.  
  260.  ' Save our display.
  261.  CALL SaveScreen
  262.  
  263.  ' Background color.
  264.  COLOR 7, 0
  265.  
  266.  ' Draw a background screen.
  267.  FOR R% = 2 TO 24
  268.     LOCATE R%, 1: PRINT STRING$(80, "░");
  269.  NEXT
  270.  
  271.  ' Show help bar.
  272.  COLOR 0, 3: LOCATE 25, 1: PRINT SPACE$(33) + "<Esc=Close Box>" + SPACE$(32);
  273.  
  274.  ' Save colors.
  275.  OldBoxForeColor = BoxForeColor
  276.  OldBoxBackColor = BoxBackColor
  277.  
  278.  BoxForeColor = 0
  279.  BoxBackColor = 7
  280.  
  281.  '===========================================================================
  282.  ' Draw calculator read-outs.
  283.  '===========================================================================
  284.  X% = 5 ' Box index.
  285.  
  286.  Box(X%).W = 64
  287.  Box(X%).H = 15
  288.  
  289.  ' Center box on screen.
  290.  Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  291.  Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  292.  
  293.  Title$ = "Integer Calculator"
  294.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  295.  
  296.  COLOR BoxForeColor, BoxBackColor
  297.  
  298.   LOCATE Box(X%).R + 2, Box(X%).C + 2: PRINT "     ┌──────────────────────────┐"
  299.   LOCATE Box(X%).R + 3, Box(X%).C + 2: PRINT "Dec: │                          │"
  300.   LOCATE Box(X%).R + 4, Box(X%).C + 2: PRINT "     └──────────────────────────┘"
  301.   LOCATE Box(X%).R + 5, Box(X%).C + 2: PRINT "     ┌──────────────────────────┐"
  302.   LOCATE Box(X%).R + 6, Box(X%).C + 2: PRINT "Hex: │                          │"
  303.   LOCATE Box(X%).R + 7, Box(X%).C + 2: PRINT "     └──────────────────────────┘"
  304.   LOCATE Box(X%).R + 8, Box(X%).C + 2: PRINT "     ┌──────────────────────────┐"
  305.   LOCATE Box(X%).R + 9, Box(X%).C + 2: PRINT "Bin: │                          │"
  306.  LOCATE Box(X%).R + 10, Box(X%).C + 2: PRINT "     └──────────────────────────┘"
  307.  
  308.  '===========================================================================
  309.  
  310.  '===========================================================================
  311.  ' Draw the calculator buttons.
  312.  '===========================================================================
  313.  Min% = LBOUND(TButton, 1)
  314.  Max% = UBOUND(TButton, 1)
  315.  
  316.  FOR I% = Min% TO Max%
  317.  
  318.     READ R%
  319.     READ C%
  320.  
  321.     TButton(I%).R = Box(X%).R + R%
  322.     TButton(I%).C = Box(X%).C + C%
  323.     READ TButton(I%).W
  324.     READ TButton(I%).H
  325.     READ TButton(I%).T
  326.  
  327.     CALL DrawButtonUp(TButton(I%).R, TButton(I%).C, TButton(I%).W, TButton(I%).H, TButton(I%).T)
  328.  
  329.  NEXT
  330.  RESTORE
  331.  '===========================================================================
  332.  
  333.  GOSUB HiLiteAccessKey
  334.  
  335.  Result$ = "0"
  336.  NumOps% = 0
  337.  LastInput$ = ""
  338.  OpFlag$ = ""
  339.  Temp$ = "0"
  340.  
  341.  ' Save mask.
  342.  CALL GetEventMask(OldMask%)
  343.  
  344.  ' Trap left button, and mouse movement events.
  345.  NewMask% = NewMask% OR LButtonDown OR LButtonUp OR MouseMoved
  346.  
  347.  ' Use new mask.
  348.  CALL SetEventMask(NewMask%)
  349.  
  350.  ' Print zeros in readouts.
  351.  GOSUB PrintResult
  352.  
  353.  CALL ShowPointer
  354.  
  355.  DO
  356.     DO ' Wait for a mouse or key event.
  357.        MouseEvent% = InMouse(MouseX%, MouseY%)
  358.        MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  359.        MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  360.    
  361.        KeyPress$ = INKEY$
  362.        KeyPress% = LEN(KeyPress$)
  363.  
  364.     LOOP UNTIL MouseEvent% OR KeyPress%
  365.  
  366.     ' Add key support.
  367.     IF KeyPress% THEN
  368.        ChosenButton$ = UCASE$(KeyPress$)
  369.        IF ChosenButton$ = "N" THEN
  370.           ChosenButton$ = "Not"
  371.        ELSEIF ChosenButton$ = "A" THEN
  372.           ChosenButton$ = "And"
  373.        ELSEIF ChosenButton$ = "O" THEN
  374.           ChosenButton$ = "Or"
  375.        ELSEIF ChosenButton$ = "X" THEN
  376.           ChosenButton$ = "Xor"
  377.        ELSEIF ChosenButton$ = "E" THEN
  378.           ChosenButton$ = "CE"
  379.        END IF
  380.     END IF
  381.  
  382.     IF MouseEvent% AND LButtonDown THEN
  383.       
  384.        ' See if we need to exit.
  385.        IF MouseRow% = 25 THEN                       ' If we're on help bar.
  386.           IF MouseCol% > 33 AND MouseCol% < 49 THEN ' <Esc=Close Box>
  387.            
  388.              ' Requires a double-click to close box.
  389.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  390.           END IF
  391.        END IF
  392.       
  393.        ' Show calc button down.
  394.        IF MouseOnButton(Index%, MouseRow%, MouseCol%) THEN
  395.           I% = Index%
  396.           TButtonDown% = -1
  397.           CALL DrawButtonDown(TButton(I%).R, TButton(I%).C, TButton(I%).W, TButton(I%).H)
  398.           GOSUB HiLiteAccessKey
  399.        END IF
  400.  
  401.     ' Show calc button up.
  402.     ELSEIF MouseEvent% AND LButtonUp AND TButtonDown% THEN
  403.     
  404.        ' Button was chosen.
  405.        IF MouseOnButton(Index%, MouseRow%, MouseCol%) THEN
  406.           ChosenButton$ = RTRIM$(TButton(I%).T)
  407.        ELSE
  408.           ChosenButton$ = ""
  409.        END IF
  410.     
  411.        Index% = 0
  412.        TButtonDown% = 0
  413.        CALL DrawButtonUp(TButton(I%).R, TButton(I%).C, TButton(I%).W, TButton(I%).H, TButton(I%).T)
  414.        GOSUB HiLiteAccessKey
  415.     
  416.     ' Check if we need to show calc button down, or up.
  417.     ELSEIF MouseEvent% AND MouseMoved AND TButtonDown% THEN
  418.        IF NOT MouseOnButton(Index%, MouseRow%, MouseCol%) THEN
  419.           CALL DrawButtonUp(TButton(I%).R, TButton(I%).C, TButton(I%).W, TButton(I%).H, TButton(I%).T)
  420.           GOSUB HiLiteAccessKey
  421.        ELSEIF MouseOnButton(Index%, MouseRow%, MouseCol%) THEN
  422.           I% = Index%
  423.           CALL DrawButtonDown(TButton(I%).R, TButton(I%).C, TButton(I%).W, TButton(I%).H)
  424.           GOSUB HiLiteAccessKey
  425.        END IF
  426.  
  427.     END IF
  428.  
  429.     ' If a calc button was chosen.
  430.     IF LEN(ChosenButton$) THEN
  431.  
  432.        ' Calculator code.
  433.        SELECT CASE ChosenButton$
  434.           CASE "C"
  435.              Temp$ = "0"
  436.              Result$ = "0"
  437.              NumOps% = 0
  438.              LastInput$ = ""
  439.              OpFlag$ = ""
  440.              GOSUB PrintResult
  441.  
  442.           CASE IS = "CE"
  443.              Result$ = Temp$
  444.              LastInput$ = ""
  445.              GOSUB PrintResult
  446.  
  447.           CASE "0" TO "9"
  448.              IF LastInput$ <> "NUMS" THEN
  449.                 Result$ = ""
  450.                 GOSUB PrintResult
  451.              END IF
  452.           
  453.              IF VAL(Result$) = 0 THEN Result$ = ""
  454.              Result$ = Result$ + ChosenButton$
  455.              LastInput$ = "NUMS"
  456.           
  457.              GOSUB PrintResult
  458.  
  459.           CASE IS = "Not"
  460.              Result$ = STR$(NOT VAL(Result$))
  461.              GOSUB PrintResult
  462.              LastInput$ = "NUMS"
  463.  
  464.           CASE IS = "\", "*", "-", "+", "=", "And", "Or", "Xor"
  465.              IF LastInput$ = "NUMS" THEN
  466.                 NumOps% = NumOps% + 1
  467.              END IF
  468.            
  469.              Temp$ = Result$
  470.              IF NumOps% = 1 THEN
  471.                 Val1& = VAL(Temp$)
  472.              ELSEIF NumOps% = 2 THEN
  473.                 Val2& = VAL(Temp$)
  474.                 SELECT CASE OpFlag$
  475.                    CASE IS = "*": Val1& = Val1& * Val2&
  476.                    CASE IS = "-": Val1& = Val1& - Val2&
  477.                    CASE IS = "+": Val1& = Val1& + Val2&
  478.                    CASE IS = "\"
  479.                       IF Val2& = 0 THEN
  480.                          ErrorMsg$ = "     Division by zero"
  481.                          GOSUB ShowCalcError
  482.                       ELSE
  483.                          Val1& = Val1& \ Val2&
  484.                       END IF
  485.                 
  486.                    CASE IS = "=": Val1& = Val2&
  487.                    CASE IS = "And": Val1& = Val1& AND Val2&
  488.                    CASE IS = "Or": Val1& = Val1& OR Val2&
  489.                    CASE IS = "Xor": Val1& = Val1& XOR Val2&
  490.  
  491.                 END SELECT
  492.  
  493.                 Result$ = LTRIM$(STR$(Val1&))
  494.                 NumOps% = 1
  495.                 GOSUB PrintResult
  496.  
  497.              END IF
  498.  
  499.           LastInput$ = ""
  500.           OpFlag$ = ChosenButton$
  501.  
  502.        END SELECT
  503.  
  504.        ChosenButton$ = ""
  505.     END IF
  506.  
  507.  LOOP UNTIL KeyPress$ = CHR$(27)
  508.  
  509.  ' Restore colors.
  510.  BoxForeColor = OldBoxForeColor
  511.  BoxBackColor = OldBoxBackColor
  512.  COLOR BoxForeColor, BoxBackColor
  513.  
  514.  ' Restore mask.
  515.  CALL SetEventMask(OldMask%)
  516.  
  517.  ' Restore our display.
  518.  CALL SaveScreen
  519.  
  520.  EXIT SUB
  521.  
  522. ' Show result.
  523. PrintResult:
  524.  
  525.  DecResult = Result$
  526.  HexResult = Result$
  527.  BinResult = Result$
  528.  
  529.  ' Test for overflow.
  530.  Test& = VAL(Result$)
  531.  IF Test& > 32767 OR Test& < -32768 THEN
  532.     ErrorMsg$ = "         Overflow"
  533.     GOSUB ShowCalcError
  534.  END IF
  535.  
  536.  IF ErrFlag% THEN
  537.     ErrFlag% = 0
  538.     Temp$ = "0"
  539.     Result$ = "0"
  540.     NumOps% = 0
  541.     LastInput$ = ""
  542.     OpFlag$ = ""
  543.  END IF
  544.  
  545.  RSET DecResult = Result$
  546.  RSET HexResult = HEX$(VAL(Result$))
  547.  RSET BinResult = CviBin$(VAL(Result$))
  548.  
  549.  CALL HidePointer
  550.  LOCATE Box(X%).R + 3, Box(X%).C + 8: PRINT DecResult
  551.  LOCATE Box(X%).R + 6, Box(X%).C + 8: PRINT HexResult
  552.  LOCATE Box(X%).R + 9, Box(X%).C + 8: PRINT BinResult
  553.  CALL ShowPointer
  554.  
  555.  RETURN
  556.  
  557. HiLiteAccessKey:
  558.  
  559.  CALL HidePointer
  560.  COLOR 15, 7
  561.  LOCATE Box(X%).R + 3, Box(X%).C + 57: PRINT "C"
  562.  LOCATE Box(X%).R + 6, Box(X%).C + 57: PRINT "E"
  563.  LOCATE Box(X%).R + 12, Box(X%).C + 9: PRINT "N"
  564.  LOCATE Box(X%).R + 12, Box(X%).C + 16: PRINT "A"
  565.  LOCATE Box(X%).R + 12, Box(X%).C + 23: PRINT "O"
  566.  LOCATE Box(X%).R + 12, Box(X%).C + 30: PRINT "X"
  567.  COLOR BoxForeColor, BoxBackColor
  568.  CALL ShowPointer
  569.  RETURN
  570.  
  571. ShowCalcError:
  572.  
  573.  ' Draw the Help box on the screen.
  574.  '===========================================================================
  575.  ErrFlag% = -1
  576.  
  577.  R% = Box(X%).R
  578.  C% = Box(X%).C
  579.  H% = Box(X%).H
  580.  W% = Box(X%).W
  581.  
  582.  CALL HidePointer
  583.  
  584.  ' Save screen.
  585.  PCOPY 0, 1
  586.  
  587.  CALL ScreenDisable
  588.  
  589.  Box(X%).H = 5
  590.  Box(X%).W = 30
  591.  
  592.  ' Center box on screen.
  593.  Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  594.  Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  595.  
  596.  Title$ = "Calculator Error"
  597.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  598.  
  599.  COLOR BoxForeColor, BoxBackColor
  600.  
  601.  ' Print message.
  602.  LOCATE Box(X%).R + 2, Box(X%).C + 2: PRINT ErrorMsg$
  603.  
  604.  CALL ShowPointer
  605.  
  606.  DO ' Wait for a mouse or key event.
  607.     MouseEvent% = InMouse(MouseX%, MouseY%)
  608.     MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  609.     MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  610.   
  611.     KeyPress$ = INKEY$
  612.       
  613.     IF MouseEvent% AND LButtonDown THEN
  614.        ' See if we need to exit.
  615.        IF MouseRow% = 25 THEN                       ' If we're on help bar.
  616.           IF MouseCol% > 33 AND MouseCol% < 49 THEN ' <Esc=Close Box>
  617.           
  618.              ' Requires a double-click to close box.
  619.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  620.           END IF
  621.        END IF
  622.     END IF
  623.  
  624.  LOOP UNTIL KeyPress$ = CHR$(27)
  625.  
  626.  KeyPress$ = ""
  627.  
  628.  CALL HidePointer
  629.  
  630.  ' Restore screen.
  631.  PCOPY 1, 0
  632.  
  633.  CALL ShowPointer
  634.  
  635.  Box(X%).R = R%
  636.  Box(X%).C = C%
  637.  Box(X%).H = H%
  638.  Box(X%).W = W%
  639.  
  640.  RETURN
  641.  
  642. END SUB
  643.  
  644. '
  645. ' Show mouse events on the screen.
  646. '
  647. SUB DecodeMouseEvent (MouseEvent%, MouseRow%, MouseCol%, UserDelay%)
  648.  
  649.  CALL HidePointer
  650.  
  651.  ' Update the Miscellaneous box.
  652.  CALL GetDblClkSettings(ClickS%, ClickW%, ClickH%)
  653.  LOCATE Box(4).R + 2, Box(4).C + 12: PRINT CviBin$(MouseEvent%)
  654.  LOCATE Box(4).R + 3, Box(4).C + 17: PRINT GetEventsPending
  655.  LOCATE Box(4).R + 4, Box(4).C + 17: PRINT GetHeadPtr
  656.  LOCATE Box(4).R + 5, Box(4).C + 17: PRINT GetTailPtr
  657.  LOCATE Box(4).R + 6, Box(4).C + 17: PRINT ClickS%; "   "
  658.  LOCATE Box(4).R + 7, Box(4).C + 17: PRINT ClickW%; "   "
  659.  LOCATE Box(4).R + 8, Box(4).C + 17: PRINT ClickH%; "   "
  660.  
  661.  DoDelay% = 0
  662.  
  663.  ' Print the position of the mouse pointer WHEN the event occurred.
  664.  LOCATE Box(2).R + 2, Box(2).C + 2
  665.  PRINT "Row:"; MouseRow%; "   Col:"; MouseCol%; " "
  666.    
  667.  ' Test for a mouse button press or release.
  668.  ' Test for each separately, as more than one
  669.  ' event can occur at the same time.
  670.  ' Position of mouse image.
  671.  R% = Box(2).R + 3: C% = Box(2).C + 2
  672.  IF MouseEvent% AND LButtonDown THEN ' Draw left button down.
  673.     CALL DrawMouse(R%, C%, -LButtonDown)
  674.  END IF
  675.  IF MouseEvent% AND LButtonUp THEN   ' Draw left button up.
  676.     CALL DrawMouse(R%, C%, LButtonUp)
  677.  END IF
  678.  IF MouseEvent% AND RButtonDown THEN ' Draw right button down.
  679.     CALL DrawMouse(R%, C%, -RButtonDown)
  680.  END IF
  681.  IF MouseEvent% AND RButtonUp THEN   ' Draw right button up.
  682.     CALL DrawMouse(R%, C%, RButtonUp)
  683.  END IF
  684.  IF MouseEvent% AND CButtonDown THEN ' Draw center button down.
  685.     CALL DrawMouse(R%, C%, -CButtonDown)
  686.  END IF
  687.  IF MouseEvent% AND CButtonUp THEN   ' Draw center button up.
  688.     CALL DrawMouse(R%, C%, CButtonUp)
  689.  END IF
  690.  
  691.  ' Test for double-click events.
  692.  IF MouseEvent% AND LButtonDblClk THEN
  693.     CALL DrawMouse(R%, C%, -LButtonDblClk): DoDelay% = -1
  694.  END IF
  695.  IF MouseEvent% AND RButtonDblClk THEN
  696.     CALL DrawMouse(R%, C%, -RButtonDblClk): DoDelay% = -1
  697.  END IF
  698.  IF MouseEvent% AND CButtonDblClk THEN
  699.     CALL DrawMouse(R%, C%, -CButtonDblClk): DoDelay% = -1
  700.  END IF
  701.  IF MouseEvent% AND MouseMoved THEN
  702.     CALL DrawMouse(R%, C%, -MouseMoved): DoDelay% = -1
  703.  END IF
  704.  
  705.  ' Test for shift-state key events.
  706.  ' The key must be down during mouse event, for the shift event
  707.  ' to be recognized.
  708.  ' Position of shift-state key images.
  709.  C% = Box(3).C + 3: R% = Box(3).R + 2
  710.  IF MouseEvent% AND AltKey THEN
  711.     CALL DrawShiftKeys(R%, C%, -AltKey): DoDelay% = -1
  712.  END IF
  713.  IF MouseEvent% AND ShiftKey THEN
  714.     CALL DrawShiftKeys(R%, C%, -ShiftKey): DoDelay% = -1
  715.  END IF
  716.  IF MouseEvent% AND CtrlKey THEN
  717.     CALL DrawShiftKeys(R%, C%, -CtrlKey): DoDelay% = -1
  718.  END IF
  719.  
  720.  CALL ShowPointer
  721.  
  722.  ' Loop here for a while so we can
  723.  ' see which event(s) took place.
  724.  IF DoDelay% AND UserDelay% THEN
  725.     T& = TIMER + .5
  726.     WHILE TIMER < T&: WEND
  727.  END IF
  728.       
  729.  ' Cleanup Mouse Events box.
  730.  R% = Box(2).R + 3: C% = Box(2).C + 2
  731.  CALL DrawMouse(R%, C%, MouseMoved)
  732.  
  733.  ' Clear all double-clicks.
  734.  CALL DrawMouse(R%, C%, LButtonDblClk)
  735.  
  736.  ' Cleanup Key Events box.
  737.  R% = Box(3).R + 2: C% = Box(3).C + 3
  738.  CALL DrawShiftKeys(R%, C%, AltKey)
  739.  CALL DrawShiftKeys(R%, C%, ShiftKey)
  740.  CALL DrawShiftKeys(R%, C%, CtrlKey)
  741.  
  742. END SUB
  743.  
  744. '
  745. ' Check for the existence of a mouse, if a mouse is detected, it is
  746. ' initialized along with the MLIB library. If no mouse is found, program
  747. ' exits.
  748. '
  749. SUB DetectMouse
  750.  
  751.  ' Name of box.
  752.  Title$ = "Initialize Mouse"
  753.  
  754.  ' Save our display.
  755.  CALL SaveScreen
  756.  CALL ScreenDisable
  757.  
  758.  ' Box index.
  759.  X% = 5
  760.  
  761.  '===========================================================================
  762.  ' Display message box.
  763.  '===========================================================================
  764.  Box(X%).W = 38
  765.  Box(X%).H = 7
  766.  
  767.  ' Center box on screen.
  768.  Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  769.  Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  770.  
  771.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  772.  COLOR BoxForeColor, BoxBackColor
  773.  
  774.  LOCATE Box(X%).R + 2, Box(X%).C + 7: PRINT "Initializing the mouse"
  775.  LOCATE Box(X%).R + 4, Box(X%).C + 9: PRINT "Please wait..."
  776.  '===========================================================================
  777.  
  778.  ' Initialize the mouse, and MLIB.
  779.  CALL InitPointer(MouseButtons)
  780.  
  781.  ' If MouseButtons equals zero, there's no mouse installed.
  782.  IF MouseButtons = 0 THEN
  783.    
  784.     LOCATE Box(X%).R + 2, Box(X%).C + 7: PRINT "Unable to detect a mouse!"
  785.     LOCATE Box(X%).R + 4, Box(X%).C + 9: PRINT "Press any key to exit"
  786.  
  787.     BEEP
  788.  
  789.     ' Wait for a key press.
  790.     WHILE LEN(INKEY$) = 0: WEND
  791.  
  792.     COLOR 7, 0
  793.     SCREEN 0, 0, 0
  794.     CLS
  795.     END
  796.  
  797.  END IF
  798.    
  799.  ' Restore our display.
  800.  CALL SaveScreen
  801.  
  802. END SUB
  803.  
  804. '
  805. ' Demonstrates: Mouse movement and button events.
  806. '
  807. ' You will notice if the mouse is moved too quickly, characters will be
  808. ' missed when drawing. This is due to the fact that the operating system
  809. ' allows only a limited number of mouse checks per second.
  810. '
  811. ' IMPORTANT: Trapping mouse movement can noticeably slow program execution
  812. '            down. Therefore, in speed critical areas, you should turn this
  813. '            feature off.
  814. '
  815. SUB DoodlePad
  816.  
  817.  ' Name of box.
  818.  Title$ = "Doodle Pad"
  819.  
  820.  ' Save our display.
  821.  CALL SaveScreen
  822.  CALL ScreenDisable
  823.  
  824.  ' Box index.
  825.  X% = 5
  826.  
  827.  ' Get status of handler.
  828.  Status% = InMouseState
  829.  
  830.  ' If handler is not active.
  831.  IF Status% = 0 OR Status% AND EventDisable THEN
  832.     
  833.     '===========================================================================
  834.     ' Display message box.
  835.     '===========================================================================
  836.     Box(X%).W = 38
  837.     Box(X%).H = 12
  838.  
  839.     ' Center box on screen.
  840.     Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  841.     Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  842.  
  843.     CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  844.     COLOR BoxForeColor, BoxBackColor
  845.    
  846.     LOCATE Box(X%).R + 2, Box(X%).C + 2: PRINT "Mouse event handler is not active!"
  847.     LOCATE Box(X%).R + 4, Box(X%).C + 2: PRINT "Choose from Menu: "
  848.     LOCATE Box(X%).R + 6, Box(X%).C + 5: PRINT "1. Install Handler."
  849.     LOCATE Box(X%).R + 7, Box(X%).C + 5: PRINT "2. Enable Handler."
  850.     LOCATE Box(X%).R + 9, Box(X%).C + 5: PRINT "Press any key to continue..."
  851.     '===========================================================================
  852.    
  853.     ' Wait for a key press.
  854.     WHILE LEN(INKEY$) = 0: WEND
  855.  
  856.     ' Restore our display.
  857.     CALL SaveScreen
  858.     EXIT SUB
  859.  END IF
  860.  
  861.  CALL HidePointer
  862.  
  863.  ' Show help bar.
  864.  COLOR 0, 3: LOCATE 25, 1: PRINT "     <Left=Doodle>  <Shift+Left=Erase>  <Right DblClk=New>  <Esc=Close Box>     ";
  865.  CALL ShowPointer
  866.  
  867.  ' Get the current event mask (events currently being trapped).
  868.  CALL GetEventMask(OldMask%)
  869.  
  870.  ' DoodlePad, requires the following mouse events trapped.
  871.  CALL SetEventMask(NewMask% OR RButtonDown OR LButtonUp OR LButtonDown OR MouseMoved)
  872.  
  873.  ' Get pointer rate of travel settings.
  874.  CALL GetSpeedM(OldH%, OldV%, OldD%)
  875.  
  876.  ' Use our own settings here.
  877.  CALL SetSpeedM(30, 30, 20)
  878.  
  879.  '===========================================================================
  880.  ' Draw the Doodle Pad box on the screen.
  881.  '===========================================================================
  882.  Box(X%).W = 70
  883.  Box(X%).H = 21
  884.  
  885.  ' Center box on screen.
  886.  Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  887.  Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  888.  
  889.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  890.  
  891.  COLOR BoxForeColor, BoxBackColor
  892.  '===========================================================================
  893.  
  894.  DO
  895.     DO ' Wait for a mouse or key event.
  896.        MouseEvent% = InMouse(MouseX%, MouseY%)
  897.        MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  898.        MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  899.        KeyPress$ = INKEY$
  900.     LOOP UNTIL MouseEvent% OR LEN(KeyPress$)
  901.    
  902.     ' Show that the left button went down.
  903.     IF MouseEvent% AND LButtonDown THEN
  904.        LeftDown% = -1
  905.       
  906.        ' See if we need to exit.
  907.        IF MouseRow% = 25 THEN                       ' If we're on help bar.
  908.           IF MouseCol% > 60 AND MouseCol% < 76 THEN ' <Esc=Close Box>
  909.             
  910.              ' Requires a double-click to close box.
  911.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  912.           END IF
  913.        END IF
  914.    
  915.     ' Show that the left button went up,
  916.     ELSEIF MouseEvent% AND LButtonUp THEN
  917.        LeftDown% = 0
  918.     
  919.     ' Check if doodle pad needs to be cleared.
  920.     ELSEIF MouseEvent% AND RButtonDblClk AND DidDoodle% THEN
  921.        
  922.        ' Clear did doodle flag.
  923.        DidDoodle% = 0
  924.  
  925.        ' Requires a double-click to completely erase pad.
  926.        CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  927.     END IF
  928.  
  929.     ' Doodle code begins here.
  930.     IF LeftDown% THEN
  931.          
  932.        ' If the pointer is inside the draw box.
  933.        IF MouseRow% >= Box(X%).R + 1 AND MouseRow% <= (Box(X%).R + Box(X%).H) - 2 THEN
  934.           IF MouseCol% >= Box(X%).C + 1 AND MouseCol% <= (Box(X%).C + Box(X%).W) - 2 THEN
  935.             
  936.              ' Draw if the pointer moved, or if the left
  937.              ' button is down.
  938.              IF MouseEvent% AND MouseMoved OR LeftDown% THEN
  939.            
  940.                 ' If the shift key bit is set, reverse colors
  941.                 ' to erase, else use the normal colors.
  942.                 IF MouseEvent% AND ShiftKey THEN
  943.                    COLOR BoxBackColor, BoxForeColor
  944.                 ELSE
  945.                    COLOR BoxForeColor, BoxBackColor
  946.                 END IF
  947.            
  948.                 ' Draw or erase a character.
  949.                 CALL HidePointer
  950.                 LOCATE MouseRow%, MouseCol%
  951.                 PRINT CHR$(219);
  952.                 CALL ShowPointer
  953.                
  954.                 ' Set we did doodle flag.
  955.                 DidDoodle% = -1
  956.              END IF
  957.           END IF
  958.        END IF
  959.     END IF
  960.    
  961.  LOOP UNTIL KeyPress$ = CHR$(27)
  962.  
  963.  COLOR BoxForeColor, BoxBackColor
  964.  
  965.  ' Restore our display.
  966.  CALL SaveScreen
  967.  
  968.  ' Restore original mask.
  969.  CALL SetEventMask(OldMask%)
  970.  
  971.  ' Restore original pointer rate of travel settings.
  972.  CALL SetSpeedM(OldH%, OldV%, OldD%)
  973.  
  974. END SUB
  975.  
  976. '
  977. ' Draw what represents a text button in the down position.
  978. '
  979. ' R - Row
  980. ' C - Col
  981. '
  982. SUB DrawButtonDown (R%, C%, Wide%, High%)
  983.  
  984.  CALL HidePointer
  985.  
  986.  ' Draw frame.
  987.  COLOR BoxForeColor, BoxBackColor
  988.  
  989.  LOCATE R%, C%: PRINT "▄"; STRING$(Wide% - 2, "▄"); "▄";
  990.  
  991.  FOR RR% = R% + 1 TO R% + High% - 2
  992.     LOCATE RR%, C%: PRINT "▌";
  993.     LOCATE RR%, C% + Wide% - 1: PRINT "▐";
  994.  NEXT RR%
  995.  
  996.  LOCATE R% + High% - 1, C%: PRINT "▀"; STRING$(Wide% - 2, "▀"); "▀";
  997.  
  998.  CALL ShowPointer
  999.  
  1000. END SUB
  1001.  
  1002. '
  1003. ' Draw what represents a text button in the up position.
  1004. '
  1005. ' R - Row
  1006. ' C - Col
  1007. '
  1008. SUB DrawButtonUp (R%, C%, Wide%, High%, Title$)
  1009.  
  1010.  CALL HidePointer
  1011.  
  1012.  ' Draw frame.
  1013.  COLOR BoxForeColor, BoxBackColor
  1014.  
  1015.  LOCATE R%, C%: PRINT "┌"; STRING$(Wide% - 2, "─"); "┐";
  1016.  
  1017.  FOR RR% = R% + 1 TO R% + High% - 2
  1018.     LOCATE RR%, C%: PRINT "│";
  1019.     LOCATE RR%, C% + Wide% - 1: PRINT "│";
  1020.  NEXT RR%
  1021.  
  1022.  LOCATE R% + High% - 1, C%:
  1023.  PRINT "└"; STRING$(Wide% - 2, "─"); "┘";
  1024.  
  1025.  ' Fill in frame.
  1026.  COLOR BoxForeColor, BoxBackColor ' Frame fill color.
  1027.  FOR RR% = R% + 1 TO R% + High% - 2
  1028.      LOCATE RR%, C% + 1: PRINT SPACE$(Wide% - 2);
  1029.  NEXT RR%
  1030.  
  1031.  ' Calculate title stuff.
  1032.  TitleBarWidth% = Wide% - 2
  1033.  TitleBarCenter% = (TitleBarWidth%) \ 2
  1034.  
  1035.  Text$ = RTRIM$(Title$)
  1036.  TitleLen% = LEN(Text$)
  1037.  
  1038.  ' Clip title if needed.
  1039.  IF TitleLen% > TitleBarWidth% THEN
  1040.     Text$ = LEFT$(Text$, TitleBarWidth%)
  1041.     TitleLen% = LEN(Text$)
  1042.  END IF
  1043.  
  1044.  ' Calculate title stuff.
  1045.  TitleBarHeight% = High%
  1046.  TitleBarCenter2% = (TitleBarHeight%) \ 2
  1047.  
  1048.  ' Center and print title.
  1049.  LOCATE R% + TitleBarCenter2%, C% + TitleBarCenter% - (TitleLen% \ 2) + 1
  1050.  PRINT Text$
  1051.  
  1052.  CALL ShowPointer
  1053.  
  1054. END SUB
  1055.  
  1056. '
  1057. ' Draw something that resembles a mouse on the screen.
  1058. '
  1059. ' R% - Row    \
  1060. '              - Upper left corner of image.
  1061. ' C% - Column /
  1062. '
  1063. ' Action:  0 - Draw complete mouse.
  1064. '            - A negative value shows event.
  1065. '            - A positive value clears event.
  1066. '
  1067. SUB DrawMouse (R%, C%, Action%)
  1068.  
  1069.  CALL HidePointer
  1070.  
  1071.  IF Action% = 0 THEN
  1072.   
  1073.     COLOR BoxForeColor, BoxBackColor
  1074.  
  1075.         LOCATE R%, C%: PRINT "┌─────┬─────┬─────┐"
  1076.     LOCATE R% + 1, C%: PRINT "│     │     │     │"
  1077.     LOCATE R% + 2, C%: PRINT "│  L  │  C  │  R  │"
  1078.     LOCATE R% + 3, C%: PRINT "│     │     │     │"
  1079.     LOCATE R% + 4, C%: PRINT "├─────┴─────┴─────┤"
  1080.     LOCATE R% + 5, C%: PRINT "│                 │"
  1081.     LOCATE R% + 6, C%: PRINT "│                 │"
  1082.     LOCATE R% + 7, C%: PRINT "│  Double-Click   │"
  1083.     LOCATE R% + 8, C%: PRINT "│                 │"
  1084.     LOCATE R% + 9, C%: PRINT "│                 │"
  1085.    LOCATE R% + 10, C%: PRINT "└─────────────────┘"
  1086.    LOCATE R% + 11, C%: PRINT "┌─────────────────┐"
  1087.    LOCATE R% + 12, C%: PRINT "│                 │"
  1088.    LOCATE R% + 13, C%: PRINT "│   Mouse Moved   │"
  1089.    LOCATE R% + 14, C%: PRINT "│                 │"
  1090.    LOCATE R% + 15, C%: PRINT "└─────────────────┘"
  1091.  
  1092.  ' Show that an event occurred
  1093.  ELSEIF Action% < 0 THEN
  1094.  
  1095.     ' Reverse colors.
  1096.     COLOR BoxBackColor, BoxForeColor
  1097.  
  1098.     IF Action% = -MouseMoved THEN
  1099.       
  1100.        ' Show that the mouse moved.
  1101.        FOR RR% = R% + 12 TO R% + 14
  1102.           LOCATE RR%, C% + 1: PRINT SPACE$(17)
  1103.        NEXT RR%
  1104.        LOCATE R% + 13, C% + 4: PRINT "Mouse Moved"
  1105.  
  1106.     ELSEIF Action% = -LButtonDown THEN
  1107.  
  1108.        ' Draw left button down.
  1109.        FOR RR% = R% + 1 TO R% + 3
  1110.           LOCATE RR%, C% + 1: PRINT SPACE$(5)
  1111.        NEXT RR%
  1112.        LOCATE R% + 2, C% + 3: PRINT "L"
  1113.   
  1114.     ELSEIF Action% = -RButtonDown THEN
  1115.  
  1116.        ' Draw right button down.
  1117.        FOR RR% = R% + 1 TO R% + 3
  1118.           LOCATE RR%, C% + 13: PRINT SPACE$(5)
  1119.        NEXT RR%
  1120.        LOCATE R% + 2, C% + 15: PRINT "R"
  1121.   
  1122.     ELSEIF Action% = -CButtonDown THEN
  1123.  
  1124.        ' Draw center button down.
  1125.        FOR RR% = R% + 1 TO R% + 3
  1126.           LOCATE RR%, C% + 7: PRINT SPACE$(5)
  1127.        NEXT RR%
  1128.        LOCATE R% + 2, C% + 9: PRINT "C"
  1129.  
  1130.     ELSEIF Action% = -LButtonDblClk THEN
  1131.  
  1132.        ' Show that left button was double-clicked.
  1133.        FOR RR% = R% + 5 TO R% + 9
  1134.           LOCATE RR%, C% + 1: PRINT SPACE$(5)
  1135.        NEXT RR%
  1136.        LOCATE R% + 7, C% + 3: PRINT "Dou"
  1137.   
  1138.     ELSEIF Action% = -RButtonDblClk THEN
  1139.  
  1140.        ' Show that right button was double-clicked.
  1141.        FOR RR% = R% + 5 TO R% + 9
  1142.           LOCATE RR%, C% + 13: PRINT SPACE$(5)
  1143.        NEXT RR%
  1144.        LOCATE R% + 7, C% + 13: PRINT "ck"
  1145.   
  1146.     ELSEIF Action% = -CButtonDblClk THEN
  1147.  
  1148.        ' Show that center button was double-clicked.
  1149.        FOR RR% = R% + 5 TO R% + 9
  1150.           LOCATE RR%, C% + 7: PRINT SPACE$(5)
  1151.        NEXT RR%
  1152.        LOCATE R% + 7, C% + 7: PRINT "le-Cl"
  1153.  
  1154.     END IF
  1155.       
  1156.     ' Restore colors.
  1157.     COLOR BoxForeColor, BoxBackColor
  1158.  
  1159.  ' Clear shown events.
  1160.  ELSEIF Action% > 0 THEN
  1161.  
  1162.     COLOR BoxForeColor, BoxBackColor
  1163.   
  1164.     IF Action% = MouseMoved THEN
  1165.       
  1166.        ' Clear mouse moved box.
  1167.        FOR RR% = R% + 12 TO R% + 14
  1168.           LOCATE RR%, C% + 1: PRINT SPACE$(17)
  1169.        NEXT RR%
  1170.        LOCATE R% + 13, C% + 4: PRINT "Mouse Moved"
  1171.   
  1172.     ELSEIF Action% = LButtonUp THEN
  1173.  
  1174.        ' Clear left button box.
  1175.        FOR RR% = R% + 1 TO R% + 3
  1176.           LOCATE RR%, C% + 1: PRINT SPACE$(5)
  1177.        NEXT RR%
  1178.        LOCATE R% + 2, C% + 3: PRINT "L"
  1179.   
  1180.     ELSEIF Action% = RButtonUp THEN
  1181.  
  1182.        ' Clear right button box.
  1183.        FOR RR% = R% + 1 TO R% + 3
  1184.           LOCATE RR%, C% + 13: PRINT SPACE$(5)
  1185.        NEXT RR%
  1186.        LOCATE R% + 2, C% + 15: PRINT "R"
  1187.   
  1188.     ELSEIF Action% = CButtonUp THEN
  1189.  
  1190.        ' Clear center button box.
  1191.        FOR RR% = R% + 1 TO R% + 3
  1192.           LOCATE RR%, C% + 7: PRINT SPACE$(5)
  1193.        NEXT RR%
  1194.        LOCATE R% + 2, C% + 9: PRINT "C"
  1195.   
  1196.     ELSEIF Action% = LButtonDblClk OR RButtonDblClk OR CButtonDblClk THEN
  1197.  
  1198.        ' Clear double-click box.
  1199.        FOR RR% = R% + 5 TO R% + 9
  1200.           LOCATE RR%, C% + 1: PRINT SPACE$(17)
  1201.        NEXT RR%
  1202.        LOCATE R% + 7, C% + 3: PRINT "Double-Click"
  1203.   
  1204.     END IF
  1205.  END IF
  1206.  
  1207.  CALL ShowPointer
  1208.  
  1209. END SUB
  1210.  
  1211. '
  1212. ' Draw boxes that represent the Shift, Ctrl and Alt keys.
  1213. '
  1214. ' R% - Row    \
  1215. '              - Upper left corner of image.
  1216. ' C% - Column /
  1217. '
  1218. ' Action:  0 - Draw complete picture.
  1219. '            - A negative value shows event.
  1220. '            - A positive value removes event.
  1221. '
  1222. SUB DrawShiftKeys (R%, C%, Action%)
  1223.  
  1224.  CALL HidePointer
  1225.  
  1226.  IF Action% = 0 THEN
  1227.  
  1228.     COLOR BoxForeColor, BoxBackColor
  1229.     
  1230.         LOCATE R%, C%: PRINT "┌───────┬──────┬───────┐"
  1231.     LOCATE R% + 1, C%: PRINT "│       │      │       │"
  1232.     LOCATE R% + 2, C%: PRINT "│ Shift │ Ctrl │  Alt  │"
  1233.     LOCATE R% + 3, C%: PRINT "│       │      │       │"
  1234.     LOCATE R% + 4, C%: PRINT "└───────┴──────┴───────┘"
  1235.  
  1236.  ' Show that an event occurred.
  1237.  ELSEIF Action% < 0 THEN
  1238.  
  1239.     ' Reverse colors.
  1240.     COLOR BoxBackColor, BoxForeColor
  1241.  
  1242.     IF Action% = -ShiftKey THEN
  1243.  
  1244.        ' Show that Shift key was down.
  1245.        FOR RR% = R% + 1 TO R% + 3
  1246.           LOCATE RR%, C% + 1: PRINT SPACE$(7)
  1247.        NEXT RR%
  1248.        LOCATE R% + 2, C% + 2: PRINT "Shift"
  1249.  
  1250.     ELSEIF Action% = -CtrlKey THEN
  1251.  
  1252.        ' Show that Ctrl key was down.
  1253.        FOR RR% = R% + 1 TO R% + 3
  1254.           LOCATE RR%, C% + 9: PRINT SPACE$(6)
  1255.        NEXT RR%
  1256.        LOCATE R% + 2, C% + 10: PRINT "Ctrl"
  1257.    
  1258.     ELSEIF Action% = -AltKey THEN
  1259.  
  1260.        ' Show that Alt key was down.
  1261.        FOR RR% = R% + 1 TO R% + 3
  1262.           LOCATE RR%, C% + 16: PRINT SPACE$(7)
  1263.        NEXT RR%
  1264.        LOCATE R% + 2, C% + 18: PRINT "Alt"
  1265.  
  1266.     END IF
  1267.  
  1268.     ' Restore colors.
  1269.     COLOR BoxForeColor, BoxBackColor
  1270.  
  1271.  ' Clear shown events.
  1272.  ELSEIF Action% > 0 THEN
  1273.  
  1274.     COLOR BoxForeColor, BoxBackColor
  1275.    
  1276.     IF Action% = ShiftKey THEN
  1277.  
  1278.        ' Clear Shift key box.
  1279.        FOR RR% = R% + 1 TO R% + 3
  1280.           LOCATE RR%, C% + 1: PRINT SPACE$(7)
  1281.        NEXT RR%
  1282.        LOCATE R% + 2, C% + 2: PRINT "Shift"
  1283.  
  1284.     ELSEIF Action% = CtrlKey THEN
  1285.  
  1286.        ' Clear Ctrl key box.
  1287.        FOR RR% = R% + 1 TO R% + 3
  1288.           LOCATE RR%, C% + 9: PRINT SPACE$(6)
  1289.        NEXT RR%
  1290.        LOCATE R% + 2, C% + 10: PRINT "Ctrl"
  1291.  
  1292.     ELSEIF Action% = AltKey THEN
  1293.  
  1294.        ' Clear Alt key box.
  1295.        FOR RR% = R% + 1 TO R% + 3
  1296.           LOCATE RR%, C% + 16: PRINT SPACE$(7)
  1297.        NEXT RR%
  1298.        LOCATE R% + 2, C% + 18: PRINT "Alt"
  1299.  
  1300.     END IF
  1301.  END IF
  1302.  
  1303.  CALL ShowPointer
  1304.  
  1305.  
  1306. END SUB
  1307.  
  1308. '
  1309. ' Display a simple help screen.
  1310. '
  1311. SUB Help
  1312.  
  1313.  ' Save colors.
  1314.  OldFrameForeColor = FrameForeColor
  1315.  OldFrameBackColor = FrameBackColor
  1316.  OldBoxForeColor = BoxForeColor
  1317.  OldBoxBackColor = BoxBackColor
  1318.  OldTitleForeColor = TitleForeColor
  1319.  OldTitleBackColor = TitleBackColor
  1320.  OldMenuForeColor = MenuForeColor
  1321.  OldMenuBackColor = MenuBackColor
  1322.  
  1323.  CALL HidePointer
  1324.  
  1325.  ' Save our display.
  1326.  CALL SaveScreen
  1327.  
  1328.  CALL ScreenDisable
  1329.  
  1330.  ' Save menu items.
  1331.  CALL SaveMenuItems
  1332.  
  1333.  ' Show help bar.
  1334.  COLOR 0, 3: LOCATE 25, 1: PRINT "   <Arrow=Scroll Menu Items>  <Enter=Choose Menu Item>  <Esc=Close Help Menu>   ";
  1335.  
  1336.  ' Set our Help colors.
  1337.  FrameForeColor = 0
  1338.  FrameBackColor = 7
  1339.  BoxForeColor = 7
  1340.  BoxBackColor = 0
  1341.  TitleForeColor = 15
  1342.  TitleBackColor = 4
  1343.  
  1344.  '===========================================================================
  1345.  ' Display the Help box plus help topics.
  1346.  '===========================================================================
  1347.  X% = 5 ' Box index.
  1348.  Box(X%).C = 15
  1349.  Box(X%).R = 5
  1350.  Box(X%).W = 0
  1351.  Box(X%).H = 0
  1352.  
  1353.  Title$ = "Choose Help On:"
  1354.  
  1355.  ' Define the items to appear on menu.
  1356.  TotalItem% = 4   ' Total number of menu items.
  1357.  
  1358.  REDIM MenuItem(1 TO TotalItem%) AS STRING ' Menu item array.
  1359.  
  1360.  MenuItem(1) = "       Menu Items          "
  1361.  MenuItem(2) = "       Mouse Events        "
  1362.  MenuItem(3) = "       Key Events          "
  1363.  MenuItem(4) = "       Miscellaneous       "
  1364.  
  1365.  MenuForeColor = BoxForeColor: MenuBackColor = BoxBackColor
  1366.  COLOR MenuForeColor, MenuBackColor
  1367.  
  1368.  ' Upper left corner of menu.
  1369.  Row% = Box(X%).R: Col% = Box(X%).C
  1370.  CALL ShowMenu(Row%, Col%, Title$)
  1371.  
  1372.  '===========================================================================
  1373.  CALL ShowPointer
  1374.  
  1375.  DO
  1376.     DO ' Wait for a mouse or key event.
  1377.        MouseEvent% = InMouse(MouseX%, MouseY%)
  1378.        MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  1379.        MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  1380.        KeyPress$ = INKEY$
  1381.     LOOP UNTIL MouseEvent% OR LEN(KeyPress$)
  1382.     
  1383.     ' Check for a mouse event first.
  1384.     IF MouseEvent% AND LButtonDown THEN
  1385.        IF MouseRow% = 25 THEN                           ' If we're on help bar.
  1386.           IF MouseCol% > 3 AND MouseCol% < 29 THEN      ' <Arrow=Scroll Menu Items>
  1387.              KeyPress$ = CHR$(0) + "P"
  1388.           ELSEIF MouseCol% > 30 AND MouseCol% < 55 THEN ' <Enter=Choose Menu Item>
  1389.              KeyPress$ = CHR$(13)
  1390.           ELSEIF MouseCol% > 56 AND MouseCol% < 78 THEN ' <Esc=Close Help Menu>
  1391.             
  1392.              ' Requires a double-click to close help menu.
  1393.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  1394.           END IF
  1395.        END IF
  1396.       
  1397.        ' Check on menu.
  1398.        CALL MouseCheck(ChosenItem%, MouseRow%, MouseCol%)
  1399.  
  1400.     END IF
  1401.   
  1402.     ' Check for a key press.
  1403.     IF KeyPress$ <> "" THEN
  1404.        CALL KeyBoardCheck(KeyPress$, ChosenItem%)
  1405.     END IF
  1406.   
  1407.     IF ChosenItem% THEN
  1408.        HelpTopic$ = LTRIM$(RTRIM$(MenuItem(ChosenItem%)))
  1409.        SELECT CASE HelpTopic$
  1410.           CASE "Menu Items": GOSUB MenuItemsHelp
  1411.           CASE "Mouse Events": GOSUB MouseEventsHelp
  1412.           CASE "Key Events": GOSUB KeyEventsHelp
  1413.           CASE "Miscellaneous": GOSUB MiscellaneousHelp
  1414.        END SELECT
  1415.        KeyPress$ = ""
  1416.        ChosenItem% = 0
  1417.     ELSE
  1418.        HelpTopic$ = ""
  1419.     END IF
  1420.  
  1421.  LOOP UNTIL KeyPress$ = CHR$(27)
  1422.  
  1423.  ' Restore colors.
  1424.  FrameForeColor = OldFrameForeColor
  1425.  FrameBackColor = OldFrameBackColor
  1426.  BoxForeColor = OldBoxForeColor
  1427.  BoxBackColor = OldBoxBackColor
  1428.  TitleForeColor = OldTitleForeColor
  1429.  TitleBackColor = OldTitleBackColor
  1430.  MenuForeColor = OldMenuForeColor
  1431.  MenuBackColor = OldMenuBackColor
  1432.  COLOR MenuForeColor, MenuBackColor
  1433.  
  1434.  ' Restore our display.
  1435.  CALL SaveScreen
  1436.  
  1437.  ' Restore menu items.
  1438.  CALL SaveMenuItems
  1439.  
  1440.  ' Redisplay caller's menu.
  1441.  Row% = Box(1).R: Col% = Box(1).C
  1442.  CALL ShowMenu(Row%, Col%, "Menu")
  1443.  
  1444.  ' Return to caller.
  1445.  EXIT SUB
  1446.  
  1447. MenuItemsHelp:
  1448.  '===========================================================================
  1449.  ' Initialize help array and show help box for: Menu Items.
  1450.  '===========================================================================
  1451.  
  1452.  REDIM H(1 TO 21) AS STRING
  1453.  
  1454.   H(1) = ""
  1455.   H(2) = "Choose:                 To:"
  1456.   H(3) = "══════════════════════  ═════════════════════════════════════════════════"
  1457.   H(4) = "Install Handler         Initialize the mouse event handler."
  1458.   H(5) = "Disable Handler         Disable the mouse event handler."
  1459.   H(6) = "Enable Handler          Enable the mouse event handler."
  1460.   H(7) = "Left Press Off/On       Stop/start trapping left button press events."
  1461.   H(8) = "Left Release Off/On     Stop/start trapping left button release events."
  1462.   H(9) = "Right Press Off/On      Stop/start trapping right button press events."
  1463.  H(10) = "Right Release Off/On    Stop/start trapping right button release events."
  1464.  H(11) = "Center Press Off/On     Stop/start trapping center button press events."
  1465.  H(12) = "Center Release Off/On   Stop/start trapping center button release events."
  1466.  H(13) = "Mouse Move On/Off       Start/stop trapping mouse pointer movement."
  1467.  H(14) = "Clear Buffer            Clear all data from the mouse event buffer."
  1468.  H(15) = "Delay Off/On            Toggle visual display timer off/on."
  1469.  H(16) = "Default Settings        Use demo/mouse event handler default settings."
  1470.  H(17) = "Doodle Pad              Draw, using mouse movement."
  1471.  H(18) = "Calculator              Display a calculator, handles integers only."
  1472.  H(19) = "DOS Shell               Temporarily drop to DOS."
  1473.  H(20) = "Quit Demo               Exit program."
  1474.  H(21) = "─────────────────────────────────────────────────────────────────────────"
  1475.  
  1476.  Box(X%).W = 77
  1477.  Box(X%).H = 23
  1478.  Title$ = "Help: Menu Items"
  1479.  
  1480.  GOSUB ShowHelpBox
  1481.  '===========================================================================
  1482.  RETURN
  1483.  
  1484. MouseEventsHelp:
  1485.  '===========================================================================
  1486.  ' Initialize help array and show help box for: Mouse Events.
  1487.  '===========================================================================
  1488.  
  1489.  REDIM H(1 TO 21) AS STRING
  1490.  
  1491.   H(1) = ""
  1492.   H(2) = "Items:               Indicates the following:"
  1493.   H(3) = "═══════════════════  ═══════════════════════════════════════════════════"
  1494.   H(4) = " Row:    Col:        Pointer position WHEN event occurred, mouse button"
  1495.   H(5) = "┌─────┬─────┬─────┐  status, double-click events, and pointer movement."
  1496.   H(6) = "│  L  │  C  │  R  │"
  1497.   H(7) = "├─────┴─────┴─────┤  MouseEvent% = InMouse(MouseX%, MouseY%)"
  1498.   H(8) = "│                 │"
  1499.   H(9) = "│  Double-Click   │  MouseEvent% bit-field:  Represents (when set):"
  1500.  H(10) = "│                 │  ──────────────────────  ───────────────────────────"
  1501.  H(11) = "└─────────────────┘  00000000 00000000─────  Mouse pointer moved."
  1502.  H(12) = "┌─────────────────┐        ││ ││││││└──────  Left button pressed."
  1503.  H(13) = "│   Mouse Moved   │        ││ │││││└───────  Left button released."
  1504.  H(14) = "└─────────────────┘        ││ ││││└────────  Right button pressed."
  1505.  H(15) = "                           ││ │││└─────────  Right button released."
  1506.  H(16) = "                           ││ ││└──────────  Center button pressed."
  1507.  H(17) = "                           ││ │└───────────  Center button released."
  1508.  H(18) = "                           ││ └────────────  Left button double-click."
  1509.  H(19) = "                           │└──────────────  Right button double-click."
  1510.  H(20) = "                           └───────────────  Center button double-click."
  1511.  H(21) = "────────────────────────────────────────────────────────────────────────"
  1512.  
  1513.  Box(X%).W = 76
  1514.  Box(X%).H = 23
  1515.  Title$ = "Help: Mouse Events"
  1516.  
  1517.  GOSUB ShowHelpBox
  1518.  '===========================================================================
  1519.  RETURN
  1520.  
  1521. KeyEventsHelp:
  1522.  '===========================================================================
  1523.  ' Initialize help array and show help box for: Key Events.
  1524.  '===========================================================================
  1525.  
  1526.  REDIM H(1 TO 17) AS STRING
  1527.  
  1528.   H(1) = ""
  1529.   H(2) = "Item:                 Indicates:"
  1530.   H(3) = "════════════════════  ═════════════════════════════════════════════════════"
  1531.   H(4) = "┌───────┬────┬─────┐  Shift-state key events."
  1532.   H(5) = "│ Shift │Ctrl│ Alt │  Shift events occur when one or more of these keys are"
  1533.   H(6) = "└───────┴────┴─────┘  down during a mouse event."
  1534.   H(7) = ""
  1535.   H(8) = "                      Shift events are returned in the following bit order:"
  1536.  H(9) = ""
  1537.  H(10) = "                      MouseEvent% = InMouse(MouseX%, MouseY%)"
  1538.  H(11) = ""
  1539.  H(12) = "                      MouseEvent% = 00011100 00000000"
  1540.  H(13) = "                                       │││"
  1541.  H(14) = "                                       ││└─ Shift - Value: 1024"
  1542.  H(15) = "                                       │└── Ctrl  - Value: 2048"
  1543.  H(16) = "                                       └─── Alt   - Value: 4096"
  1544.  H(17) = "───────────────────────────────────────────────────────────────────────────"
  1545.  
  1546.  Box(X%).W = 79
  1547.  Box(X%).H = 19
  1548.  Title$ = "Help: Key Events"
  1549.  
  1550.  GOSUB ShowHelpBox
  1551.  '===========================================================================
  1552.  RETURN
  1553.  
  1554. MiscellaneousHelp:
  1555.  '===========================================================================
  1556.  ' Initialize help array and show help box for: Miscellaneous.
  1557.  '===========================================================================
  1558.  
  1559.  REDIM H(1 TO 16) AS STRING
  1560.  
  1561.   H(1) = ""
  1562.   H(2) = "Item:             Description:"
  1563.   H(3) = "════════════════  ══════════════════════════════════════════════════════"
  1564.   H(4) = "Status            Indicates status of the mouse event handler."
  1565.   H(5) = "Bit Field         Binary representation of returned shift/mouse events."
  1566.   H(6) = "Events Pending    Number of events currently in the mouse event buffer."
  1567.   H(7) = "Tail Pointer      Position of tail pointer in the mouse event buffer."
  1568.   H(8) = "Head Pointer      Position of head pointer in the mouse event buffer."
  1569.   H(9) = "Click Speed       Time frame in which a double-click will be registered."
  1570.  H(10) = "Click Width       Amount of horizontal movement (in pixels, on either"
  1571.  H(11) = "                  side of pointer) that the mouse pointer can move"
  1572.  H(12) = "                  between clicks when double-clicking."
  1573.  H(13) = "Click Height      The amount of vertical movement (in pixels, above or"
  1574.  H(14) = "                  below pointer) that the mouse pointer can move between"
  1575.  H(15) = "                  clicks when double-clicking."
  1576.  H(16) = "────────────────────────────────────────────────────────────────────────"
  1577.  
  1578.  Box(X%).W = 76
  1579.  Box(X%).H = 18
  1580.  Title$ = "Help: Miscellaneous"
  1581.  
  1582.  GOSUB ShowHelpBox
  1583.  '===========================================================================
  1584.  RETURN
  1585.  
  1586. ShowHelpBox:
  1587.  
  1588.  '===========================================================================
  1589.  ' For demonstration purposes, we will use a new instance of the mouse
  1590.  ' handler. This will eliminate unwanted events waiting in the buffer. First
  1591.  ' save the handler's state in Buffer$, next, clear the buffer. Now we have a
  1592.  ' new instance to use. After the help screen is cleared, we will restore the
  1593.  ' handler's state back to original.
  1594.  '===========================================================================
  1595.  ' Save handler's state.
  1596.  CALL InMouseSave(Buffer$)
  1597.  
  1598.  ' Clear buffer and zero internal data.
  1599.  CALL InMouseHandler(ClearBuffer)
  1600.  '===========================================================================
  1601.  
  1602.  '===========================================================================
  1603.  ' Draw the Help box on the screen.
  1604.  '===========================================================================
  1605.  CALL HidePointer
  1606.  
  1607.  ' Save help screen.
  1608.  PCOPY 0, 1
  1609.  
  1610.  ' Center box on screen.
  1611.  Box(X%).R = (25 - Box(X%).H) \ 2 + 1
  1612.  Box(X%).C = (80 - Box(X%).W) \ 2 + 1
  1613.  
  1614.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  1615.  
  1616.  ' Show help bar.
  1617.  COLOR 0, 3: LOCATE 25, 1: PRINT SPACE$(30); "<Esc=Close Help Box>"; SPACE$(30);
  1618.  COLOR BoxForeColor, BoxBackColor
  1619.  
  1620.  ' Print help lines.
  1621.  FOR L% = LBOUND(H, 1) TO UBOUND(H, 1)
  1622.     LOCATE Box(X%).R + L%, Box(X%).C + 2: PRINT H(L%)
  1623.  NEXT L%
  1624.  
  1625.  CALL ShowPointer
  1626.  
  1627.  DO ' Wait for a mouse or key event.
  1628.     MouseEvent% = InMouse(MouseX%, MouseY%)
  1629.     MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  1630.     MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  1631.     
  1632.     IF MouseEvent% AND LButtonDown THEN ' On help bar?
  1633.        IF MouseRow% = 25 THEN
  1634.           IF MouseCol% > 30 AND MouseCol% < 51 THEN      '<Esc=Close Help Box>
  1635.             
  1636.              ' Requires a double-click to close help box.
  1637.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  1638.           END IF
  1639.        END IF
  1640.     END IF
  1641.    
  1642.     KeyPress$ = INKEY$
  1643.  
  1644.  LOOP UNTIL KeyPress$ = CHR$(27)
  1645.  
  1646.  ERASE H
  1647.  
  1648.  CALL HidePointer
  1649.  
  1650.  ' Restore help screen.
  1651.  PCOPY 1, 0
  1652.  
  1653.  CALL ShowPointer
  1654.  
  1655.  ' Restore handler's state.
  1656.  CALL InMouseRestore(Buffer$)
  1657.  '===========================================================================
  1658.  
  1659.  RETURN
  1660.  
  1661. END SUB
  1662.  
  1663. '
  1664. ' Checks if mouse pointer is on a button.
  1665. '
  1666. ' X% - Returns index to button.
  1667. '
  1668. FUNCTION MouseOnButton (X%, MouseRow%, MouseCol%)
  1669.  
  1670.  IF X% = 0 THEN
  1671.     FOR X% = LBOUND(TButton, 1) TO UBOUND(TButton, 1)
  1672.  
  1673.         SELECT CASE MouseRow%
  1674.            CASE TButton(X%).R TO TButton(X%).R + TButton(X%).H - 1
  1675.         
  1676.               SELECT CASE MouseCol%
  1677.                  CASE TButton(X%).C TO TButton(X%).C + TButton(X%).W - 1
  1678.                     MouseOnButton = -1
  1679.                     EXIT FUNCTION
  1680.               END SELECT
  1681.         END SELECT
  1682.  
  1683.     NEXT X%
  1684.  
  1685.     ' No match found.
  1686.     X% = 0
  1687.  
  1688.     MouseOnButton = 0
  1689.  
  1690.  ' If X% holds a value upon entry, then check if pointer is on the
  1691.  ' button that X% (index) refers to.
  1692.  ELSE
  1693.   
  1694.     SELECT CASE MouseRow%
  1695.        CASE TButton(X%).R TO TButton(X%).R + TButton(X%).H - 1
  1696.        
  1697.           SELECT CASE MouseCol%
  1698.              CASE TButton(X%).C TO TButton(X%).C + TButton(X%).W - 1
  1699.                 MouseOnButton = -1
  1700.                 EXIT FUNCTION
  1701.           END SELECT
  1702.     END SELECT
  1703.  
  1704.     ' Pointer moved off button.
  1705.     MouseOnButton = 0
  1706.  
  1707.  END IF
  1708.  
  1709. END FUNCTION
  1710.  
  1711. '
  1712. ' Save the contents of MenuItem array in OldMenuArray.
  1713. '
  1714. ' First call saves, second restores.
  1715. '
  1716. SUB SaveMenuItems STATIC
  1717.  
  1718.  'Save the calling procedure's dialog box properties.
  1719.  IF NOT BeenHere% THEN
  1720.  
  1721.     ' Save the menu item array.
  1722.    
  1723.     'Get current boundries.
  1724.     MenuMin% = LBOUND(MenuItem, 1)
  1725.     MenuMax% = UBOUND(MenuItem, 1)
  1726.   
  1727.     REDIM OldMenuArray(MenuMin% TO MenuMax%)   AS STRING
  1728.  
  1729.     FOR Xn% = MenuMin% TO MenuMax%
  1730.  
  1731.         SWAP OldMenuArray(Xn%), MenuItem(Xn%)
  1732.  
  1733.     NEXT Xn%
  1734.  
  1735.     'Save old boundaries.
  1736.     OldMenuMin% = MenuMin%
  1737.     OldMenuMax% = MenuMax%
  1738.  
  1739.     BeenHere% = -1
  1740.     '==========================================================
  1741.  
  1742.  'Restore the calling procedure's button properties.
  1743.  ELSE
  1744.  
  1745.     ' Restore the menu item array.
  1746.     REDIM MenuItem(OldMenuMin% TO OldMenuMax%) AS STRING
  1747.  
  1748.     'Restore the old boundaries.
  1749.     FOR Xn% = OldMenuMin% TO OldMenuMax%
  1750.  
  1751.         SWAP MenuItem(Xn%), OldMenuArray(Xn%)
  1752.  
  1753.     NEXT Xn%
  1754.   
  1755.     ERASE OldMenuArray
  1756.     BeenHere% = 0
  1757.     '==========================================================
  1758.  
  1759.  END IF
  1760.  
  1761. END SUB
  1762.  
  1763. '
  1764. ' Store the contents of display memory in ScreenBuf.
  1765. '
  1766. ' First call saves, second restores.
  1767. '
  1768. SUB SaveScreen
  1769.  
  1770.  STATIC BeenHere%
  1771.  
  1772.  BufSeg% = VARSEG(ScreenBuf)
  1773.  BufOff% = VARPTR(ScreenBuf)
  1774.  
  1775.  IF PEEK(&H463) = &HB4 THEN    ' Monochrome.
  1776.     DisplaySeg% = &HB000
  1777.  ELSE                          ' Color.
  1778.     DisplaySeg% = &HB800
  1779.  END IF
  1780.  
  1781.  CALL HidePointer
  1782.  
  1783.  IF NOT BeenHere% THEN
  1784.  
  1785.     FOR X% = 0 TO 3998 STEP 2
  1786.         Value% = GetWord(DisplaySeg%, X%)
  1787.         CALL PutWord(BufSeg%, BufOff% + X%, Value%)
  1788.     NEXT X%
  1789.  
  1790.     BeenHere% = -1
  1791.  
  1792.  ELSE
  1793.  
  1794.     FOR X% = 0 TO 3998 STEP 2
  1795.         Value% = GetWord(BufSeg%, BufOff% + X%)
  1796.         CALL PutWord(DisplaySeg%, X%, Value%)
  1797.     NEXT X%
  1798.  
  1799.     BeenHere% = 0
  1800.  
  1801.  END IF
  1802.  
  1803.  CALL ShowPointer
  1804.  
  1805. END SUB
  1806.  
  1807. '
  1808. ' Causes the objects on the screen to appear disabled, making new objects
  1809. ' drawn easier to see.
  1810. '
  1811. SUB ScreenDisable
  1812.  
  1813.  IF PEEK(&H463) <> &HB4 THEN            ' If not monochrome.
  1814.  
  1815.     Titles% = TitleBackColor * 16 + TitleForeColor
  1816.     Boxes% = BoxBackColor * 16 + BoxForeColor
  1817.     Item% = MenuForeColor * 16 + MenuBackColor ' These colors are reversed.
  1818.     Shade% = 0 * 16 + 8
  1819.    
  1820.     DEF SEG = &HB800
  1821.  
  1822.     CALL HidePointer
  1823.  
  1824.     FOR X% = 161 TO 3999 STEP 2         ' Skip main title.
  1825.  
  1826.        C% = PEEK(X%)
  1827.        IF C% = Titles% THEN             ' Disable titles.
  1828.           POKE X%, &H70                 ' 7*16+0
  1829.        ELSEIF C% = Boxes% THEN          ' Disable boxes.
  1830.           POKE X%, &H70                 ' 7*16+0
  1831.        ELSEIF C% = Item% THEN           ' Disable menu hilighted item.
  1832.           POKE X%, &H70                 ' 7*16+0
  1833.       
  1834.        ' Works only one level deep.
  1835.        ELSEIF C% = Shade% THEN          ' Remove shading.
  1836.           POKE X%, &H7                  ' 7
  1837.        END IF
  1838.  
  1839.     NEXT X%
  1840.    
  1841.     CALL ShowPointer
  1842.  
  1843.     DEF SEG
  1844.  END IF
  1845.  
  1846. END SUB
  1847.  
  1848. '
  1849. ' Initialize some data and draw boxes on screen.
  1850. '
  1851. SUB ShowBoxes
  1852.  
  1853.  '===========================================================================
  1854.  ' Initialize box colors, and draw a background.
  1855.  '===========================================================================
  1856.  FrameForeColor = 0
  1857.  FrameBackColor = 7
  1858.  BoxForeColor = 7
  1859.  BoxBackColor = 1
  1860.  TitleForeColor = 15
  1861.  TitleBackColor = 5
  1862.  
  1863.  ' Use all the screen.
  1864.  VIEW PRINT
  1865.  
  1866.  ' Background color.
  1867.  COLOR 7, 0
  1868.  
  1869.  ' Draw a background screen.
  1870.  FOR R% = 2 TO 24
  1871.     LOCATE R%, 1: PRINT STRING$(80, "░");
  1872.  NEXT
  1873.  
  1874.  COLOR TitleForeColor, TitleBackColor
  1875.  LOCATE 1, 1: PRINT SPACE$(32); "Mouse Event Test"; SPACE$(32)
  1876.  
  1877.  COLOR 0, 3 ' Draw help bar.
  1878.  LOCATE 25, 1: PRINT "  <F1=Help>  <Arrow=Scroll Menu>  <Enter=Choose Menu Item>  <Esc=Quit>  │ 0 :0  ";
  1879.  '===========================================================================
  1880.  
  1881.  '===========================================================================
  1882.  ' Draw the Menu box on the screen, and show items.
  1883.  '===========================================================================
  1884.  X% = 1
  1885.  Box(X%).C = 2
  1886.  Box(X%).R = 3
  1887.  Box(X%).W = 19
  1888.  Box(X%).H = 11
  1889.  
  1890.  Title$ = "Menu"
  1891.  ' The menu procedure will automatically draw a box.
  1892.  'CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  1893.  
  1894.  ' Define the items that will appear on the menu.
  1895.  TotalItem% = 17   ' Total number of menu items.
  1896.  
  1897.  REDIM MenuItem(1 TO TotalItem%) AS STRING ' Array to hold menu items.
  1898.  
  1899.  MenuItem(1) = " Install Handler    "
  1900.  MenuItem(2) = " Disable Handler    "
  1901.  MenuItem(3) = " Enable Handler     "
  1902.  MenuItem(4) = " Left Press Off     "
  1903.  MenuItem(5) = " Left Release Off   "
  1904.  MenuItem(6) = " Right Press Off    "
  1905.  MenuItem(7) = " Right Release Off  "
  1906.  MenuItem(8) = " Center Press Off   "
  1907.  MenuItem(9) = " Center Release Off "
  1908.  MenuItem(10) = " Mouse Move On      "
  1909.  MenuItem(11) = " Clear Buffer       "
  1910.  MenuItem(12) = " Delay Off          "
  1911.  MenuItem(13) = " Default Settings   "
  1912.  MenuItem(14) = " Doodle Pad         "
  1913.  MenuItem(15) = " Calculator         "
  1914.  MenuItem(16) = " DOS Shell          "
  1915.  MenuItem(17) = " Quit Demo          "
  1916.  
  1917.  MenuForeColor = BoxForeColor: MenuBackColor = BoxBackColor
  1918.  COLOR MenuForeColor, MenuBackColor
  1919.  
  1920.  ' Upper left corner of menu.
  1921.  Row% = Box(X%).R: Col% = Box(X%).C
  1922.  CALL ShowMenu(Row%, Col%, Title$)
  1923.  '===========================================================================
  1924.  
  1925.  '===========================================================================
  1926.  ' Draw the Mouse Events box on the screen.
  1927.  '===========================================================================
  1928.  X% = 2
  1929.  Box(X%).C = 25
  1930.  Box(X%).R = 3
  1931.  Box(X%).W = 23
  1932.  Box(X%).H = 20
  1933.   
  1934.  Title$ = "Mouse Events"
  1935.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  1936.  CALL DrawMouse(Box(X%).R + 3, Box(X%).C + 2, 0)
  1937.  LOCATE Box(2).R + 2, Box(2).C + 2: PRINT "Row:      Col:"
  1938.  
  1939.  '===========================================================================
  1940.  
  1941.  '===========================================================================
  1942.  ' Draw the Key Events box on the screen.
  1943.  '===========================================================================
  1944.  X% = 3
  1945.  Box(X%).C = 50
  1946.  Box(X%).R = 3
  1947.  Box(X%).W = 30
  1948.  Box(X%).H = 9
  1949.  
  1950.  Title$ = "Key Events"
  1951.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  1952.  CALL DrawShiftKeys(Box(X%).R + 2, Box(X%).C + 3, 0)
  1953.  '===========================================================================
  1954.  
  1955.  '===========================================================================
  1956.  ' Draw the Miscellaneous box on the screen.
  1957.  '===========================================================================
  1958.  X% = 4
  1959.  Box(X%).C = 50
  1960.  Box(X%).R = 13
  1961.  Box(X%).W = 30
  1962.  Box(X%).H = 10
  1963.  
  1964.  Title$ = "Miscellaneous"
  1965.  CALL DrawBox(Box(X%).R, Box(X%).C, Box(X%).W, Box(X%).H, Title$)
  1966.  
  1967.  COLOR BoxForeColor, BoxBackColor
  1968.  LOCATE Box(X%).R + 1, Box(X%).C + 2: PRINT "   Status: Not installed"
  1969.  LOCATE Box(X%).R + 2, Box(X%).C + 2: PRINT "Bit Field:"
  1970.  LOCATE Box(X%).R + 3, Box(X%).C + 2: PRINT "Events Pending:"
  1971.  LOCATE Box(X%).R + 4, Box(X%).C + 2: PRINT "  Tail Pointer:"
  1972.  LOCATE Box(X%).R + 5, Box(X%).C + 2: PRINT "  Head Pointer:"
  1973.  LOCATE Box(X%).R + 6, Box(X%).C + 2: PRINT "   Click Speed:"
  1974.  LOCATE Box(X%).R + 7, Box(X%).C + 2: PRINT "   Click Width:"
  1975.  LOCATE Box(X%).R + 8, Box(X%).C + 2: PRINT "  Click Height:"
  1976.  '===========================================================================
  1977.  
  1978. END SUB
  1979.  
  1980. '
  1981. '  This procedure is the main control for the demo.
  1982. '
  1983. SUB TheMainLoop
  1984.  
  1985.  ' If you want to change the default double-click
  1986.  ' settings, just unREM the following few lines of
  1987.  ' code and replace the values with your own.
  1988.  '
  1989.  ' ClickS% = 6  ' Double-click speed  - 18 = 1 second (approx).
  1990.  ' ClickW% = 2  ' Double-click width  - 2 pixels of movement on either side,
  1991.  ' ClickH% = 2  ' Double-click height - plus, above and below pointer.
  1992.  ' CALL SetDblClkSettings(ClickS%, ClickW%, ClickH%)
  1993.  
  1994.  Title$ = "Menu"
  1995.  UserDelay% = -1        ' Turn delay on.
  1996.  
  1997.  DO
  1998.     DO ' Wait for a mouse or key event.
  1999.        MouseEvent% = InMouse(MouseX%, MouseY%)
  2000.        MouseCol% = MouseX% \ 8 + 1 ' Convert to BASIC's
  2001.        MouseRow% = MouseY% \ 8 + 1 ' row/column format.
  2002.       
  2003.        ' InMouse(), returns the current pointer position only
  2004.        ' if the mouse event buffer is empty. Display position
  2005.        ' in lower right hand corner of screen.
  2006.        IF MouseEvent% = 0 THEN
  2007.           IF MouseX% <> OldMouseX% OR MouseY% <> OldMouseY% THEN
  2008.              CurMouseRow = LTRIM$(STR$(MouseRow%))
  2009.              CurMouseCol = LTRIM$(STR$(MouseCol%))
  2010.              COLOR 0, 3: CALL HidePointer
  2011.              LOCATE 25, 75: PRINT CurMouseRow; ":"; CurMouseCol;
  2012.              CALL ShowPointer: COLOR BoxForeColor, BoxBackColor
  2013.              OldMouseX% = MouseX%
  2014.              OldMouseY% = MouseY%
  2015.           END IF
  2016.        END IF
  2017.       
  2018.        KeyPress$ = INKEY$
  2019.  
  2020.     LOOP UNTIL MouseEvent% OR LEN(KeyPress$)
  2021.    
  2022.     IF KeyPress$ = CHR$(0) + CHR$(59) THEN CALL Help ' F1 key.
  2023.    
  2024.     ' Pass event through DecodeMouseEvent() first so we can visually
  2025.     ' see what is happening (if delay is turned on).
  2026.     IF MouseEvent% THEN
  2027.        CALL DecodeMouseEvent(MouseEvent%, MouseRow%, MouseCol%, UserDelay%)
  2028.     END IF
  2029.    
  2030.     ' Check for a mouse event.
  2031.     IF MouseEvent% AND LButtonDown THEN
  2032.        IF MouseRow% = 25 THEN                           ' Pointer on help bar?
  2033.           IF MouseCol% > 2 AND MouseCol% < 12 THEN      ' <F1=Help>
  2034.              CALL Help
  2035.           ELSEIF MouseCol% > 13 AND MouseCol% < 33 THEN ' <Arrow=Scroll Menu>
  2036.              KeyPress$ = CHR$(0) + "P"
  2037.           ELSEIF MouseCol% > 34 AND MouseCol% < 59 THEN ' <Enter=Choose Menu Item>
  2038.              KeyPress$ = CHR$(13)
  2039.           ELSEIF MouseCol% > 60 AND MouseCol% < 71 THEN ' <Esc=Quit>
  2040.              ' Requires a double-click to quit program.
  2041.              IF MouseEvent% AND LButtonDblClk THEN EXIT DO
  2042.           END IF
  2043.        END IF
  2044.       
  2045.        CALL MouseCheck(ChosenItem%, MouseRow%, MouseCol%) ' Menu procedure.
  2046.  
  2047.     END IF
  2048.    
  2049.     ' Check for a key press.
  2050.     IF KeyPress$ <> "" THEN
  2051.        CALL KeyBoardCheck(KeyPress$, ChosenItem%)       ' Menu procedure.
  2052.     END IF
  2053.    
  2054.     IF ChosenItem% THEN
  2055.        ItemText$ = LTRIM$(RTRIM$(MenuItem(ChosenItem%)))
  2056.        SELECT CASE ItemText$
  2057.           CASE "Install Handler"
  2058.  
  2059.              ' Only if handler is not installed.
  2060.              IF InMouseState = 0 THEN
  2061.                 CALL DetectMouse
  2062.                
  2063.                 CALL SetPointer(0, 0)
  2064.  
  2065.                 ' NOTE, installing also shows mouse pointer.
  2066.                 CALL InMouseHandler(EventInstall)
  2067.              END IF
  2068.  
  2069.           CASE "Disable Handler"
  2070.  
  2071.              ' NOTE, disabling also hides mouse pointer.
  2072.              CALL InMouseHandler(EventDisable)
  2073.             
  2074.           CASE "Enable Handler"
  2075.             
  2076.              ' NOTE, enabling also shows mouse pointer.
  2077.              CALL InMouseHandler(EventEnable)
  2078.             
  2079.           ' Trap left button presses.
  2080.           CASE "Left Press On"
  2081.              MenuItem(4) = " Left Press Off     "
  2082.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2083.              CALL GetEventMask(OldMask%)
  2084.             
  2085.              '===============================================================
  2086.              ' CvsBin%- lets you visually see what bit is being added to
  2087.              ' the new mask (by ORing it with the old mask).
  2088.              NewMask% = OldMask% OR CvsBin%("0000000000000010") ' 2
  2089.              '===============================================================
  2090.              
  2091.              ' Inform handler.
  2092.              CALL SetEventMask(NewMask%)
  2093.  
  2094.           ' Stop trapping left button presses.
  2095.           CASE "Left Press Off"
  2096.              MenuItem(4) = " Left Press On      "
  2097.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2098.              CALL GetEventMask(OldMask%)
  2099.             
  2100.              '===============================================================
  2101.              ' CvsBin%- lets you visually see what bit is being removed
  2102.              ' (masked out) from the old mask (by ANDing with the old mask).
  2103.              NewMask% = OldMask% AND CvsBin%("1111111111111101")' -3
  2104.              '===============================================================
  2105.             
  2106.              CALL SetEventMask(NewMask%)
  2107.          
  2108.           ' Trap left button releases.
  2109.           CASE "Left Release On"
  2110.              MenuItem(5) = " Left Release Off   "
  2111.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2112.              CALL GetEventMask(OldMask%)
  2113.             
  2114.              '===============================================================
  2115.              ' OR the constant LButtonUp with (start trapping left button
  2116.              ' release events) the old mask.
  2117.              NewMask% = OldMask% OR LButtonUp
  2118.              'NewMask% = OldMask% OR CvsBin%("0000000000000100") ' 4
  2119.              '===============================================================
  2120.  
  2121.              CALL SetEventMask(NewMask%)
  2122.  
  2123.           ' Stop trapping left button releases.
  2124.           CASE "Left Release Off"
  2125.              MenuItem(5) = " Left Release On    "
  2126.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2127.              CALL GetEventMask(OldMask%)
  2128.             
  2129.              '===============================================================
  2130.              ' Use the NOT operator to mask out (stop trapping) left button
  2131.              ' releases.
  2132.              NewMask% = OldMask% AND NOT LButtonUp
  2133.              'NewMask% = OldMask% AND CvsBin%("1111111111111011") ' -5
  2134.              '===============================================================
  2135.             
  2136.              CALL SetEventMask(NewMask%)
  2137.          
  2138.           CASE "Right Press On"
  2139.              MenuItem(6) = " Right Press Off    "
  2140.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2141.              CALL GetEventMask(OldMask%)
  2142.              NewMask% = OldMask% OR CvsBin%("0000000000001000") ' 8
  2143.              CALL SetEventMask(NewMask%)
  2144.  
  2145.           CASE "Right Press Off"
  2146.              MenuItem(6) = " Right Press On     "
  2147.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2148.              CALL GetEventMask(OldMask%)
  2149.              NewMask% = OldMask% AND CvsBin%("1111111111110111") ' -9
  2150.              CALL SetEventMask(NewMask%)
  2151.          
  2152.           CASE "Right Release On"
  2153.              MenuItem(7) = " Right Release Off  "
  2154.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2155.              CALL GetEventMask(OldMask%)
  2156.              NewMask% = OldMask% OR CvsBin%("0000000000010000") ' 16
  2157.              CALL SetEventMask(NewMask%)
  2158.  
  2159.           CASE "Right Release Off"
  2160.              MenuItem(7) = " Right Release On   "
  2161.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2162.              CALL GetEventMask(OldMask%)
  2163.              NewMask% = OldMask% AND CvsBin%("1111111111101111") ' -17
  2164.              CALL SetEventMask(NewMask%)
  2165.  
  2166.           CASE "Center Press On"
  2167.              MenuItem(8) = " Center Press Off   "
  2168.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2169.              CALL GetEventMask(OldMask%)
  2170.              NewMask% = OldMask% OR CvsBin%("0000000000100000") ' 32
  2171.              CALL SetEventMask(NewMask%)
  2172.  
  2173.           CASE "Center Press Off"
  2174.              MenuItem(8) = " Center Press On    "
  2175.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2176.              CALL GetEventMask(OldMask%)
  2177.              NewMask% = OldMask% AND CvsBin%("1111111111011111") ' -33
  2178.              CALL SetEventMask(NewMask%)
  2179.          
  2180.           CASE "Center Release On"
  2181.              MenuItem(9) = " Center Release Off "
  2182.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2183.              CALL GetEventMask(OldMask%)
  2184.              NewMask% = OldMask% OR CvsBin%("0000000001000000") ' 64
  2185.              CALL SetEventMask(NewMask%)
  2186.  
  2187.           CASE "Center Release Off"
  2188.              MenuItem(9) = " Center Release On  "
  2189.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2190.              CALL GetEventMask(OldMask%)
  2191.              NewMask% = OldMask% AND CvsBin%("1111111110111111") ' -65
  2192.              CALL SetEventMask(NewMask%)
  2193.          
  2194.           CASE "Mouse Move On"
  2195.              MenuItem(10) = " Mouse Move Off     "
  2196.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2197.              CALL GetEventMask(OldMask%)
  2198.              NewMask% = OldMask% OR CvsBin%("0000000000000001") ' 1
  2199.              CALL SetEventMask(NewMask%)
  2200.  
  2201.           CASE "Mouse Move Off"
  2202.              MenuItem(10) = " Mouse Move On      "
  2203.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2204.              CALL GetEventMask(OldMask%)
  2205.              'NewMask% = OldMask% AND CvsBin%("1111111111111110") ' -2
  2206.              NewMask% = OldMask% AND NOT MouseMoved
  2207.              CALL SetEventMask(NewMask%)
  2208.          
  2209.           CASE "Clear Buffer": CALL InMouseHandler(ClearBuffer)
  2210.          
  2211.           CASE "Delay On"
  2212.              UserDelay% = -1
  2213.              MenuItem(12) = " Delay Off          "
  2214.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2215.           
  2216.           CASE "Delay Off"
  2217.              UserDelay% = 0
  2218.              MenuItem(12) = " Delay On           "
  2219.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2220.  
  2221.           CASE "Default Settings"
  2222.              CALL SetDblClkSettings(6, 2, 2)
  2223.              DefaultMask% = CvsBin%("0000000001111110") '126
  2224.              CALL SetEventMask(DefaultMask%)
  2225.              MenuItem(4) = " Left Press Off     "
  2226.              MenuItem(5) = " Left Release Off   "
  2227.              MenuItem(6) = " Right Press Off    "
  2228.              MenuItem(7) = " Right Release Off  "
  2229.              MenuItem(8) = " Center Press Off   "
  2230.              MenuItem(9) = " Center Release Off "
  2231.              MenuItem(10) = " Mouse Move On      "
  2232.              MenuItem(12) = " Delay Off          "
  2233.              CALL ShowMenu(Box(1).R, Box(1).C, Title$)
  2234.              UserDelay% = -1
  2235.  
  2236.              ' Only if disabled.
  2237.              IF InMouseState AND EventDisable THEN
  2238.                 ' NOTE, enabling also shows mouse pointer.
  2239.                 CALL InMouseHandler(EventEnable)
  2240.              END IF
  2241.  
  2242.           CASE "Doodle Pad": CALL DoodlePad
  2243.           CASE "Calculator": CALL Calculator
  2244.  
  2245.           '==================================================================
  2246.           ' We must save our mouse driver's state before shelling in case
  2247.           ' some other program alters it after we have dropped to DOS.
  2248.           '==================================================================
  2249.           CASE "DOS Shell"
  2250.                CALL InMouseHandler(EventDisable) ' Disable event handler.
  2251.                CALL HidePointer
  2252.                MouseSize% = GetSizeM%            ' Get the size of mouse
  2253.                Buf$ = SPACE$(MouseSize%)         ' state and store it in
  2254.                CALL SaveStateM(Buf$, ErrNum%)    ' Buf$.
  2255.                CALL SaveScreen                   ' Save our display.
  2256.                COLOR 7, 0: CLS
  2257.                PRINT "Type EXIT to return. "
  2258.                SHELL
  2259.                CALL SaveScreen                   ' Restore everything back
  2260.                COLOR BoxForeColor, BoxBackColor  ' to normal.
  2261.                CALL RestoreStateM(Buf$, ErrNum%)
  2262.                Buf$ = ""
  2263.                CALL InMouseHandler(EventEnable)
  2264.                CALL ShowPointer
  2265.          
  2266.           CASE "Quit Demo": EXIT DO
  2267.        END SELECT
  2268.        KeyPress$ = ""
  2269.        ChosenItem% = 0
  2270.     ELSE
  2271.        ItemText$ = ""
  2272.     END IF
  2273.    
  2274.     ' Show state of handler.
  2275.     Status% = InMouseState
  2276.  
  2277.     IF Status% = 0 THEN
  2278.        Stat$ = "Not Installed"
  2279.     ELSEIF Status% AND EventEnable THEN
  2280.        Stat$ = "Enabled      "
  2281.     ELSEIF Status% AND EventDisable THEN
  2282.        Stat$ = "Disabled     "
  2283.     END IF
  2284.    
  2285.     CALL HidePointer
  2286.     LOCATE Box(4).R + 1, Box(4).C + 2: PRINT "   Status: "; Stat$
  2287.     CALL ShowPointer
  2288.     
  2289.  LOOP UNTIL KeyPress$ = CHR$(27)
  2290.  
  2291. END SUB
  2292.  
  2293.