Page 1 of 1

Detecting mouse over button

Posted: Mon Nov 06, 2006 7:15 am
by The Mexican
I have a window with a button and a text gadget. I want the text gadget to change from "test" to "Mouse over button" when the mouse cursor is over the button. I am trying to understand the winapi but I am confused.

Code: Select all

Structure wndMain
  window.l
  btnClose.l
  btnViewParents.l
  txtMessage.l
EndStructure

MainWindow.wndMain
;assign Id's
MainWindow\window=0
MainWindow\btnClose=1
MainWindow\btnViewParents=2
MainWindow\txtMessage=3

;Create window

OpenWindow(mainWindow\window,0,0,500,200,"TEST",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(mainWindow\window))
ButtonGadget(MainWindow\btnClose,400,150,40,30,"CLOSE")
TextGadget(MainWindow\txtMessage,10,10,200,30,"TEST")


Repeat
  event.l=WaitWindowEvent(10)   ;catch all events from any window
  
  If event=#PB_Event_Gadget     ;If event is from a gadget
      
      Select EventGadget()      ; get the gadget number
        Case MainWindow\btnClose
          
          [b]If #BCN_HOTITEMCHANGE [/b] ;I am confused here
            SetGadgetText(MainWindow\txtMessage,""Mouse over button"")
          EndIf
         
      EndSelect
      
  EndIf
Until event=#PB_Event_CloseWindow And EventWindow()=MainWindow\window
Any help will be appreciated. I have been using PB 4.0 for over 2 weeks now. I mostly interested in using database applications with nice gui's.

thanks.

Posted: Mon Nov 06, 2006 1:46 pm
by netmaestro
I'll show you three different ways you can do it:

Method 1: ChildWindowFromPoint

Code: Select all

Structure wndMain 
  window.l 
  btnClose.l 
  btnViewParents.l 
  txtMessage.l 
EndStructure 

MainWindow.wndMain 
;assign Id's 
MainWindow\window=0 
MainWindow\btnClose=1 
MainWindow\btnViewParents=2 
MainWindow\txtMessage=3 

;Create window 

OpenWindow(mainWindow\window,0,0,500,200,"TEST",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(mainWindow\window)) 
ButtonGadget(MainWindow\btnClose,400,150,40,30,"CLOSE") 
TextGadget(MainWindow\txtMessage,10,10,200,30,"TEST") 


Repeat 
  event.l=WaitWindowEvent(10)   ;catch all events from any window 
  
  If event = #WM_MOUSEMOVE
    If ChildWindowFromPoint_(WindowID(Mainwindow\window), WindowMouseX(Mainwindow\window), WindowMouseY(Mainwindow\window)) = GadgetID(Mainwindow\btnclose)
      SetGadgetText(MainWindow\txtMessage,"Mouse over button")
    Else
      SetGadgetText(MainWindow\txtMessage,"Where's the mouse?")
    EndIf
  EndIf
  
  If event=#PB_Event_Gadget     ;If event is from a gadget 
      
      Select EventGadget()      ; get the gadget number 
  
          
      EndSelect 
      
  EndIf 
Until event=#PB_Event_CloseWindow And EventWindow()=MainWindow\window 
Method 2: PtinRect

Code: Select all

Structure wndMain 
  window.l 
  btnClose.l 
  btnViewParents.l 
  txtMessage.l 
EndStructure 

MainWindow.wndMain 
;assign Id's 
MainWindow\window=0 
MainWindow\btnClose=1 
MainWindow\btnViewParents=2 
MainWindow\txtMessage=3 

;Create window 

OpenWindow(mainWindow\window,0,0,500,200,"TEST",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(mainWindow\window)) 
ButtonGadget(MainWindow\btnClose,400,150,40,30,"CLOSE") 
TextGadget(MainWindow\txtMessage,10,10,200,30,"TEST") 


Repeat 
  event.l=WaitWindowEvent(10)   ;catch all events from any window 
  
  If event = #WM_MOUSEMOVE
    GetWindowRect_(GadgetID(Mainwindow\btnclose), @gr.RECT)
    GetCursorPos_(@cp.point)
    If PtInRect_(@gr, cp\x, cp\y)
      SetGadgetText(MainWindow\txtMessage,"Mouse over button")
    Else
      SetGadgetText(MainWindow\txtMessage,"Where's the mouse?")
    EndIf
  EndIf
  
  If event=#PB_Event_Gadget     ;If event is from a gadget 
      
      Select EventGadget()      ; get the gadget number 
  
          
      EndSelect 
      
  EndIf 
Until event=#PB_Event_CloseWindow And EventWindow()=MainWindow\window 
Method 3: PtinRegion

Code: Select all

Structure wndMain 
  window.l 
  btnClose.l 
  btnViewParents.l 
  txtMessage.l 
EndStructure 

MainWindow.wndMain 
;assign Id's 
MainWindow\window=0 
MainWindow\btnClose=1 
MainWindow\btnViewParents=2 
MainWindow\txtMessage=3 

;Create window 

OpenWindow(mainWindow\window,0,0,500,200,"TEST",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(mainWindow\window)) 
ButtonGadget(MainWindow\btnClose,400,150,40,30,"CLOSE") 
TextGadget(MainWindow\txtMessage,10,10,200,30,"TEST") 

Repeat 
  event.l=WaitWindowEvent(10)   ;catch all events from any window 
  
  If event = #WM_MOUSEMOVE
    If Not hRgn : hRgn = CreateRectRgn_(0,0, 40, 30) : EndIf
    GetCursorPos_(@cp.POINT)
    MapWindowPoints_(#Null, GadgetID(Mainwindow\btnclose), @cp, 1)
    If PtInRegion_(hRgn, cp\x, cp\y)
      SetGadgetText(MainWindow\txtMessage,"Mouse over button")
    Else
      SetGadgetText(MainWindow\txtMessage,"Where's the mouse?")
    EndIf
  EndIf
  
  If event=#PB_Event_Gadget     ;If event is from a gadget 
      
      Select EventGadget()      ; get the gadget number 

      EndSelect 
      
  EndIf 
Until event=#PB_Event_CloseWindow And EventWindow()=MainWindow\window 

Posted: Mon Nov 06, 2006 2:04 pm
by AND51
What about WindowFromPoint_()? It's the easiest way to realize that, I assume.

WindowFromPoint_(x.l, y.l) returns the Handle of what the mouse is over. If the mouse is over a Gadget, the GadgetID() is returned. If the mouse is over a window, the WindowID() is returned.

You must give this procedure two parameters: The coords, you want to test.

Simply put the mouse-coords in:

Code: Select all

Repeat
     handle=WindowFromPoint_(DesktopMouseX(), DesktopMouseY())
     If handle = GadgetID(#Button_1)
          Debug "Mouse is over the Button!"
     EndIf
     
     Delay(1000)
ForEver
By the way: This procedure does not require any Structures, Buffers or Pointers!

Thank You

Posted: Mon Nov 06, 2006 2:19 pm
by The Mexican
Thank You guys, this was very helpful!!

Posted: Mon Nov 06, 2006 2:57 pm
by Flype
AND51 wrote:What about WindowFromPoint_()? It's the easiest way to realize that, I assume.

WindowFromPoint_(x.l, y.l) returns the Handle of what the mouse is over. If the mouse is over a Gadget, the GadgetID() is returned. If the mouse is over a window, the WindowID() is returned.

You must give this procedure two parameters: The coords, you want to test.

Simply put the mouse-coords in:

Code: Select all

Repeat
     handle=WindowFromPoint_(DesktopMouseX(), DesktopMouseY())
     If handle = GadgetID(#Button_1)
          Debug "Mouse is over the Button!"
     EndIf
     
     Delay(1000)
ForEver
By the way: This procedure does not require any Structures, Buffers or Pointers!
yes, and this can be cumulated with the GetDlgCtrlID_() win32 function to easily obtain the PureBasic identifier.

something like this :

Code: Select all

Repeat
  
  hwnd = WindowFromPoint_(DesktopMouseX(), DesktopMouseY())
  
  If hwnd
    Select GetDlgCtrlID_(hwnd)
      Case #Button_1: Debug "Mouse is over the Button 1 !"
      Case #Button_2: Debug "Mouse is over the Button 2 !"
    EndSelect
  EndIf
  
  Delay(1000)
  
ForEver

Posted: Mon Nov 06, 2006 5:41 pm
by AND51
I don't understand the word "cumulated"... Can you explain it to me again?

Well, I understood your idea as the following: getDlgCtrlID_() turns a unique system handle into the internal PureBasic ID?

Posted: Mon Nov 06, 2006 8:33 pm
by Flype
AND51 wrote:I don't understand the word "cumulated"... Can you explain it to me again?

Well, I understood your idea as the following: getDlgCtrlID_() turns a unique system handle into the internal PureBasic ID?
well, it's exactly that.

and the word 'cumulated' must be an error of translation as my french -> english is not perfect - but much better than the google one :)

i would say something like 'added', 'mixed' or 'improved'.