Is _MOUSEMOVEMENTY and _MOUSEMOVEMENTX supposed to act this way?
#1
So what I thought should be doable with thee two commands cannot be accomplished.

Here is what the code demonstrates.

1) Sets the program screen to the top left corner of the desktop.
2) Make a screen click, which places the mouse at 0, 0 of your desktop.
3) Now carefully move the mouse around in the program screen, and after a bit, carefully move it back to the upper right corner.

Well it should be back to 0, 0, right? Well, far from it. I mean provided the mouse isn't moved past the borders of the desktop, I would think the relative coordinates should be the same at the same points the mouse originated from: 0, 0 when back at the top left side of the desktop.

Code: (Select All)
_SCREENMOVE 0, 0
_DELAY .1
_SCREENCLICK 0, 0
DO
    _LIMIT 30
    WHILE _MOUSEINPUT
        x = x + _MOUSEMOVEMENTX
        y = y + _MOUSEMOVEMENTY
    WEND
    LOCATE 1, 1: PRINT y; x; "    ";
    IF LEN(INKEY$) THEN
        EXIT DO
    END IF
LOOP
END

Pete
Reply
#2
I believe I know the issue, basically
_MouseMovementX
and
_MouseMovementY
do not just report the delta between mouse X/Y in movement, they actually report movement information more directly from the mouse itself. You can read about it a bit here. The reason it doesn't accurately track your cursor is because Windows doesn't just move your cursor X units for every Y  movement units reported by the mouse, rather it applies the "speed" and "acceleration" pointer settings. This distinction is good for things like games where you're hiding the cursor anyway (and thus you get more accurate info to work with), but not if you're just trying to track where the cursor is.

You can kinda see this if you go into the
Mouse Properties
and turn off
Enhance pointer precision
, that's basically the acceleration setting. When it's off the mouse position reported by your program stays more or less accurate (as far as I can tell). The distance it thinks you traveled is still wrong though because that's dependent on your "mouse pointer speed".
Reply
#3
Very difficult for me to imagine a practical use for this keyword set. Since the difference is very little at the start, but multiplies the longer you use it, I also find it difficult to understand why the developers didn't sync it with the mouse pointer.

So unfortunately we have nothing in QB64 to locate the mouse cursor outside of the program window in the same y, x coordinates that _SCREENCLICK would be assigned to.

If it wasn't for Windows API, I'd have to do a hack where I build a transparent window over the desktop to accomplish this, but since Steve appointed me as the official API Princess, I'll go with this...

Code: (Select All)
REDIM Hold AS POINTAPI
TYPE POINTAPI
    X_Pos AS LONG
    Y_Pos AS LONG
END TYPE

DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION GetCursorPos (lpPoint AS POINTAPI)
END DECLARE

DO
    _LIMIT 30
    z = GetCursorPos(Hold)
    LOCATE 1, 1: PRINT "Col ="; Hold.X_Pos;: LOCATE 1, 11 + 1: PRINT "Row ="; Hold.Y_Pos; "   ";
    IF LEN(INKEY$) THEN
        EXIT DO
    END IF
LOOP
END

Pete
Reply
#4
The API makes some sense when you think of it as a way to directly make use of mouse movement, not a way to track where the cursor is. It's simply not intended for that usage, it's intended for the case where the application has hidden the cursor and is using the mouse to move a camera or etc. In that situation they don't want the cursor acceleration and speed to impact it, such settings are likely configurable within their application instead and they handle it themselves.

Potentially we could add commands for getting the absolute cursor position, it sounds fairly achievable. We'd have to work out how it fits in with the rest of the mouse stuff though, throwing it into _MouseInput might not be the best (your program would have to handle every mouse event from the system), and also we wouldn't want it easily confusable with the existing
_MouseX
and
_MouseY
.
Reply
#5
I'd think the way _SCREENCLICK is set up would be the same method you would want to use for a y and x absolute mouse cursor position addition. Of course it opens up a small can of worms in that _MOUSEMOVEY and X would have to have absolute additions, too.

Maybe something like...

_MOUSEABSY and X

_MOUSEMOVEABSY and X

Oh well, I'm, not the GOTO guy when it comes to coming up with names. If I had Adam's job, all the animals would have been named Spot. See Spot run. See Spot fly. See Spot swim. You get the idea.

For now, I'm going to continue my project with my API solution. The project will make use of a couple more API calls, so it wouldn't have been x-platform, anyway.

Thanks Matt,


Pete (Retired API Princess.)
Reply
#6
Man I had to remind myself of _ScreenClick and I seem to recall _MouseMovementX (sounds like an old Disney ad campaign) wasn't working.

@Pete what did you want from or expect or need from _MouseMovementX ? (That term also drops a hint of a recent mouse presence.)
Wiki: "The _MOUSEMOVEMENTX function returns the relative horizontal position of the mouse cursor as positive or negative values."

Seems like an easy thing to code from a click by saving the mouse x, y and then calc the current location or click from the saved mouse x, y.
b = b + ...
Reply
#7
Like this:
Code: (Select All)
Do
    While _MouseInput: Wend
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then saveMx = mx: saveMy = my
    Cls
    Print mx, my
    Print "Movements:"; mx - saveMx; my - saveMy
    _Display
    _Limit 30
Loop
b = b + ...
Reply
#8
I was playing around with these commands some time ago and dug out the code where I got them to successfully work.

The code is a simple iOS clone, allowing you to move icons around on the screen. While icons are being moved other icons leap out of the way.

Perhaps a peek at the source code will help.

Terry


Attached Files
.zip   Mouse.zip (Size: 18.36 KB / Downloads: 31)
Reply
#9
@bplus

@TerryRitchie

I'm making something where I need the program window minimized and it tracks the mouse position anywhere on the Desktop at the exact coordinates a _SCREENCLICK or SCREENPRINT could be used. Our QB64 _MOUSEY and X functions, of course, only track movement in the QB64 window, not the entire desktop, and no, I don't want to make the QB64 window a desktop overlay. I could, as I could make it perfectly transparent and you'd never even know it was overlying your desktop, but I don't want that. I want the cursor to move about the desktop, the minimized program window to track it, and if I make a click, those coordinates get feed to the _SCREENPRINT command, and at that screen position on some open desktop app the text gets printed.

Now in QB64 the only keywords that track the mouse cursor outside the program window are _MOUSEMOVEMENTY and X. The problem is they apparently, according to Matt, work based on speed and direction, not on absolute pixel location. I get it "relative" but I thought releative movement out would always equal relative movement back, but they don't work that way. So for example, using those keywords to move the pointer and display the difference from the exact upper left corner of the desktop to the middle of the desktop and back will never get you back to 0, 0. Something like 20, -8. Anyway, that's spells fail for using _SCREENCLICK or _SCREENPRINT at specific desktop pixels, so those two QB64 keyword functions are out.

So for now I just created a simple Windows API call that does this for me. I didn't even have to hock my tiara Steve gave me to do it. API Princess my ASCII! I'm the Queen, and Steve knows it!

Pete (Sorry guys, I feel a bit bloated today.) Big Grin
Reply
#10
Something exists besides Window dressing outside a QB64 screen?
b = b + ...
Reply




Users browsing this thread: 1 Guest(s)