Help! Mouse control outside of canvas..

BlitzPlus Forums/BlitzPlus Programming/Help! Mouse control outside of canvas..

Thanks BlitzSupport! Perfect! :D

I kind of think I've solved this using the B+ commands, but this userlib seems more
robust, so I'll use it. Though, is it safe to use this user32.dll hackery?

Below I've posted my solution (doesn't use user32.dll).. hope it's useful to someone.
If you make improvements, corrections etc. to the code, please email me.

;CANVAS X/Y by norki.

;The reason I made this is because when you use MouseX/Y(canvas) and the pointer
;leaves the canvas, you lose control of the player in a most horrible way, say if you
;move the mouse really fast to the right, the sprite's last X/Y position might be in the
;middle of the playfield, helpless, and you won't gain control until the pointer reenters
;the canvas. Therefore, I use MouseX/Y(desktop) and CanvasX/Y as an offset to where
;on the canvas to draw the player.

;Formula to find Canvas X and Y below..
;CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2
;CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2)

;I've tested this on WinXP and Win98SE using various border widths and resolutions.
;I don't know how it would fare against a desktop that uses skinning applications though..
;Let me know if it craps on you..
;Don't worry about seeing GadgetWidth() in the CanvasY calculation, it's only there
;because it's easier to use to find the border size, which is the same on all four sides.
;Of course, the titlebar height is added on the top side.

;NOTE: These calculations won't work if the window's got a status bar, if the window shape isn't
;set to be in client coordinates (32), and if the window is set to be a tool window.
;All other flags are working though.
;Also note that this example was made to work with a stretched canvas, but this can easily be changed.

Const winw=320		;Original game resolution width
Const winh=240		;Original game resolution height
Const str_winw=400	;Stretched width
Const str_winh=480	;Stretched height

Global window=CreateWindow("Canvas X/Y by norki",ClientWidth(Desktop())/2-winw,ClientHeight(Desktop())/2-winh/2,winw,winh,Desktop(),3+32)
Global canvas=CreateCanvas(0,0,winw,winh,window)
SetGadgetLayout canvas,1,1,1,1;Set canvas attributes to stretch
SetGadgetShape window,ClientWidth(Desktop())/2-str_winw/2,ClientHeight(Desktop())/2-str_winh/2,str_winw,str_winh;
ActivateGadget canvas
SetBuffer CanvasBuffer(canvas)

Type player1
	Field x#
	Field y#
End Type

player.player1=New player1
player\x#=winw/2
player\y#=winh/2

CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2
CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2)

MoveMouse winw/2,winh/2,canvas
;----------------------------------------------------------------------------------------------------
While Not KeyHit(1)
	Select WaitEvent(0)
	Case $803;Window close
		Exit
	Case $801;Window move, update CanvasX and CanvasY
		CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2
		CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2)
	Case $802;Window size, update CanvasX and CanvasY
		CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2
		CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2)
	End Select
	Cls
	Gosub updateplayer
	FlipCanvas canvas
Wend
;Clean up and end
For player.player1=Each player1:Delete player:Next
FreeGadget canvas:FreeGadget window
End
;----------------------------------------------------------------------------------------------------
.updateplayer
For player.player1=Each player1
	;Correct the stretched coordinates, and make it the player's coords
	player\x#=((MouseX(Desktop)-CanvasX)/(Float(GadgetWidth(canvas))/Float(winw)))
	player\y#=((MouseY(Desktop)-CanvasY)/(Float(GadgetHeight(canvas))/Float(winh)))
	If player\x#<0 player\x#=0;Bounds checking
	If player\x#>winw-1 player\x#=winw-1
	If player\y#<0 player\y#=0
	If player\y#>winh-1 player\y#=winh-1
	Color 255,0,255:Rect player\x#-3, player\y#-3,6,6
	Color 255,255,255:Text 1,40,"PlayerX/Y in "+winw+"x"+winh+" coords:"+Int(player\x#)+","+Int(player\y#)
	Text 1,20,"CanvasX/Y relative to screen:"+(GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2)+","+(GadgetY(window)+((GadgetHeight(window)-GadgetHeight(canvas))/2)+(((GadgetHeight(window)-GadgetHeight(canvas))/2)/2)+(GadgetWidth(window)-GadgetWidth(canvas))/2)
	Text 1,30,"MouseX/Y relative to canvas:"+(MouseX(Desktop)-CanvasX)+","+(MouseY(Desktop)-CanvasY)
Next
Return