Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Detect when mouse leaves program window
#11
Oh that's a good idea.  

(I made an EDIT to my previous post)

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#12
(08-16-2023, 06:24 PM)TerryRitchie Wrote:
(08-16-2023, 06:09 PM)Dav Wrote: Yeah I guess we will have to account for the title bar height.  There's an API called GetSystemMetrics that can be used for that kind of information:
https://learn.microsoft.com/en-us/window...temmetrics

I'm getting ready to leave, so I don't have time to whip something up with it.  I'll try to get on it when getting back home.

Here's some VB code to look at to give you an example: http://allapi.mentalis.org/apilist/7D8B6...CE469.html


- Dav
I was just googling and came across that same API call. I'm like a lost puppy when it comes to working with APIs in QB64 however, something I need to learn and then create a tutorial lesson for others with the same issue.
Eager to follow that tutorial and become less lost with your help. Smile
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#13
(08-16-2023, 09:37 PM)grymmjack Wrote: Eager to follow that tutorial and become less lost with your help. Smile
Well I just brute forced my way through adding another function in Dav's example so I'm off to a good start. Smile
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#14
I just now saw this post but I'm glad y'all got it working.
Tread on those who tread on you

Reply
#15
(08-17-2023, 12:24 PM)SpriggsySpriggs Wrote: I just now saw this post but I'm glad y'all got it working.
Do you have any suggestions on improvement? Dav's solution seems solid. Was I correct that the height of the caption bar and border needed to be taken into account or is there another function that just returns the work area of a window?
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#16
Hmmm.... GetClientRect might take it into account. It reports the coordinates of each corner, if I'm not mistaken.
Tread on those who tread on you

Reply
#17
(08-16-2023, 06:46 PM)TerryRitchie Wrote: The border width and height were always reporting a value of 1 for some reason throwing off the working area calculations within the window by a slight amount.

I traced this down to having used the wrong values for getting the border width and height. There are values for 3D and non-3D borders. Apparently Windows defaults to 3D. I made the changes below that now reflects the working area calculations perfectly. I also made the changes in the original code I posted on the previous page.


Code: (Select All)
TYPE POINTAPI
    x AS LONG
    y AS LONG
END TYPE
DIM apixy AS POINTAPI 'mouse x/y for the GetCursorPos function
DIM CaptionHeight AS INTEGER
DIM BorderHeight AS INTEGER
DIM BoderWidth AS INTEGER
DECLARE DYNAMIC LIBRARY "user32"
    'get current mouse x/y position
    'http://allapi.mentalis.org/apilist/GetCursorPos.shtml
    FUNCTION GetCursorPos% (lpPoint AS POINTAPI)
    '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

SCREEN 12
DO
    CaptionHeight = GetSystemMetrics(4) ' caption (title bar) height in pixels
    BorderWidth = GetSystemMetrics(45) '   3D width of window border in pixels (5 for non-3D)
    BorderHeight = GetSystemMetrics(46) '  3D height of window border in pixels (6 for non-3D)
    'poll mouse x/y
    tmp = GetCursorPos(apixy)
    ax = apixy.x - BorderWidth
    ay = apixy.y - CaptionHeight - BorderHeight
    sx = _SCREENX
    sy = _SCREENY
    CLS: PRINT "MOUSE IN"
    IF ax - sx < 0 THEN CLS: PRINT "MOUSE OUT"
    IF ax - sx > _WIDTH THEN CLS: PRINT "MOUSE OUT"
    IF ay - sy < 0 THEN CLS: PRINT "MOUSE OUT"
    IF ay - sy > _HEIGHT THEN CLS: PRINT "MOUSE OUT"
    LOCATE 2, 2: PRINT "CaptionHeight:"; CaptionHeight
    LOCATE 3, 2: PRINT "BorderWidth  :"; BorderWidth
    LOCATE 4, 2: PRINT "BorderHeight :"; BorderHeight
    _DISPLAY
LOOP

(08-17-2023, 05:34 PM)SpriggsySpriggs Wrote: Hmmm.... GetClientRect might take it into account. It reports the coordinates of each corner, if I'm not mistaken.

I'll look into that, thank you.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#18
(08-17-2023, 05:34 PM)SpriggsySpriggs Wrote: Hmmm.... GetClientRect might take it into account. It reports the coordinates of each corner, if I'm not mistaken.
After testing it seems GetClientRect returns (0,0) - (_WIDTH(0), _HEIGHT(0))

Code: (Select All)
TYPE RECTAPI
    left AS LONG
    top AS LONG
    right AS LONG
    bottom AS LONG
END TYPE

DIM apirect AS RECTAPI

DECLARE DYNAMIC LIBRARY "user32"
    'https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclientrect
    FUNCTION GetClientRect% (BYVAL hWnd AS LONG, lpRect AS RECTAPI)
END DECLARE

SCREEN _NEWIMAGE(800, 600, 32)
_DELAY .25 ' small delay for window to be created
tmp = GetClientRect(_WINDOWHANDLE, apirect)

PRINT apirect.left
PRINT apirect.top
PRINT apirect.right
PRINT apirect.bottom
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#19
See if this doesn't tell you what you want to know:

Code: (Select All)
Type POINTAPI
    x As Long
    y As Long
End Type
Dim apixy As POINTAPI 'mouse x/y for the GetCursorPos function

Declare Dynamic Library "user32" 'get current mouse x/y position
    Function GetCursorPos% (lpPoint As POINTAPI) 'http://allapi.mentalis.org/apilist/GetCursorPos.shtml
End Declare


Screen 12
sx = 100: sy = 100
ScreenMove sx, sy

Do

    'poll mouse x/y
    tmp = GetCursorPos(apixy)
    ax = apixy.x: ay = apixy.y

    Cls: Print "MOUSE IN"
    If ax - sx < 0 Then Cls: Print "MOUSE OUT"
    If ax - sx > _Width Then Cls: Print "MOUSE OUT"
    If ay - sy < 0 Then Cls: Print "MOUSE OUT"
    If ay - sy > _Height Then Cls: Print "MOUSE OUT"
    _Display

Loop

Sub ScreenMove_Middle
    $If BORDERDEC = UNDEFINED Then
        $Let BORDERDEC = TRUE
        Declare Library
            Function glutGet& (ByVal what&)
        End Declare
    $End If
    BorderWidth = glutGet(506)
    TitleBarHeight = glutGet(507)
    _ScreenMove (_DesktopWidth - _Width - BorderWidth) / 2 + 1, (_DesktopHeight - _Height - BorderWidth) / 2 - TitleBarHeight + 1
End Sub

Sub ScreenMove (x, y)
    $If BORDERDEC = UNDEFINED Then
            $LET BORDERDEC = TRUE
            DECLARE LIBRARY
            FUNCTION glutGet& (BYVAL what&)
            END DECLARE
    $End If
    BorderWidth = glutGet(506)
    TitleBarHeight = glutGet(507)
    _ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
End Sub

These two screenmoves will position the program section (not the title bar) where you specify.  All you need to do is check against them to see if you're in window, or not.  Wink
Reply
#20
And there's always THIS option, if you just don't want to be worried about it at all:

Code: (Select All)
Type Rectangle
    left As Long
    top As Long
    right As Long
    bottom As Long
End Type
Dim Rec As Rectangle

Declare Dynamic Library "User32"
    Function ClipCursor%% (Rect As Rectangle) 'sets mouse box work area on desktop
    Sub SetCursorPos (ByVal x As Long, Byval y As Long) 'move cursor position
End Declare


Screen _NewImage(720, 480, 32)
sx = 100: sy = 100
ScreenMove sx, sy
SetCursorPos sx + 10, sy + 10

Rec.left = sx
Rec.top = sy
Rec.bottom = sy + 480
Rec.right = sx + 720
work%% = ClipCursor(Rec)

Print "Click the mouse to quit!"
Do
    While _MouseInput: Wend
    _Limit 15
Loop Until _MouseButton(2) Or _MouseButton(1)
System


Sub ScreenMove_Middle
    $If BORDERDEC = UNDEFINED Then
        $Let BORDERDEC = TRUE
        Declare Library
            Function glutGet& (ByVal what&)
        End Declare
    $End If
    BorderWidth = glutGet(506)
    TitleBarHeight = glutGet(507)
    _ScreenMove (_DesktopWidth - _Width - BorderWidth) / 2 + 1, (_DesktopHeight - _Height - BorderWidth) / 2 - TitleBarHeight + 1
End Sub

Sub ScreenMove (x, y)
    $If BORDERDEC = UNDEFINED Then
            $LET BORDERDEC = TRUE
            DECLARE LIBRARY
            FUNCTION glutGet& (BYVAL what&)
            END DECLARE
    $End If
    BorderWidth = glutGet(506)
    TitleBarHeight = glutGet(507)
    _ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
End Sub
Reply




Users browsing this thread: 12 Guest(s)