Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Some MOUSE Routines
#1
I was updating my mouse library to incorporate a windows API call and was having a heck of a time. So I wrote this little program to get everything straight in my head before incorporating the changes. I thought others might find the code useful.

Note: This will only work with Windows.

If you run the code let me know if you find any of the values off. Everything tests ok with my Windows 7 Pro machine but I know some changes related to DPI were introduced with Windows 10 that may cause these to be inaccurate. Please let me know if this is the case.

Code: (Select All)
'MOUSE test

TYPE TYPE_IPOINT ' 2D x,y point definition
    x AS LONG '    x long integer coordinate
    y AS LONG '    y long integer coordinate
END TYPE

DECLARE DYNAMIC LIBRARY "user32"
    'get current mouse x/y position
    'http://allapi.mentalis.org/apilist/GetCursorPos.shtml
    FUNCTION GetCursorPos% (lpPoint AS TYPE_IPOINT)
    'system window metrics in pixels
    'https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
    FUNCTION GetSystemMetrics% (BYVAL nIndex AS INTEGER)
END DECLARE

DIM GetXY AS INTEGER '        dummy variable to use with API function call
DIM Mouse AS TYPE_IPOINT '    absolute mouse location on dekstop
DIM CaptionHeight AS INTEGER ' program window caption height
DIM BorderHeight AS INTEGER '  program window border height
DIM BorderWidth AS INTEGER '  program window border width
DIM WindowX1 AS INTEGER '      location of program window on desktop
DIM WindowY1 AS INTEGER '      (everything including borders)
DIM WindowX2 AS INTEGER
DIM WindowY2 AS INTEGER
DIM ClientX1 AS INTEGER '      location of client window on desktop
DIM ClientY1 AS INTEGER '      (the SCREEN statement)
DIM ClientX2 AS INTEGER
DIM ClientY2 AS INTEGER
DIM CaptionX1 AS INTEGER '    location of client window caption on desktop
DIM CaptionY1 AS INTEGER '    (the _TITLE bar)
DIM CaptionX2 AS INTEGER
DIM CaptionY2 AS INTEGER
DIM ClientMouseX AS INTEGER '  relative mouse location on client window
DIM ClientMouseY AS INTEGER
DIM WindowMouseX AS INTEGER '  relative mouse location on program window
DIM WindowMouseY AS INTEGER
DIM CaptionMouseX AS INTEGER ' relative mouse location on program window's caption
DIM CaptionMouseY AS INTEGER
DIM ProgramTitle AS STRING '  program title to display
DIM OldTitle AS STRING '      the old program title (to reduce flickering)

'+-----------------+
'| Begin main code |
'+-----------------+

SCREEN _NEWIMAGE(800, 600, 32) ' create client window

'+---------------------------------------------------------------+
'| Get the program window's caption height and border dimensions |
'|                                                              |
'| Note: This would need to go into the loop to pick up theme    |
'|      changes made by user.                                  |
'+---------------------------------------------------------------+

CaptionHeight = GetSystemMetrics(4) '                        caption height                              (from windows)
BorderHeight = GetSystemMetrics(33) - GetSystemMetrics(6) '  sizing border width - window border width  (from windows)
BorderWidth = GetSystemMetrics(32) - GetSystemMetrics(5) '  sizing border height - window border height (from windows)

DO
    '+---------------------------------------------------------------+
    '| Calculate absolute x,y locations of program window on desktop |
    '+---------------------------------------------------------------+

    WindowX1 = _SCREENX
    WindowY1 = _SCREENY
    WindowX2 = WindowX1 + BorderWidth * 2 + _WIDTH - 1
    WindowY2 = WindowY1 + CaptionHeight + BorderHeight * 2 + _HEIGHT - 1

    '+--------------------------------------------------------------+
    '| Calculate absolute x,y locations of client window on desktop |
    '+--------------------------------------------------------------+

    ClientX1 = _SCREENX + BorderWidth
    ClientY1 = _SCREENY + CaptionHeight + BorderHeight
    ClientX2 = ClientX1 + _WIDTH - 1
    ClientY2 = ClientY1 + _HEIGHT - 1

    '+-----------------------------------------------------------------------+
    '| Calculate absolute x,y locations of program window caption on desktop |
    '+-----------------------------------------------------------------------+

    CaptionX1 = ClientX1
    CaptionY1 = _SCREENY + BorderHeight
    CaptionX2 = ClientX2
    CaptionY2 = CaptionY1 + CaptionHeight

    '+-----------------------------------------------------+
    '| Get absolute mouse location on desktop              |
    '|                                                    |
    '| Calculate relative mouse location on program window |
    '| Calculate relative mouse location on client window  |
    '+-----------------------------------------------------+

    GetXY = GetCursorPos(Mouse) '        absolute mouse location on desktop
    WindowMouseX = Mouse.x - WindowX1 '  relative mouse location on program window
    WindowMouseY = Mouse.y - WindowY1
    ClientMouseX = Mouse.x - ClientX1 '  relative mouse location on client window
    ClientMouseY = Mouse.y - ClientY1
    CaptionMouseX = Mouse.x - CaptionX1
    CaptionMouseY = Mouse.y - CaptionY1

    LOCATE 2, 1 '                        print some variables
    PRINT " Mouse Locations:"
    PRINT
    PRINT " ABSOLUTE DESKTOP X ="; Mouse.x
    PRINT " ABSOLUTE DESKTOP Y ="; Mouse.y
    PRINT
    PRINT " RELATIVE WINDOW  X ="; WindowMouseX
    PRINT " RELATIVE WINDOW  Y ="; WindowMouseY
    PRINT
    PRINT " RELATIVE CAPTION X ="; CaptionMouseX
    PRINT " RELATIVE CAPTION Y ="; CaptionMouseY
    PRINT

    '+-------------------------------------------------------------------------------------------------+
    '| Note: _MOUSEX and _MOUSEY won't even be needed and probably should be avoided because of delays |
    '|      caused by calling the API and then clearing the buffer with WHILE _MOUSEINPUT: WEND      |
    '+-------------------------------------------------------------------------------------------------+

    WHILE _MOUSEINPUT: WEND
    PRINT " RELATIVE CLIENT  X ="; ClientMouseX, "_MOUSEX ="; _MOUSEX; "  ", "These values should equal"
    PRINT " RELATIVE CLIENT  Y ="; ClientMouseY, "_MOUSEY ="; _MOUSEY; "  ", "when pointer is in client"
    PRINT
    PRINT " Program window coordinates on desktop: ("; WindowX1; ","; WindowY1; ") - ("; WindowX2; ","; WindowY2; ")"
    PRINT
    PRINT " Client  window coordinates on desktop: ("; ClientX1; ","; ClientY1; ") - ("; ClientX2; ","; ClientY2; ")"
    PRINT
    PRINT " Caption window coordinates on desktop: ("; CaptionX1; ","; CaptionY1; ") - ("; CaptionX2; ","; CaptionY2; ")"
    PRINT

    IF MouseWithin(Mouse.x, Mouse.y, ClientX1, ClientY1, ClientX2, ClientY2) THEN
        ProgramTitle = "In CLIENT Area          "
    ELSEIF MouseWithin(Mouse.x, Mouse.y, CaptionX1, CaptionY1, CaptionX2, CaptionY2) THEN
        ProgramTitle = "In CAPTION Area        "
    ELSEIF MouseWithin(Mouse.x, Mouse.y, WindowX1, WindowY1, WindowX2, WindowY2) THEN
        ProgramTitle = "On WINDOW Border        "
    ELSE
        ProgramTitle = "Mouse OUTSIDE of program"
    END IF
    PRINT " "; ProgramTitle
    IF OldTitle <> ProgramTitle THEN
        _TITLE ProgramTitle
        OldTitle = ProgramTitle
    END IF

LOOP UNTIL _KEYDOWN(27)
SYSTEM


FUNCTION MouseWithin% (mx AS INTEGER, my AS INTEGER, x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER)

    'Quick and dirty rectangular collision routine

    MouseWithin% = 0
    IF mx >= x1 AND mx <= x2 AND my >= y1 AND my <= y2 THEN MouseWithin% = -1

END FUNCTION
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#2
I got this mouse source and used it in QB64PE 32-bit on Windows 10 and it seems to work.

It is brilliant code when detecting the mouse in Client/Caption/Border/Outside areas.. Did not know that could be done!

Erik.
Reply
#3
(06-05-2024, 03:22 AM)eoredson Wrote: I got this mouse source and used it in QB64PE 32-bit on Windows 10 and it seems to work.

It is brilliant code when detecting the mouse in Client/Caption/Border/Outside areas.. Did not know that could be done!

Erik.
Thank you for testing it. I can't take credit for the API calls. One of our API gurus on the forum showed me that a while back.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply




Users browsing this thread: 4 Guest(s)