PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → [WD20] WM_MouseMove Event
[WD20] WM_MouseMove Event
Débuté par Curtis, 27 sep. 2017 18:32 - 7 réponses
Posté le 27 septembre 2017 - 18:32
Has anyone ever got an Event() with WM_MouseMove(512) to work correctly? I use the following code on a simple window with only a few controls. The trace hits constantly as long as my mouse cursor is inside the window even when it's not moving. I want TempProcedure() to run only when the mouse is moved inside the window.

nMoveEvent is int = Event(TempProcedure, "*.*", WM_MOUSEMOVE) PROCEDURE TempProcedure() Trace("mouse moved")
Posté le 27 septembre 2017 - 20:06
Hi

instead of doing a Trace("mouse moved"), try doing a trace(Position X and position Y of the mouse)...

If I remember correctly, these values are constantly changing of a very small amount, even when the mouse doesn't seem to move...
So generally, you need to calculate the difference in pixel between the current position and the last one and decide WHEN to do something.

Best regards
Posté le 27 septembre 2017 - 20:11
Tracing MouseXPos() and MouseYPos() show that the pixel position stays exactly the same when not moving the mouse.

This is quite frustrating. Thanks though!
Posté le 28 septembre 2017 - 12:44
well

even if that's the case, you can still add a test inside your code to execute your action only when there is a difference big enough for your needs.

Best regards
Posté le 28 septembre 2017 - 12:53
Hi,

I confirmed that what you are seeing is normal and that my solution is the way to go. Here is the gist of it:

>> Notice that the delivery of a mouse message includes lots of work that is typically thought of as being part of mouse movement. Often, Windows wants to do that follow-on work even though the mouse hasn't actually moved. The most obvious example is when a window is shown, hidden or moved. When that happens, the mouse cursor may be over a window different from the window it was over previously (or in the case of a move, it may be over a different part of the same window). Windows needs to recalculate the mouse cursor (for example, the old window may have wanted an arrow but the new window wants a pointy finger), so it artificially sets the "The mouse moved, in case anybody cares" flag. This causes all the follow-on work to happen, a side-effect of which is the generation of a spurious WM_MOUSEMOVE message.

So if your program wants to detect whether the mouse has moved, you need to add a check in your WM_MOUSEMOVE that the mouse position is different from the position reported by the previous WM_MOUSEMOVE message. <<

and the source with all the gory details: https://blogs.msdn.microsoft.com/oldnewthing/20031001-00/…

Best regards
Posté le 28 septembre 2017 - 18:00
Hi

You may try this alternative to see if it fits as below:
//declare this as as Global boolean

gnMouseIsMoving is int = true // false = stops mouseMovement

//create visible controls EDT_X,_Y


//create a button btnStartMouseMove
//code in btnStartMouseMove

posXY is int
WHILE gnMouseIsMoving = true
Multitask(-1)
posXY = CursorPos(cpScreen)
EDT_X=LoWord(pos)
EDT_Y= HiWord(pos)
END


//create a stopMouseMove button with code
gnMouseIsMoving is boolean = false

HTH

King
Posté le 29 septembre 2017 - 19:19
I somehow got this working yesterday while I was 75% asleep. I will post my code once I go through it and figure out how it works! :xcool:
Posté le 03 octobre 2017 - 21:27
Here is the code I use. 350 is amount of pixels the mouse must move in either direction to start the timer.

// Global init code of window nLastMouseX, nLastMouseY is int nTimer is int nMouseTimer is int = 400 duMouseIdle is Duration nMouseEvent is int = Event(MouseMoved, MyWindow..Name + ".*", WM_MOUSEMOVE)
PROCEDURE MouseMoved() bRunTimer is boolean = False IF nLastMouseX = 0 _OR_ Abs(nLastMouseX - MouseXPos()) > 350 THEN nLastMouseX = MouseXPos() bRunTimer = True END IF nLastMouseY = 0 _OR_ Abs(nLastMouseY - MouseYPos()) > 350 THEN nLastMouseY = MouseYPos() bRunTimer = True END IF bRunTimer THEN IF nTimer > 0 THEN EndTimerSys(nTimer) duMouseIdle = 0 nTimer = TimerSys(MouseMovementTimer, 100, nMouseTimer) END
PROCEDURE MouseMovementTimer() duMouseIdle..Second++ Trace("Mouse moved " + duMouseIdle..Second + " seconds ago.") IF duMouseIdle..Second > 5 THEN duMouseIdle = 0 Trace("Mouse Timer Ending Itself") EndTimerSys(nTimer) END