Point in client rect

Just starting out? Need help? Post your questions and find answers here.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Point in client rect

Post 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().
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post by r_hyde »

Have you tried GetClientRect_()?
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

GetClientRect_() returns the local position of the client rectangle within the window and not its screen position.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Why without GetWindowRect_()?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post 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.
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post 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
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post 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
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Or use MapWindowPoints_() etc.
I may look like a mule, but I'm not a complete ass.
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post 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 :)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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. :)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Post Reply