Controling System Mouse?

Previous topic - Next topic

kamakazieturtle

I know if I disable system mouse I can set the mouse for whatever I want. But is it possible to set coordinates for the system mouse? For example I don't want to let the mouse go beyond a certain point while the left button is pressed, but still want to use the system mouse.

Moru

Is SETMOUSE what you are looking for mabe?

kamakazieturtle

As I figured, it only works if you are providing the mouse image. I want to have SYSTEMPOINTER TRUE and be able to do this. Any ideas?

Moebius

#3
You should be able to use API calls in Windows.  Take a look at SetCursorPos.
Here is it's msdn page: http://msdn.microsoft.com/en-us/library/ms648394(v=vs.85).aspx

EDIT:
Try this...
Code (glbasic) Select
//Put at beginning...
INLINE
DECLARE(SetCursorPos, "user32.dll", (int, int), int);
ENDINLINE

//Put anywhere...
FUNCTION SetCursorPos: x%, y%
INLINE
if(SetCursorPos) return SetCursorPos(x, y);
ENDINLINE
ENDFUNCTION

It's so easy to do cruel stuff with these commands.  In a networked chat program I wrote, I put in a command to 'disable' another user's cursor using this command  :whistle:   Anyway good luck!
Endless Loop: n., see Loop, Endless.
Loop, Endless: n., see Endless Loop.
- Random Shack Data Processing Dictionary

kamakazieturtle

It kinda works. At first I had trouble realizing you can't call an API function from another function, but as far as I know this code is clean but the mouse just gets stuck at 100,100?

Code (glbasic) Select

SETSCREEN 640,480,0
LIMITFPS 60
SYSTEMPOINTER TRUE

TYPE CursorType
Image
X
Y
LeftClick
RightClick
SetPosSwitch
ENDTYPE

GLOBAL Cursor AS CursorType
Cursor.Image=1
MOUSESTATE Cursor.X,Cursor.Y,Cursor.LeftClick,Cursor.RightClick
Cursor.SetPosSwitch=0

INLINE
   DECLARE(SetCursorPos,"user32.dll",(int,int),int);
ENDINLINE

Main:
CLEARSCREEN

CursorUpdate()

IF Cursor.SetPosSwitch=1
SetCursorPos(Cursor.X,Cursor.Y)
Cursor.SetPosSwitch=0
ENDIF

PRINT "Cursor.X:"+Cursor.X+" Cursor.Y:"+Cursor.Y,0,0

SHOWSCREEN
GOTO Main

FUNCTION CursorUpdate:
MOUSESTATE Cursor.X,Cursor.Y,Cursor.LeftClick,Cursor.RightClick
IF Cursor.X<100
Cursor.X=100
Cursor.SetPosSwitch=1
ENDIF
IF Cursor.X>300
Cursor.X=300
Cursor.SetPosSwitch=1
ENDIF
IF Cursor.Y<100
Cursor.Y=100
Cursor.SetPosSwitch=1
ENDIF
IF Cursor.Y>300
Cursor.Y=300
Cursor.SetPosSwitch=1
ENDIF
ENDFUNCTION

FUNCTION SetCursorPos:X%,Y%
   INLINE
      if(SetCursorPos) return SetCursorPos(X,Y);
   ENDINLINE
ENDFUNCTION

Moebius

The problem here is that the mouse gets set to an ABSOLUTE position, not relative to the GLBASIC window.  MOUSESTATE is relative to the window, so your code keeps reading the mouse to be at a relative "0,0" then setting it to an absolute "100,100" in CursorUpdate.
Also BTW SETMOUSE seems to do the same thing as the API call...

Anyway there might be a command to set the mouse position relative to the window, but I haven't found one yet, so I'd make use of one of these:
GetWindowRect()
ClientToScreen()

I've tried wrapping them, but failed because they involve structures... Anyway good luck!
Endless Loop: n., see Loop, Endless.
Loop, Endless: n., see Endless Loop.
- Random Shack Data Processing Dictionary

kamakazieturtle

Oh yeah, I realized that after about an hour of that last post.  :S All I think I need now is how to find out the resolution the monitor is running at, using the math of the difference between the monitor's res and the screen's res, then add that to the position of SetCursor. So in other words, anyone know how to pull the current monitors resolution, just out of curiosity maybe how pull all other possible resolutions?

Slydog

Here's some Visual Basic code that does that:
Code (glbasic) Select

Private Declare Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long

Private Const SM_CXSCREEN As Long = 0
Private Const SM_CYSCREEN As Long = 1
Public Sub ShowScreenDimensions()
   Dim X As Long
   Dim Y As Long

   X = GetSystemMetrics(SM_CXSCREEN)
   Y = GetSystemMetrics(SM_CYSCREEN)

   Call MsgBox("Screen resolution is " & X & "x" & Y)
End Sub


Basically, pass '0' for the width, and '1' for the height, to the 'GetSystemMetrics()' api.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Moru

That sounds like a lot of work to avoid using a sprite to display the mouse limited to an area :-)

Moebius

GetSystemMetrics() is a useful function, but it should be better to get window coords rather than screen length...  If the user moves your window, the cursor won't be in the middle any more if you used screen dimensions   :|

"That sounds like a lot of work to avoid using a sprite to display the mouse limited to an area :-)"x2  8)
Endless Loop: n., see Loop, Endless.
Loop, Endless: n., see Endless Loop.
- Random Shack Data Processing Dictionary

kamakazieturtle

It seems this has gone to indepth for my level as of now anyway, thanks for all the help anyway. I always just get to curious as to how things work.

Slydog

I didn't even notice the GLBasic command 'GETDESKTOPSIZE()' that gets the current screen's resolution, so that's one less API call.

But, in case you're still curious, to get a window's position (and size), use the 'GetWindowRect()' API function.
You just need to pass it the window's handle, which you can find by using the 'FindWindow()' API function.

Here's a Visual Basic example I found:
http://www.bigresource.com/Tracker/Track-vb-VcdeGGTXB7/
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Moebius

#12
EDIT:  Code replaced with function compatible version, with thanks to Gernot for the code and comments  :good:
Code (glbasic) Select
// OK, we need a structure holding 2 32bit ints:
TYPE DECL_POINT
x%
y%
ENDTYPE
// now, get the windows API functions as if they were real GLBasic functions
// -> we still need inline when we deal with pointers!
// That only works for C-Runtime and Windows API function (stuff I link against)
IMPORT "C" int __stdcall SetCursorPos(int x, int y)
IMPORT "C" int __stdcall ClientToScreen(void*, void*)


FUNCTION MoveMouseMiddle:
LOCAL scx%, scy%
GETSCREENSIZE scx%, scy%

// Convert local (screen) point to desktop point
LOCAL mypt AS DECL_POINT
mypt.x=scx%/2
mypt.y=scy%/2

INLINE
ClientToScreen(GLBASIC_HWND(), &mypt);
ENDINLINE
// put the cursor there
SetCursorPos(mypt.x, mypt.y)
ENDFUNCTION
Endless Loop: n., see Loop, Endless.
Loop, Endless: n., see Endless Loop.
- Random Shack Data Processing Dictionary