Jump to content

Check if cursor hovers over a label


Radiance
 Share

Recommended Posts

Hi all,

I'm trying to check if my mouse cursor hovers over a transparent label control which I have put over two other labels.

I've provided an example script below.

Even if the overlay is on top (you can check by including line 15) the GUIGetCursorInfo() function still returns the handle of the label below.

The only way to get the handle of the overlay is to mouseover in the space between the two labels.

Any ideas?

#include <GUIConstantsEx.au3>

Global $GUI = GUICreate("Test GUI", 400, 400)
Global $Label1 = GUICtrlCreateLabel("Label1", 20, 80, 150, 20)
Global $Label2 = GUICtrlCreateLabel("Label2", 200, 80, 150, 20)
Global $Input = GUICtrlCreateInput("", 20, 200)
Global $Overlay = GUICtrlCreateLabel("", 20, 80, 350, 20, $GUI_ONTOP)

GUICtrlSetBkColor($Label1, 0x000000)
GUICtrlSetBkColor($Label2, 0x000000)
GUICtrlSetColor($Label1, 0xffffff)
GUICtrlSetColor($Label2, 0xffffff)

GUICtrlSetBkColor($Overlay, -2)
;GUICtrlSetBkColor($Overlay, 0x000000)

GUISetState(@SW_SHOW)

AdlibRegister("_CheckHover", 200)


While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop
    Sleep(50)
WEnd


Func _CheckHover()
    Local $Info = GUIGetCursorInfo()
    If Not IsArray($Info) Then Return
    If $Info[4] = $Label1 Then GUICtrlSetData($Input, "Cursor over Label1")
    If $Info[4] = $Label2 Then GUICtrlSetData($Input, "Cursor over Label2")
    If $Info[4] = $Overlay Then GUICtrlSetData($Input, "Cursor over Overlay")
EndFunc

 

Edited by Radiance
Link to comment
Share on other sites

I bypassed the problem for now by increasing the width of the 3 labels per line so that they "dock" at each other, meaning there's no space between them.

I then have to check if the mouse is over any of the three labels, per line.

This works but I was hoping someone would come up with a better solution.

Edited by Radiance
Link to comment
Share on other sites

  • 1 year later...

Here's one way around it.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GUIConstantsEx.au3>

Global $GUI = GUICreate("Test GUI", 400, 400)
Global $Label1 = GUICtrlCreateLabel("Label1", 20, 80, 150, 20)
Global $Label2 = GUICtrlCreateLabel("Label2", 200, 80, 150, 20)
Global $Input = GUICtrlCreateInput("", 20, 200)
Global $Overlay = GUICtrlCreateLabel("", 20, 80, 350, 20) ;, $GUI_ONTOP)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $GUI_ONTOP = ' & Hex($GUI_ONTOP) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

GUICtrlSetBkColor($Label1, 0x000000)
GUICtrlSetBkColor($Label2, 0x000000)
GUICtrlSetColor($Label1, 0xffffff)
GUICtrlSetColor($Label2, 0xffffff)

GUICtrlSetBkColor($Overlay, -2)
;GUICtrlSetBkColor($Overlay, 0x000000)

GUISetState(@SW_SHOW)

AdlibRegister("_CheckHover", 200)


While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop
    Sleep(50)
WEnd


Func _CheckHover()
    Local $Info = GUIGetCursorInfo($GUI)
    If Not IsArray($Info) Then Return
    If $Info[0] > 19 And $Info[0] < 371 And $Info[1] > 79 And $Info[1] < 101 Then
        GUICtrlSetData($Input, "Cursor over Overlay")
    Else
        GUICtrlSetData($Input, "Cursor not over anything")
    EndIf
;~  If $Info[4] = $Label1 Then GUICtrlSetData($Input, "Cursor over Label1")
;~  If $Info[4] = $Label2 Then GUICtrlSetData($Input, "Cursor over Label2")
;~  If $Info[4] = $Overlay Then GUICtrlSetData($Input, "Cursor over Overlay")
EndFunc   ;==>_CheckHover

This checks the coordinates to see if it's over the overlay label in the GUI.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

That's a pretty cool approach but not exactly what I was looking for.

I need a way to put one transparent GUI control over the two labels and from my understanding the big label should already be above the other two.

Why does GUIGetCursorInfo still detect the one below it?

Link to comment
Share on other sites

That's a question for the devs. Open a track ticket and post the code above explaining what you're seeing.

In the meantime, use a workaround.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I'm not positive what result you are trying to accomplish, but I had some fun a made a dynamic "Hover" function.  Just to give you more workaround ideas. 

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>

#include <Array.au3>

Global $sHoveredControls = ""

Global $GUI = GUICreate("Test GUI", 400, 400)

Global $Overlay = GUICtrlCreateLabel("Static 1", 16, 76, 352, 28, $ES_CENTER)
Global $Label1 = GUICtrlCreateLabel("Static 2", 20, 80, 125, 20, $ES_CENTER)
Global $Label2 = GUICtrlCreateLabel("Static 3", 240, 80, 125, 20, $ES_CENTER)
Global $Input = GUICtrlCreateInput("", 20, 200, 344, 20, BitOR($ES_READONLY, $ES_CENTER))


GUICtrlSetBkColor($Overlay, 0xff7bff)
GUICtrlSetBkColor($Label1, 0x000000)
GUICtrlSetBkColor($Label2, 0x000000)
GUICtrlSetColor($Label1, 0xffffff)
GUICtrlSetColor($Label2, 0xffffff)


GUISetState(@SW_SHOW)

AdlibRegister("_CheckHover", 10)


While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop
    Sleep(50)
WEnd

Func _CheckHover()
    Local $sControlHover = _ControlHover()
    If $sControlHover <> $sHoveredControls Then
        $sHoveredControls = $sControlHover
        GUICtrlSetData($Input, $sHoveredControls)

    EndIf
EndFunc


Func _ControlHover()
    AdlibUnRegister("_ControlHover")
    ;Collect Class Instances
    Local $aControls = StringSplit(WinGetClassList($GUI),@CRLF)
    ;If No Instances Found Return Error
    If Not UBound($aControls) Then Return SetError(1, 0, 0)

    ;Create Local Variables
    Local $sControlClass = "", $iInstance = 1, $hCtrl, $aCtrlPos, $hCtrlHover = ""
    ;Collect Cursor Info
    Local $aMousePos = GUIGetCursorInfo($GUI)

    ;Loop Through Class Instances
    For $iX = 1 to $aControls[0]
        If $aControls[$iX] Then
            ;Track Class Instances
            $iInstance = Eval("CLASS_" & $aControls[$iX])
            If Not $iInstance Then
                $iInstance = 1
            Else
                $iInstance += 1
            EndIf
            Assign("CLASS_" & $aControls[$iX], $iInstance)
            $aControls[$iX] = $aControls[$iX] & Eval("CLASS_" & $aControls[$iX])
            ;Get Class Instance / Control Handle
            $hCtrl = ControlGetHandle($GUI, "", $aControls[$iX])
            ;Get Control Position
            $aCtrlPos = ControlGetPos($GUI, "", $hCtrl)
            ;Compare to Cursor Position
            If ($aMousePos[0] >= $aCtrlPos[0]) And ($aMousePos[0] <= $aCtrlPos[2]+$aCtrlPos[0]) And ($aMousePos[1] >= $aCtrlPos[1]) And ($aMousePos[1] <= $aCtrlPos[3]+$aCtrlPos[1]) Then
                If Not $hCtrlHover Then
                    $hCtrlHover &= $aControls[$iX] & " (" & $hCtrl & ")"
                Else
                    $hCtrlHover &= " | " & $aControls[$iX] & " (" & $hCtrl & ")"
                EndIf
            EndIf
        EndIf
    Next

    AdlibRegister("_ControlHover",10)
    Return $hCtrlHover
EndFunc

What might be of use would be to return an array of all controls that the mouse is over instead of the just first or last control found (like my example).  Then you can make a determination based on what controls are "hovered."  Just a thought.

edit:
I had to do it.  The function now returns handles for all of controls (detectable by WinGetClassList) the mouse is hovering over as a pipe "|" delimited string.  The control listing is in order of control creation/instance.

edit:
Minor performance tweak

Edited by spudw2k
Link to comment
Share on other sites

Thank you both for your answers. I think I'm going to open a ticket for the devs.
 

@spudw2k:

That was fun to try out, seems similar to the one from BrewManNH, working with coordinates.

 

Trying to explain what I want to do in detail.
 

Main_Menu.png.eeb77d67a38f55ffc2ada1e56b

 

I'm creating a GUI with multiple selection buttons where I want to perform certain action when the user hovers over one line, for example changing text in an information box or highlighting the line.

This works well if there's only one one element per line but gives me problems when I'm creating some sort of custom list view with more than 1 controls per line.

2.thumb.jpg.92cbc5e04afb0b5bfeaf072963f4

I need to check for every control in a line if the mouse hovers above it.
Also there are small gaps (around 3-5 pixels) between the controls where mouse hovering would also not be detected.

Link to comment
Share on other sites

Yes, my example works based on the control co-ords like BrewManNH's, but my function is "dynamic".  

Thank you for explaining your GUI; I think I get it. I must say, that is a neat looking GUI.  Are all of those controls labels?  It would be great if you could use a stylized listview which would made "tracking" the items beneath the mouse easier.

For what you are trying to accomplish both BrewManNHs and my workaround are reasonable candidates I'd say if you are looking to get something working now rather wait for the DEVs to correct it in X revision.  In fact....if those are all individual controls...I'm curious how my "hover" function performs.  My function (as I left it) iterates through all controls.  

Link to comment
Share on other sites

Personally, I'd use ToolTips for this, you have a lot of wasted space on the GUI just to display what is normally in a tooltip.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...