GLBasic forum

Main forum => GLBasic - en => Topic started by: kamakazieturtle on 2011-Jan-01

Title: Controling System Mouse?
Post by: kamakazieturtle on 2011-Jan-01
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.
Title: Re: Controling System Mouse?
Post by: Moru on 2011-Jan-01
Is SETMOUSE what you are looking for mabe?
Title: Re: Controling System Mouse?
Post by: kamakazieturtle on 2011-Jan-02
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?
Title: Re: Controling System Mouse?
Post by: Moebius on 2011-Jan-02
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 (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!
Title: Re: Controling System Mouse?
Post by: kamakazieturtle on 2011-Jan-02
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
Title: Re: Controling System Mouse?
Post by: Moebius on 2011-Jan-03
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!
Title: Re: Controling System Mouse?
Post by: kamakazieturtle on 2011-Jan-03
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?
Title: Re: Controling System Mouse?
Post by: Slydog on 2011-Jan-03
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.
Title: Re: Controling System Mouse?
Post by: Moru on 2011-Jan-04
That sounds like a lot of work to avoid using a sprite to display the mouse limited to an area :-)
Title: Re: Controling System Mouse?
Post by: Moebius on 2011-Jan-04
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)
Title: Re: Controling System Mouse?
Post by: kamakazieturtle on 2011-Jan-04
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.
Title: Re: Controling System Mouse?
Post by: Slydog on 2011-Jan-04
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/ (http://www.bigresource.com/Tracker/Track-vb-VcdeGGTXB7/)
Title: Re: Controling System Mouse?
Post by: Moebius on 2011-Jan-05
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