Mouse problem and resolution switching problem

Blitz3D Forums/Blitz3D Programming/Mouse problem and resolution switching problem

Dr Derek Doctors(Posted 2003) [#1]
Okay, couple of B3D questions. When I'm running an application in a window and I move the mouse cursor outside of the window really fast it just supplies the last pair of co-ordinates. Is there any way to detect that the mouse is now outside the window at all? Get it's real co-ordinates in effect? Or just find out that it's outside the window?

Also when switching from full-screen to windowed the application stays on top of all other windows regardless if I try swapping to another window. If you start it in windowed mode then you can switch between windows without problem which is nice. Any way to stop this problem?


_PJ_(Posted 2003) [#2]
Blitz itself cannot help with this, as it only deals with it's own window.
As for checking to see if coords are outside or not, just use this:

MOUSE_OUTSIDE=false
If mouseX()>=GraphicsWidth() or mouseX()<=0 then MOUSE_OUTSIDE=true

If mouseY()>=GraphicsHeight() or mouseY()<=0 then MOUSE_OUTSIDE=true



...Or similar. This will react if the mouse travels outside the window, but also at the very very edge (but one pixel shouldn't make too much of a difference I hope)





I reckon API calls etc. may be able to do all you require quite simply- but - that sort of stuff's way beyond me.


GfK(Posted 2003) [#3]
That code won't work - well it will, but only if you move the mouse out of the window VERY slowly.

MouseX() and MouseY() both stop working once the pointer is beyond the window boundary.

It isn't possible to solve either of these problems 'natively'. I'm sure someone with DLL expertise will be along shortly...


_PJ_(Posted 2003) [#4]
Ah sorry, I understand what you mean now. If you move the mouse so fast the pointer goes from the middle of the window to outside before MouseX() and MouseY() are updated.

Hmm I don't know if any GetSystemMetrics stuff might help... sorry best I can do.


Dr Derek Doctors(Posted 2003) [#5]
Fair enuff, I'll guess I'll have to wait for a DLL then.


John Pickford(Posted 2003) [#6]
You don't have to move the mouse fast at all for that code to fail.

mousex() , mousey() NEVER return coords outside of the window, so the test is useless.

I haven't found a way around this.


Dr Derek Doctors(Posted 2003) [#7]
Well, you could've told Carleton that before he nagged me to post this bloody topic. ;)


BlitzSupport(Posted 2003) [#8]
Userlibs! This works here...

; -----------------------------------------------------------------------------
; IMPORTANT: Add these to user32.decls in your Userlibs folder:
; -----------------------------------------------------------------------------
; .lib "user32.dll"
; -----------------------------------------------------------------------------
; GetCursorPos% (point*): GetCursorPos
; ScreenToClient% (window, point*): ScreenToClient
; GetActiveWindow% (): GetActiveWindow
; SetWindowPos% (window, order, x, y, width, height, flags): SetWindowPos
; -----------------------------------------------------------------------------

; -----------------------------------------------------------------------------
; Required constants for UnstickWindow ()
; -----------------------------------------------------------------------------

Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = 1
Const SWP_NOMOVE = 2

; -----------------------------------------------------------------------------
; Required structure for MouseInWindow ()
; -----------------------------------------------------------------------------

Type MousePoint
	Field x
	Field y
End Type

; -----------------------------------------------------------------------------
; Functions
; -----------------------------------------------------------------------------

Function MouseInWindow (mp.MousePoint)
	GetCursorPos (mp)
	ScreenToClient (GetActiveWindow (), mp)
	If (mp\x < 0) Or (mp\x > GraphicsWidth ()) Or (mp\y < 0) Or (mp\y > GraphicsHeight ())
		Return 0
	EndIf
	Return 1
End Function

Function UnstickWindow ()
	SetWindowPos (GetActiveWindow (), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE)
End Function

; -----------------------------------------------------------------------------
; Demo...
; -----------------------------------------------------------------------------

AppTitle "Move mouse outside window..."
Graphics3D 640, 480

; -----------------------------------------------------------------------------
; Important! Create a 'MousePoint' and pass to MouseInWindow () below...
; -----------------------------------------------------------------------------

mp.MousePoint = New MousePoint

Repeat

	Cls

	; SPACE = switch between full screen and windowed...
	
	If KeyHit (57)

		; Mode switch variable...
		
		mode = 1 - mode
		
		; Close graphics mode...
		
		EndGraphics

		; If going into windowed mode, unstick window!
		
		If mode = 1
			Graphics3D 640, 480, 0, 2
			UnstickWindow ()
		Else
			Graphics3D 640, 480
		EndIf

	EndIf
	
	Text 20, 20, "Hit SPACE to switch modes..."

	; Check in mouse is within window...
		
	If MouseInWindow (mp) = False
		Text 20, 40, "Outside window!"
	EndIf
	
	Flip
	
Until KeyHit (1)

End



DJWoodgate(Posted 2003) [#9]
That looks darn useful. Works fine here (Win98SE). I suppose it would be relatively simple to make it check if its in the blitz window, in which case it would handle task switching as well. In fact is it fair to say the blitz window will always be the active one after a mode change? I wonder if its also possible to retain the relative mouse position?


Red Ocktober(Posted 2003) [#10]
Sorry I didn't see this topic until now... If I had've read it sooner, I would've offered some half-baked suggestion, that may or may not have worked...

... but whatever it was that I had come up with, it would've pointed you to the Win32 api.

Whenever I can't do something in VB, I always run to ye ole VB5 Programmer's Guide To The Win32 API (Appleman) for help.

Windows is really nothing more than a collection of dlls (for the most part), and if you can access the exported functions (use userlibs in Blitz like you would Declare in VB) in any of the dlls that make up Windows, you can usually find something that will satisfy your needs.

Userlibs is cool...

--Mike


BlitzSupport(Posted 2003) [#11]
David, GetActiveWindow () returns the active window for the current thread (ie. the one getting the input for the Blitz program), rather than the active desktop window, so it *should* always return the Blitz window regardless of whether it's the active desktop window... as I understand it ;)


Dr Derek Doctors(Posted 2003) [#12]
Ta' muchly, James. The chap in the office who was having the problem says that your solution worked a peachy treat.


DJWoodgate(Posted 2003) [#13]
James, not in Win98SE it seems. You have to love these little inconsistencies across OS versions. However as mentioned I think there are ways around it.


Red Ocktober(Posted 2003) [#14]
maybe FindWindow might do it...

Applemans book is a great resource i you're gonna be messing with the WIn32 api a lot...

--Mike