JPmouse.zip, Version 1.0 Program to manage the dBASE IV, Version 1.5, mouse. *------------------------------------------------------------------------ *-- Programmer : Jay Parsons, BORBBS Jparsons, CIS 70160,340 *-- Date : May 25, 1992 *-- Notes : A .bin file for the dBASE IV 1.5 mouse. *-- Revisions : None *-- Usage : See below. *-- Parameters : a single character among six; see below. *------------------------------------------------------------------------ This ZIP file contains the following files: JPMOUSE.BIN, a dBASE IV 1.5 .bin to manage the mouse. JPMOUSE.ASM, its source code. README, this file. If you simply want to use the mouse in dBASE IV, Version 1.5, you don't need any of this. This program is intended for those developers who wish to control the use of the mouse by their users. Disclaimer The concepts used in this program were picked up through hurried experimentation and skimming the mostly unhelpful "Microsoft Mouse Programmer's Reference", Second Edition, Microsoft Press, 1991. If the author's understanding is incorrect, which has happened, so is the program. Advice of any errors in understanding, as well as of any bugs in the program, will be appreciated. Use in general SETMOUSE.BIN must be loaded by the dBASE command LOAD Setmouse. Thereafter, it may be called with any of five one-character arguments that fall into three groups: '?' to check for and reset mouse. Does NOT show it '+' to enable driver and show(?) mouse cursor '-' to disable driver and hide mouse cursor 'S' to show(?) cursor only 'H' to hide cursor only Example: LOAD JPmouse Ismouse = ( call("JPmouse","?") = 'T' ) If no argument is given, the routine does nothing and returns nothing. If an argument of at least one character is given, the routine does as follows: If the character is not in the set of permissible arguments ( lower- case is acceptable for letters ), it does nothing and returns 'F'. If the argument is '?', it checks for a mouse and enables it. It should not turn the mouse on, but it will be on if the .bin has been called from the dot prompt. If called this way, the .bin returns either 'T' if a mouse driver is found or 'F'. In all other cases, it acts as though there is a mouse whether there is or not and returns 'T'. NOTE: As always in dBASE, a .bin can return a value only 1) as the result of the call() function; or 2) in a variable passed as an argument. Consequently, do not use 'CALL JPmouse WITH "?"'. The .bin will report the status to the argument buffer in which dBASE passed the character literal "?", but dBASE will have no way to access it. Use the call() function instead of the CALL command, or place the argument in a variable and CALL WITH that. Anatomy of Mice Why all the complication? Because dBASE itself turns the mouse on when issuing the dot prompt, because the mouse calls work in complex ways, and because turning the mouse on when it is on leaves immobile cursors, "mouse droppings", on the screen. The designers of the mouse software considered the possibility that a subroutine or function might want to hide the mouse cursor while doing video output, but that the mouse cursor might already have been hidden by some higher-level routine. Accordingly, the mouse is designed so that any call to turn it off will do so, but a call to turn it on will take effect only if it was on before the last call to turn it off. A counter that I call the "showmouse" counter is kept. Turning the mouse on increases its value; turning it off decreases it. The mouse comes on only when the showmouse counter is zero, after which no more calls to turn it on change the counter, although they do leave mouse turds. A call to reset the mouse sets the counter to -1, hidden but ready to be shown by the next call. Mouse driver functions Microsoft decreed that the mouse driver should inhabit interrupt 33h (51) and respond in fixed ways to calls to that interrupt. While numerous functions are provided that this program does not use, these are the interrupt 33h functions it does use: Function 0 Reset mouse Function 1 Show mouse Function 2 Hide mouse Function 1Fh Disable mouse Function 20h Enable mouse The reset function, Function 0, cleans up everything, returns the mouse to screen center, enables it, and sets the showmouse counter to -1. The show function increments the showmouse counter. If it was -1, it becomes 0 and the mouse cursor appears. If it was 0, mouse turds appear. The hide function decrements the showmouse counter, always hiding the mouse cursor since the counter is never greater than 0. The disable function stops the mouse driver from tracking what the mouse does, and the enable function starts it tracking again. Neither has a direct effect on the mouse cursor. The arguments to JPmouse call these functions as follows: '?' calls function 0. '+' calls function 20h, then function 1. '-' calls function 1Fh, then function 2. 'S' calls function 1 only. 'H' calls function 2 only. Belt, Suspenders and Velcro too The "?" call to the .bin uses the technique recommended by Microsoft to detect the presence of a mouse driver. This is a totally stupid technique. It first looks for "00 00 00 00" as the vector for int 33h, the mouse interrupt. To be sure, if this vector were null there would be a serious problem, because the processor would jump to location 0000:0000 and try to execute as code the address found there. A crash would almost surely result. However, one of the first things the computer does on power up is place a jump to an IRET in each interrupt vector so that calling one that is not used will not be fatal. If there is in fact a set of four nulls as the int 33h vector, there's a lot more wrong than the absence of a mouse and it is unlikely that this defense will salvage the situation. The presence of an IRET at the location pointed to by the int 33h vector does show there is no mouse driver. On the other hand, calling one of the int 33h functions such as 0 to reset the mouse will, if the vector points to an IRET, return with nothing changed, after which the calling program will know there is no driver. Accordingly, checking for an IRET is essentially a waste of time. If you have an assembler, be brave and remove this garbage from the program. dBASE Programming In programs, it is often desirable to check for a mouse and turn it on if it exists with one operation. From the dot prompt, this is disastrous because after the program turns on the mouse, so will dBASE, leaving mouse turds. Consequently, this program is written so that when the bin is called with "?", it should not set the mouse on. Unfortunately, the state of the mouse is hard to predict. I think, but do not know for sure, that calling this bin with "?", then with "-", and finally with "+" will always turn on the mouse and its cursor without leaving mouse droppings. Assistance of any volunteer "beta testers" in figuring out how to do this properly is welcomed. If the mouse is disabled with '-', enable it again with '+' and the cursor will reappear in the same place it disappeared from. If you want to start it over in the center of the screen after a call with '-', call with '?'. Don't, however, call with an '?' in a function or other subroutine if a higher-level routine may have itself turned the mouse off. To avoid turning it on inappropriately, use only the '+' and '-', or 'H' and 'S', calls in such a case. You should be able to keep track of whether the mouse is on or off with a program variable, remembering that dBASE will reset it and turn it on after a RUN command. You may call JPmouse with '+' and '-' to switch from one state to the other. However, if you lose track, calling with '+' may leave mouse turds. If in doubt, call with '?' to reset it, then with "-", before calling with '+'. Why then the 'H' and 'S' calls? These will not often be needed. They simply allow hiding the mouse cursor quickly and showing it again when it is required only to hide it for an instant, as during a screen repaint. If the mouse is to be off while dBASE is accepting actions from the user, use '-' instead so the user's clicks will be ignored. When leaving a program, if the mouse is off, be sure to turn it on with a call with "+". If you don't, dBASE will get the mouse in an unknown state and mouse turds or just absence of the mouse when wanted may ensue. Summary Check for mouse with "?" Turn off with "-". Turn on, after "?" and only if off, with "+". If you lose track of the showmouse counter, call with "?" then "+" to prevent mouse droppings. Before leaving a program, turn it on with "+" if off. In a procedure or function: Do not use "?" if the mouse may already have been turned off for good reason outside. Use "-" to hide it and "+" to restore it to its condition before "-". For momentary hide and reshow, where disabling the mouse driver is not needed to keep dBASE from mistaking user fiddling for useful input: Use "H" and "S" instead of "-" and "+" if the very slight increase in speed of execution matters. If you've lost track of the showmouse counter, use "?" to reset it to -1, then use "S" to show the cursor. *----------------------------------------------------------------------- This program is not copyrighted. Use it as you wish, no charge. However, I'll appreciate your leaving my name and address with it so that you or others can report bugs or other problems. Bernardsville, NJ 07924 Jay Parsons May 25, 1992 BORBBS Jparsons, CIS 70160,340