No announcement yet.

capture mouse clicks with a TSR

  • Filter
  • Time
  • Show
Clear All
new posts

  • capture mouse clicks with a TSR

    Is it possible to capture the mouse movements and clicks through a TSR?
    Much like one would start a TSR on a key, but on a click instead?
    I would like to know before I put too much more effort into this

    Jonathan Simpson

    Jonathan Simpson
    Jonathan Simpson

  • #2
    Hmmm, haven't touched PB/DOS in quite a while...

    ..but if the mouse generates interrupts as it moves and clicks, I "guess" you could look at using POPUP INTERRUPT, unless the interrupt generated is one of those for which POPUP INTERRUPT is not permitted. (See manual, I know they are listed there).

    And if that interrupt is one of the forbidden interrupts, I "suppose" you could install an Interrupt Service Routine. (I remember Dave Navarro and Alan Earnshaw co-authrored an article in BASICally Speaking on this topic).

    But a long time ago in a galaxy far far away it seems I recall something I did which might be useful........yes, there it is...
      Bin,  Bytes:    21387, Count:   177, 29-Jul-96
      Title   : File Pickbox unit for DOS
      Create a callable SUB which allows a user to navigate the directory tree
      and select a file using the keyboard or a mouse. Completely self-contained
      PBU - no PUBLIC, EXTERNAL, $LINK or DECLARE. Copyright, free for personal
      use. Upgrade of 1993 file; from Michael Mattias. Demo, documentation and
      full source included (PB 3.1+ required).
    This code, which was one of the more popular downloads from the Compuserve version of PB Peer Support, reads mouse clicks by polling, not by use of a TSR, but may be instructive anyway.

    I'll place this in the public domain and send it to anyone who wants it. Just drop me an email. I have the ZIP archive on disk and can attach to a reply.

    (I don't think I try to post it, because it's about 1600 total lines of source code)

    Michael Mattias
    Tal Systems Inc.
    Racine WI USA
    mailto:[email protected][email protected]</A>

    [This message has been edited by Michael Mattias (edited May 05, 2004).]
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]


    • #3
      My first guess would be that it's probably impractical. If you can
      tell us more about what you aim to accomplish, though, perhaps
      we can offer some suggestions.

      Tom Hanlin
      PowerBASIC Staff


      • #4
        You bet... I was asked to provide an interface to a set of DOS
        programs used by a restaurant, via a touch screen. These programs
        are key based... you select menu items by key, or by arrow.
        Since the programs run in 80x25 text mode, the basic thought was to
        switch the mode to 80x50 or 80x43, and display keys on the bottom
        half of the screen. The TSR then places the correct keys in the
        buffer to accomodate the DOS based programs, which do not use mouse.
        Since the touch screens in question (and most for that matter)
        simply emulate a mouse, it seems like it should be easy to do,
        provided I can get a TSR to reliably handle mouse input.

        Jonathan Simpson

        Jonathan Simpson
        Jonathan Simpson


        • #5
          Ok. I think you can get there from here. Your program won't actually
          need to monitor every little mouse movement. There's a mouse call that
          you can make that will tell you whether a button has been clicked and,
          if so, where the mouse pointer was at the time. So, you may just be
          able to pop up using a timer, check to see if the mouse was clicked,
          and take it from there. (If that turns out to be too sluggish, there
          are other ways to do it, but that would be easiest).

          Not all DOS-level mouse drivers provide full support for 80x43 or 80x50
          text modes. It would be worth making sure that this is not a problem,
          first! If the mouse pointer won't go over the entire screen, you would
          need to work with the mouse drivers at a lower level, which would be
          a much more complicated business.

          The PB/DOS 3.5 examples contain a mouse support library called MOUSUNIT,
          which may be useful for preliminary testing. It doesn't have the call
          to find out where the mouse was at the last click, though. You can
          probably dig that up in one of the libraries in the Downloads section:

          Tom Hanlin
          PowerBASIC Staff


          • #6
            Did a quick Google:

            This may or may not be what you are looking for, but....

            There are no atheists in a fox hole or the morning of a math test.
            If my flag offends you, I'll help you pack.


            • #7
              Well, using the mousunit file I made some modifications to
              check for clicks (it's just function &h05 of the interrupt instead
              of &h03, pretty minor change). It functions reliably and with
              reasonable speed from the DOS prompt (although there seems to be
              a flickering of the screen) using POPUP TIMER 2. It even works in
              MSDOS edit! but in the end program it's meant for, it misses about 60%
              of the clicks :S. I think I'm going to need to approach this from
              a new angle.

              I came across this link:
              which mentions some interesting things... the most interesting being the following...
              FUNCTION: AX = 0Ch
              Description: Sets the user defined mouse handler.
              Call With : CX = Event Mask

              Bit If set
              0 Mouse Cursor Movement
              1 Left Button Pressed
              2 Left Button Released
              3 Right Button Pressed
              4 Right Button Released
              5 Center Button Pressed
              6 Center Button Released

              ES = Segment of your mouse handler code
              DX = Offset of your mouse handler code
              Returns : AX = Event Mask
              BX = Button Status(1 if pressed)
              Bit 0 = Left Button
              Bit 1 = Right Button
              Bit 2 = Center Button
              CX = Horizontal Coordinate
              DX = Vertical Coordinate

              This is, of course, a function of interrupt 33h (51), and it seems like the idea would work
              but I'm not quite sure how to do this... or if it would be more responsive than the current
              "timer" implementation. I believe that the reason it works so poorly in the cash register
              application is due to constant keyboard polling by that program.

              Jonathan Simpson
              Jonathan Simpson


              • #8
                It's not possible for function 5 to "miss" a click, I should think.
                The button state information is maintained by the mouse driver itself.
                Is there a chance that some other program is also trying to read the
                mouse state at the same time? That could clear the mouse data.

                Keyboard polling should have no effect at all on the accuracy of the
                mouse state data.

                Using function 0Ch is not liable to be any more effective than the
                function 5 approach. Since it involves a direct call from the interrupt
                handler, you'd have to write a service routine entirely in assembly
                language. This routine would save the mouse data, which could later
                be polled in the same way you're currently doing with function 5.

                Tom Hanlin
                PowerBASIC Staff


                • #9
                  There is no other program in the DOS VDM which uses mouse access,
                  so I'm not quite sure what the cause here is. Using function 5
                  made the routine very accurate outside of the target program, but
                  within certain parts, it's very innaccurate. The target program,
                  by the way, is a cash register program written in QuickBasic PDS.

                  In any event, it works properly from within Ms-dos edit.

                  Jonathan Simpson
                  Jonathan Simpson


                  • #10
                    DOS VDM? So, this isn't running "real" DOS? You may be able to get
                    better responsiveness by adjusting the program priority or other
                    settings. If you're using Windows, the "compatible timer emulation"
                    option may make a difference.

                    Tom Hanlin
                    PowerBASIC Staff


                    • #11
                      Tom, your absolutely right.
                      The code was not missing clicks, the problem, it seems, is that
                      the TSR gets called much less often than it should. I am using
                      POPUP TIMER 2, which should translate into about 9.1 times per
                      second, but it's actually only coming up every 3 seconds in
                      certain parts of the program, and it's only a problem on NT based OS's
                      Windows 98 works fine.

                      A little more information here...
                      The program I am adding support is available at
                      It is a free cash register program and it is quite widely used, all over the world.
                      I've been developing addon programs for it for a couple years now.

                      It still feels like it's related to the keyboard input routines... but
                      I could be way off there

                      Jonathan Simpson
                      Jonathan Simpson


                      • #12
                        I created a much more basic popup program which simply displays the time
                        in the upper left corner of the screen. It still has the same problem...
                        But here is some food for thought. It will not update at all Until
                        I move the mouse or hit a key, even though the popup routine is
                        TIMER based. Odd.

                        Jonathan Simpson
                        Jonathan Simpson


                        • #13
                          The timer is virtualized and may not be acting the way you'd expect.
                          Make sure you have set the "compatible timer emulation" checkbox.

                          Tom Hanlin
                          PowerBASIC Staff


                          • #14
                            I seem to be missing this checkbox :S I checked under the properties for
                            the DOS box and I don't see it there... should I be looking elsewhere?

                            Jonathan Simpson
                            Jonathan Simpson


                            • #15
                              On Windows 2000, you get there by right-clicking the program .exe,
                              selecting Properties, then the Program tab, then the Advanced button.
                              If you're not starting the main program through a shortcut, you will
                              probably need to change the _default.pif file instead. This may be
                              found (in Win2k) in the c:\winnt folder, or wherever the base Windows
                              installation is located. In Windows Explorer, it will look like just
                              "_default", even if you have turned off "Hide file extensions for known
                              file types"-- longtime Windows bug. Use the same right-click, Properties,
                              Program, Advanced business.

                              If you're using a different Windows version, you may need to hunt around
                              a bit. The option should be there, but it may have been relocated, just
                              to keep you on your toes.

                              Tom Hanlin
                              PowerBASIC Staff


                              • #16
                                Int &H33 is the mouse interrupt, I use it extensively in QB7, and also
                                used it in QB4.5.

                                It should be reasonably easy to revector this Interrupt to a user handler,
                                but it's a long time since I wrote any TSR's.



                                • #17
                                  Interrupt &H33 is the software interrupt for querying the mouse status
                                  (the DOS-era equivalent of Windows API calls). Intercepting int &H33
                                  would accomplish nothing useful to the app in question.

                                  Tom Hanlin
                                  PowerBASIC Staff


                                  • #18
                                    Well, nothing I've tried seems to have any impact on the
                                    responsiveness under NT based OS's, so I guess it's limited to
                                    DOS and win9x. The timer emulation setting had no impact that I
                                    could see.

                                    If anyone has any other ideas, I would be glad to
                                    hear them... if not, thanks for your help guys (especially Mr. Hanlin)

                                    Jonathan Simpson
                                    Jonathan Simpson


                                    • #19
                                      In my opinion, the best solution would be using Interrupt 33h
                                      Function 0Ch, as J.Simpson mentioned earlier. Call this function
                                      with CX = 00FEh and ES X pointing to the segment ffset address
                                      of the subroutine within your TSR which will handle the mouse
                                      events. Then this subroutine will be called every time a mouse
                                      button is being pressed.
                                      You may have to program this in assembler, however, so it will be
                                      some more work. And also, if I remember right, a subroutine hooked
                                      this way to INT 33h will be unhooked every time the mouse driver
                                      is initialized (INT 33h, AX=0).


                                      Hans Ruegg



                                      • #20
                                        Hans, that seems to make the most sense to me. The problem is,
                                        as far as I can tell from what I've been seeing, it would require
                                        most all the program be written in assembly (can't jump from ASM to PB code, right?).
                                        It seems like it might be more than a little beyond my current abilities.
                                        I'll still look into it further, and maybe eventually I'll be able to get it working.

                                        Jonathan Simpson
                                        Jonathan Simpson