Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
11-25-2022, 07:32 PM
(This post was last modified: 11-25-2022, 07:33 PM by Pete.)
Here are some interesting observations about _MOUSEHIDE and _MOUSESHOW
See the remark statements at the top of the code.
Code: (Select All) ' _MOUSEHIDE _MOUSE SHOW DEMO
' Note: _MOUSEHIDE WILL BE DISENGAGED WHEN A MOUSE BUTTON IS HELD DOWN.
' A MOUSE TRIGGER EVENT LIKE _MOUSEMOVE IS NEEDED TO HIDE/SHOW MOUSE WHEN MOUSE IS IDLE.
REM PRESS ESC TO END. <==================================================
WHILE _MOUSEINPUT: WEND
DO UNTIL my
my = _MOUSEY
mx = _MOUSEX
LOOP
PALETTE 8, 0
DO
_LIMIT 30
COLOR 1, 0
_MOUSESHOW
WHILE _MOUSEINPUT: WEND: my = _MOUSEY: mx = _MOUSEX
_MOUSEMOVE mx, my
PALETTE 0, 63
FOR i = 1 TO 10
_DELAY .2
PRINT i
IF INKEY$ = CHR$(27) THEN EXIT DO
NEXT
COLOR 8, 0
myhide = my: mxhide = mx
_MOUSEHIDE
PRINT "_MOUSEMOVEX ="; mxhide, "_MOUSEMOVEY ="; myhide
WHILE _MOUSEINPUT: WEND: myhide = _MOUSEY: mxhide = _MOUSEX
_MOUSEMOVE mxhide, myhide
PALETTE 0, 4
FOR i = 10 TO 1 STEP -1
_DELAY .2
PRINT i
IF INKEY$ = CHR$(27) THEN EXIT DO
NEXT
oldmy = my: oldmy = mx
LOOP
So curious that if you continuously move the mouse with no button held, the pointer hides on the red screen and shows on the white, as expected, but... if you initiate and hold any mouse button down WHILE ON THE WHITE SCREEN, it shows up all the time, even on the red screen. Personally, I wish it would continue to show and hide regardless of mouse button status, but unless this is a "glitch" I wonder what was the thought process to have it coded this way?
Pete
Posts: 1,510
Threads: 53
Joined: Jul 2022
Reputation:
47
Those statements seem to have been provided "just in case", and otherwise shouldn't be needed. I don't remember well but programming MS-DOS and early Windows applications required the mouse cursor drawn, or it came from a driver, which made it a necessity to "hide" the cursor temporarily, draw all or part of the screen and then "show" the cursor again. It's because a driver cannot know what another program is doing with the screen. Also if the mouse cursor has to be drawn like a simple circle or rectangle in somebody's newb program, it definitely has to be managed "manually". These days, however, it's managed gracefully by the operating system. There's almost no worry of the cursor leaving trails somewhere...
Sometimes this combination could be dangerous. I had some programs disappearing the mouse cursor and unable to get it back which forced me to quit on it, or even log out the user session. Thankfully on Linux the mouse cursor seems to be managed by the desktop environment such as KDE Plasma. It should be alike on Macintosh or Windows.
Posts: 18
Threads: 3
Joined: Apr 2022
Reputation:
1
Hi
This only happens when the red screen lights up while you have already pressed a mouse button and not when you press a button while the red color is displayed.
Gaslouk
Posts: 1,507
Threads: 160
Joined: Apr 2022
Reputation:
116
Not a "glitch". This is actual OS intended behavior.
Imagine this scenario -- you have a visible mouse cursor. You're holding it down and drawing a pretty little line towards the latest country that annoyed you and you want to nuke...
...suddenly...POOF!! Your mouse pointer is gone!!...
...OH NO!! You just nuked your girlfriend's house by accident!! AHHHHHHHHHHHH!!!
The OS can't know how important what you're doing is, nor what your threshold level is for things disrupting your work flow... If you're interacting with the mouse, via a button down or other such "major event", the OS isn't going to touch those mouse settings with a ten-foot pole!
Think of it much like trying to delete a file and getting the message, "You can't do that Pete. That file's open in another program!" New processes generally don't engage with resources or their settings if they're in use by another process. (Unless you've jumped through hoops and specifically marked them as multi-process enabled, which I don't even know if that's possible with the mouse.)
Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
That's what I've been finding from doing some experimenting and research. What I still haven't figured out is how Windows sticks that damn mouse pointer to one spot, regardless of how fast you move the window.
I put this little demo together with a loop event to exaggerate how the mouse cursor races the window.
Start the drag and then swirl the mouse around in a big circle and watch the window chase the mouse...
Code: (Select All) DIM WinMse AS POINTAPI
TYPE POINTAPI
X_Pos AS LONG
Y_Pos AS LONG
END TYPE
DECLARE DYNAMIC LIBRARY "User32"
FUNCTION GetWindowLongA& (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG)
FUNCTION SetWindowLongA& (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG, BYVAL dwNewLong AS LONG)
FUNCTION SetWindowPos& (BYVAL hwnd AS LONG, BYVAL hWndInsertAfter AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL cx AS LONG, BYVAL cy AS LONG, BYVAL wFlags AS LONG)
FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
FUNCTION GetCursorPos (lpPoint AS POINTAPI)
FUNCTION SetCursorPos& (BYVAL x AS INTEGER, BYVAL y AS INTEGER)
END DECLARE
DIM AS INTEGER setxy
WIDTH 50, 25
DO: LOOP UNTIL _SCREENEXISTS
GWL_STYLE = -16
ws_border = &H800000
WS_VISIBLE = &H10000000
_TITLE "No Border"
hwnd& = _WINDOWHANDLE
winstyle& = GetWindowLongA&(hwnd&, GWL_STYLE)
_DELAY .25
a& = SetWindowLongA&(hwnd&, GWL_STYLE, winstyle& AND WS_VISIBLE)
a& = SetWindowPos&(hwnd&, 0, 0, 200, 400, 0, 39)
LOCATE 1, 1
COLOR 0, 7
PRINT SPACE$(_WIDTH);
fw = _FONTWIDTH
fh = _FONTHEIGHT
x = _SCREENX: y = _SCREENY
DO
_LIMIT 60
IF GetAsyncKeyState(1) < 0 THEN
IF lb = 0 THEN lb = 1
ELSE
IF lb THEN lb = 0: dragx = 0: dragy = 0
END IF
z = GetCursorPos(WinMse)
IF lb THEN
IF dragx THEN
IF WinMse.X_Pos <> oldxpos OR WinMse.Y_Pos <> oldypos THEN
j1 = (WinMse.X_Pos - oldxpos)
j2 = (WinMse.Y_Pos - oldypos)
x = x + j1: y = y + j2
_SCREENMOVE x, y
z1 = TIMER
DO
setxy = SetCursorPos(x + dragx, y + dragy)
LOOP UNTIL ABS(TIMER - z1) > .001
END IF
z = GetCursorPos(WinMse)
ELSE
IF WinMse.Y_Pos >= _SCREENY AND WinMse.Y_Pos <= _SCREENY + fh THEN
x = _SCREENX: y = _SCREENY
dragx = (WinMse.X_Pos - x)
dragy = fw \ 2 ' Set to middle of the title bar vertical height.
END IF
END IF
END IF
IF LEN(INKEY$) THEN SYSTEM
oldypos = WinMse.Y_Pos
oldxpos = WinMse.X_Pos
LOOP
So what I was aiming to do before was hide the mouse during any off the drag point phase, but that is not possible since a button held negates the _MOUSEHIDE command. So still looking for the method that keeps the two married. I even tried the Win32 API MoveWindow approach, but it works the same as _SCREENMOVE. Obviously the mouse pointer has to move off the fixed point a bit to get the new position, but try a drag on a small resized QB64 IDE window and see how much better the pointer stays fixed to the drag point even during very rapid movement.
Oh well, in California, life's a beach. Good surf today, sunny and 75.
Pete
Posts: 1,507
Threads: 160
Joined: Apr 2022
Reputation:
116
Try this. How's it perform on your machine?
Code: (Select All) Screen _NewImage(800, 600, 32)
$Color:32
Declare Dynamic Library "User32"
Function GetWindowLongA& (ByVal hwnd As Long, Byval nIndex As Long)
Function SetWindowLongA& (ByVal hwnd As Long, Byval nIndex As Long, Byval dwNewLong As Long)
Function SetWindowPos& (ByVal hwnd As Long, Byval hWndInsertAfter As Long, Byval x As Long, Byval y As Long, Byval cx As Long, Byval cy As Long, Byval wFlags As Long)
End Declare
Do: Loop Until _ScreenExists
GWL_STYLE = -16
ws_border = &H800000
WS_VISIBLE = &H10000000
hwnd& = _WindowHandle
winstyle& = GetWindowLongA&(hwnd&, GWL_STYLE)
a& = SetWindowLongA&(hwnd&, GWL_STYLE, winstyle& And WS_VISIBLE)
a& = SetWindowPos&(hwnd&, 0, 0, 200, 400, 0, 39)
Line (0, 0)-(_Width, 30), SkyBlue, BF 'My custom titlebar
pw = _PrintWidth("ð Steve's Tripple Line Title ð")
_PrintString ((_Width - pw) \ 2, 2), "ð Steve's Tripple Line Tittle ð"
Do
x = _ScreenX: y = _ScreenY
result = MBS
If (result And 64) And (_MouseY <= 30) Then startdrag = -1 ' we're in the title bar and triggered a hold event.
If startdrag Then
_ScreenMove x + MMX, y + MMY ' drag the window from the title bar
_MouseMove Mouse_StartX, Mouse_StartY ' keep the mouse in its original position
End If
If (result And 1) = 0 Then startdrag = 0 ' hold event is over, quit dragging
_Limit 60
Loop Until _KeyDown(27)
Function MBS% 'Mouse Button Status
Static StartTimer As _Float
Static ButtonDown As Integer
Static ClickCount As Integer
Const ClickLimit## = 0.2 'Less than 1/4th of a second to down, up a key to count as a CLICK.
' Down longer counts as a HOLD event.
Shared Mouse_StartX, Mouse_StartY, Mouse_EndX, Mouse_EndY, MMX, MMY
MMX = 0: MMY = 0
While _MouseInput 'Remark out this block, if mouse main input/clear is going to be handled manually in main program.
Select Case Sgn(_MouseWheel)
Case 1: tempMBS = tempMBS Or 512
Case -1: tempMBS = tempMBS Or 1024
End Select
MMX = MMX + _MouseMovementX
MMY = MMY + _MouseMovementY
Wend
If _MouseButton(1) Then tempMBS = tempMBS Or 1
If _MouseButton(2) Then tempMBS = tempMBS Or 2
If _MouseButton(3) Then tempMBS = tempMBS Or 4
If StartTimer = 0 Then
If _MouseButton(1) Then 'If a button is pressed, start the timer to see what it does (click or hold)
ButtonDown = 1: StartTimer = Timer(0.01)
Mouse_StartX = _MouseX: Mouse_StartY = _MouseY
ElseIf _MouseButton(2) Then
ButtonDown = 2: StartTimer = Timer(0.01)
Mouse_StartX = _MouseX: Mouse_StartY = _MouseY
ElseIf _MouseButton(3) Then
ButtonDown = 3: StartTimer = Timer(0.01)
Mouse_StartX = _MouseX: Mouse_StartY = _MouseY
End If
Else
BD = ButtonDown Mod 3
If BD = 0 Then BD = 3
If Timer(0.01) - StartTimer <= ClickLimit Then 'Button was down, then up, within time limit. It's a click
If _MouseButton(BD) = 0 Then tempMBS = 4 * 2 ^ ButtonDown: ButtonDown = 0: StartTimer = 0
Else
If _MouseButton(BD) = 0 Then 'hold event has now ended
tempMBS = 0: ButtonDown = 0: StartTimer = 0
Mouse_EndX = _MouseX: Mouse_EndY = _MouseY
Else 'We've now started the hold event
tempMBS = tempMBS Or 32 * 2 ^ ButtonDown
End If
End If
End If
MBS = tempMBS
End Function
That seems to pretty well stick the mouse to my window, wherever I start dragging it from.
Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
In a word, nope. Same results I get when I run mine. Move the mouse quickly and it separates approximately 30 - 40 pixels from the drag point and back. Do exactly the same thing with a Windows app, and it sticks like glue. So if you can't see this much difference on your machine, it's probably a difference in whatever components control speed issues, the processor, video card, whatever.
About the only thing I haven't tried replacing to an API method are the _SCREENX and _SCREENY statements, but I really have my doubts that they are slower than whatever API function is used for reporting upper left window coordinates.
BTW - The routine I made for reporting the desktop coordinates is...
Code: (Select All) DIM Rec AS Rectangle
DIM hWnd AS LONG
TYPE Rectangle
left AS LONG
top AS LONG
right AS LONG
bottom AS LONG
END TYPE
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION GetWindowRect& (BYVAL Hwnd AS LONG, Rec AS Rectangle)
END DECLARE
hWnd = _WINDOWHANDLE
fwp$ = "Find Windows Position"
_TITLE fwp$
_DELAY .25
' What's interesting is Windows will not report the change in location until the window stops moving. Same if using _SCREENX _SCREENY.
DO
_LIMIT 10
SOUND 1000, .1 ' Shows the loop run continuously while being dragged.
y& = GetWindowRect&(hWnd, Rec)
LOCATE 1, 1
PRINT "top ="; Rec.top; " ";
PRINT "right ="; Rec.right; " ";
PRINT "left ="; Rec.left; " ";
PRINT "Bottom ="; Rec.bottom; " ";
LOOP UNTIL LEN(INKEY$)
I found it interesting it only reports after you stop dragging your Win around, not during. So Stevie Nicks aside for a moment, I wonder why that is? The same thing happens if you stick _SCREENX and SCREENY in that loop. Maybe it was designed that way by Windows to ignore the changing positions while dragging to increase speed. Certainly not good for collision detection. Help! My IDE window crashed into my browser window and there's BOLD everywhere!
Now if you will excuse me, I have to get back to that other Stevie... Kidding aside, and true story, I saw Fleetwood Mac the first time when I was 18. Stevie would change tops on stage, in a somewhat secluded area. Of course I was glad I invested in those premium high powered binoculars, so... Anyway, in later years I told my wife that story and she replied, "When Stevie Nicks sings she bleats like a sheep!" I agreed, and told her that was half the fantasy. Well, we didn't discuss the matter much after that comment, and frankly, I was also glad I invested in that premium pullout living room sofa.
Pete
Posts: 1,510
Threads: 53
Joined: Jul 2022
Reputation:
47
(11-26-2022, 04:55 PM)Pete Wrote: Now if you will excuse me, I have to get back to that other Stevie... Kidding aside, and true story, I saw Fleetwood Mac the first time when I was 18. Stevie would change tops on stage, in a somewhat secluded area. Of course I was glad I invested in those premium high powered binoculars, so... Anyway, in later years I told my wife that story and she replied, "When Stevie Nicks sings she bleats like a sheep!" I agreed, and told her that was half the fantasy. Well, we didn't discuss the matter much after that comment, and frankly, I was also glad I invested in that premium pullout living room sofa.
Pete There's a song by her that I swear she roars like a lioness and I think it's fantastic -- STAND BACK!
Otherwise likes electronic music from the mid-1990's...
|