[comp.lang.pascal] Microsoft mouse event handler

tswingle@oucsace.cs.ohiou.edu (Tom Swingle) (02/14/91)

I am trying to write a mouse event handler in Turbo Pascal using INT 33,
function 12 (0Ch) which gets called whenever mouse buttons are pressed.  The 
big thing I want to know is:  Do you need to declare your event handler 
procedure as an interrupt?  I have tried to do it both with and without 
declaring the procedure as an interrupt.  

Here is the program I was doing just to try it out:
 
uses crt,dos,mouse; {Mouse unit contains most common mouse functions}

var
 status,button,x,y:integer;
 regs:registers;

{$F+}
procedure leftbuttonpress; {interrupt?}

begin
 writeln('Left button was pressed!');
end;
{$F-}

begin
 minit(status,button); {Reset mouse; declared in mouse unit}
 with regs do begin
  ax:=12;
  cx:=2; {Call when left button is pressed}
  es:=seg(leftbuttonpress);
  dx:=ofs(leftbuttonpress);
 end;
 intr($33,regs);
 repeat mread(button,x,y) until button and rightdown<>0;
  { This line just waits for the right mouse button to be pressed.  Mread 
    reads the current x and y position as well as the current button status.
    Rightdown is a constant equal to 2.} 
 with regs do begin {Now turn off the event handling}
  ax:=12;
  cx:=0;
 end;
 intr($33,regs);
end.

When the procedure leftbuttonpress above is declared as an interrupt, the
message is printed on the screen but then the program hangs, but as it is now
I get a stack overflow error when it is called.  The stack overflow error makes
me think it was expecting an IRET when only a RETF was encountered, leaving the
stack a mess.  It seems to me like it should not be called as an interrupt, but
rather just as a far call.  Does anybody know which way is correct?  And why 
won't either version of my program run?  Did I mess something up in the above
program?  Thanks to anyone who can help me out.

Dave_Wyble.wbst147@xerox.com (02/14/91)

I can't say whether you need to declare you handler as an interrupt, I have
only limited experience with mouse.sys and int 33.  Technically, your routine
is an interrupt handler, your question is really if mouse.sys sets up the IRET
or not.

I do know that you can't make any dos calls from inside your handler.  Notice
that whether or not your handler is declared as an interrupt or not, it is
still called from an interrupt.  As such, no dos calls are allowed. (ie: your
writeln, or any other type of IO).  You probably got your stack error for this
reason; when your handler makes a dos call, dos may get through the call all
right, but it never makes it back, because the stack has been trashed.

I other words, for your example you need to do something like this:

procedure button;
begin
	buttonPressed := true;   { global flag }
end;
begin { main }
	buttonPressed := false;
	{ set up your handler as before here...}
	while not buttonPressed do
		{nothing }
	writeln('button has been pressed ');
	{ reset the handler  }
end.

Hope this helps some.

Dave Wyble
Xerox Corp.
DRW.Wbst147.Xerox.com
(716)422-5293

ebergman@isis.cs.du.edu (Eric Bergman-Terrell) (02/17/91)

I recently added mouse support to a program that I wrote so I may be able
to help you out.  First I got the MicroSoft Mouse Programmer's Manual,
which proved to be indespensible.

My program only calls the mouse driver when it's ready to sample the mouse
state.  In other words, I did not write a mouse interrupt handler - I just
called the relevant mouse driver routines when necessary.

If you really need to write a procedure that is automatically run in
response to a mouse event, I can't help you.  If you just need to sample
the mouse state, I can...


Terrell