Page 1 of 1
Point in client rect
Posted: Sat Mar 01, 2008 11:53 pm
by Mistrel
I would like to know if the mouse is inside of the client area of the window. is this possible to do without using GetWindowRect_() and then adding the border and titlebar width based on the system metrics?
The window I'm doing this to is not a PB window so I cannot use WindowMouseX() and WindowMouseY().
Posted: Sun Mar 02, 2008 1:10 am
by r_hyde
Have you tried GetClientRect_()?
Posted: Sun Mar 02, 2008 1:29 am
by Mistrel
GetClientRect_() returns the local position of the client rectangle within the window and not its screen position.
Posted: Sun Mar 02, 2008 1:29 am
by Fluid Byte
Why without GetWindowRect_()?
Posted: Sun Mar 02, 2008 2:38 am
by Mistrel
"..without using GetWindowRect_() and then adding the border and titlebar width based on the system metrics"
Is there a way to do this without going through the trouble of looking up the system metrics and adding them to the value returned by the GetWindowRect_() RECT structure.
Posted: Sun Mar 02, 2008 3:59 am
by r_hyde
Here's an example of what I was thinking of with GetClientRect_():
Code: Select all
OpenWindow(0, #PB_Ignore, #PB_Ignore, 300, 300, "")
in.b = #False
Repeat
ev = WaitWindowEvent(10)
GetCursorPos_(@pt.POINT)
ScreenToClient_(WindowID(0), @pt)
GetClientRect_(WindowID(0), @rc.RECT)
If PtInRect_(@rc, pt\x, pt\y)
If Not in : Debug "Entered client area" : EndIf
in = #True
Else
If in : Debug "Left client area" : EndIf
in = #False
EndIf
Until ev = #PB_Event_CloseWindow
Posted: Sun Mar 02, 2008 5:22 am
by Mistrel
I didn't know about ScreenToClient_(). Your example makes perfect sense, thank you.
This is the function I wanted to make with this:
Code: Select all
Procedure PointInClientRect(hWnd, x, y)
Define Point.POINT
Point\x=x
Point\y=y
ScreenToClient_(hWnd, @Point)
GetClientRect_(hWnd, @rc.RECT)
If PtInRect_(@rc, Point\x, Point\y)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Posted: Sun Mar 02, 2008 11:41 am
by srod
Or use MapWindowPoints_() etc.
Posted: Sun Mar 02, 2008 10:02 pm
by r_hyde
srod, that's a bit complicated for something like finding out if a single point is inside a window's client area, dontcha think? I've never actually used MapWindowPoints_(), so I could be wrong - in which case I'd be happy to see some code

Posted: Sun Mar 02, 2008 10:12 pm
by srod
Code: Select all
Procedure PointInClientRect(hWnd, x, y)
Define Point.POINT
Point\x=x
Point\y=y
MapWindowPoints_(0, hWnd, Point, 1)
GetClientRect_(hWnd, @rc.RECT)
If PtInRect_(@rc, Point\x, Point\y)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Absolutely identical to the code using ScreenToClient_() etc. I was just pointing out the MapWindowPoints_() function as it is quite a versatile and useful little thing. I wasn't saying that it would lead to the best solution for the problem under discussion.

Posted: Sun Mar 02, 2008 10:19 pm
by netmaestro
Code: Select all
OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ButtonGadget(0,100,70,100,30,"Button")
TextGadget(1, 100,130,200,20,"Not in Window")
TextGadget(2, 100,160,200,20,"Not in Button")
Repeat
ev=WaitWindowEvent(1)
Select ev
Case #WM_MOUSEMOVE
;Button
GetCursorPos_(@cp.point)
GetWindowRect_(GadgetID(0),@br.rect)
If PtInRect_(br, cp\x, cp\y)
MapWindowPoints_(#Null, GadgetID(0),cp,1)
SetGadgetText(2, "In Button: "+Str(cp\x)+", "+Str(cp\y))
Else
SetGadgetText(2, "Not in Button")
EndIf
;Window
GetCursorPos_(@cp.point)
GetWindowRect_(WindowID(0),@br.rect)
If PtInRect_(br, cp\x, cp\y)
MapWindowPoints_(#Null, WindowID(0),cp,1)
SetGadgetText(1, "In Window: "+Str(cp\x)+", "+Str(cp\y))
EndIf
EndSelect
If WindowMouseX(0) = -1 Or WindowMouseY(0)=-1
If GetGadgetText(1)<>"Not in Window"
SetGadgetText(1, "Not in Window")
EndIf
EndIf
Until ev=#PB_Event_CloseWindow
Note that MapWindowPoints_() does work with the client area of the mapped window, therefore no need to calculate frame heights/widths, etc.