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. :D

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.