Jump to content

Right-Click and Hover array values?


Burgs
 Share

Recommended Posts

Greetings,

   The attached working code creates 2 GUI windows, the 'second' is labeled as "Map Selector" and within that I have a 2048x2048 pixel image with a bunch of hexagons.  On this large image I am creating small ("plus sign") images inside each of the hexagons using an external ".txt" file that contains the x, y coordinates that each "plus sign" is to be placed at...This all works correctly.
 

  I have it setup to allow for both 'hover' and 'right-click' of controls, it seems to work however the messagebox that I have popping up reports the incorrect number for the control that has been clicked.  I believe it may be reporting the 'order' that the control was created when what I want is the array index number associated with the control so that I can further manipulate the correct control, by inserting a contextmenu for example (ideally within the 'loop' code associated with the control array).  Any help on explaining how to do this will be much appreciated.  

NOTE:  when the code begins running you will need to wait maybe 10 seconds until the images are all drawn...there will be a progressbar to indicate when the "Map Selector" is completely drawn...Thanks again.
 

#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <GuiComboBoxEx.au3>
#include <GUIConstantsEx.au3>
#include <File.au3>
#include <GDIPlus.au3>
#include <GUIScrollBars_Size.au3>
#include <Misc.au3>

 Opt("PixelCoordMode", 0)

 Global $aSB_Size_MapBack, $aSB_Size_MiniBack
 Global $hDLL = DllOpen("user32.dll")

 Global $BEACON_X = 0
 Global $BEACON_Y = 1
 Global $BEACON[2586]  
 Global $BEACON_TRAITS[2586][18]  ;hold the 'traits' for each BEACON on the map... 
 Global $MapFile = "C:\My Documents\HEXES-2048.jpg"  ;get the file for the map...


 Global $MainGUI = GUICreate("SAMPLE", 425, 540, 450, 250)
 GUISetState(@SW_SHOW) 

 GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
 GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")

 $font = "Arial"

 $_Reference = FileOpen("C:\My Documents\BEACONS_55-47.txt", 0)  ;open for READING... 
  if $_Reference == -1 Then MsgBox(64, "Error: File Open", "Unable to open 'BEACONS'...") 

 $PROGRESS_TXT = GUICtrlCreateLabel("Processing Map Data...", 10, 286, 175, 20, BitOr($GUI_SS_DEFAULT_LABEL, $SS_LEFT), -1)
 GUICtrlSetState($PROGRESS_TXT, $GUI_SHOW)
 GUICtrlSetBkColor($PROGRESS_TXT, $GUI_BKCOLOR_TRANSPARENT)
 GUICtrlSetFont($PROGRESS_TXT, 8.5, 400, 4, $font)

 $progressbar1 = GUICtrlCreateProgress(10, 300, 195, 20)
 GUICtrlSetState($progressbar1, $GUI_SHOW)
 GUICtrlSetState($PROGRESS_TXT, $GUI_SHOW)
 $s = 0  ;ProgressBar-saveposition 

 Map_Window()

 if $s >= 100 Then 
 GUICtrlSetState($progressbar1, $GUI_HIDE)  ;hide 'ProgressBar' when 'completed'... 
 $s = 0  ;reset ProgressBar-saveposition 
 GUICtrlSetData($PROGRESS_TXT, "Thank you for waiting...")
 EndIf  ;$s >= 100...'ProgressBar' has been 'completed' 
    

 GUISetState(@SW_ENABLE, $MapBack)

 WinActivate("SAMPLE")


While 1
   
    $nMsg = GUIGetMsg(1)  ;use advanced mode when using multiple GUIs
    Switch $nMsg[1]  ;Switch on the GUI sending the message

        Case $MapBack
            Switch $nMsg[0]
            
                Case $BEACON[0] To $BEACON[2585]

                 For $i = 1 To UBound($BEACON) - 1 
                  if $nMsg[0] = $BEACON[$i] Then

                  $MARK_X_PLOT = $BEACON_TRAITS[$i][$BEACON_X]  ;store the 'clicked' X position...
                  $MARK_Y_PLOT = $BEACON_TRAITS[$i][$BEACON_Y]  ;store the 'clicked' Y position...  
                  GUISwitch($MapBack)                

                  Local $aPos = ControlGetPos($MapBack, "", $nMsg[0])


                  ExitLoop
                  EndIf     
                 Next

                 GUISwitch($MainGUI)  ;set the focus back to the Main Interface...

            EndSwitch

        Case $MainGUI
            Switch $nMsg[0] ; switch on the control from the GUI sending the message.
                Case $GUI_EVENT_CLOSE
                  Exit

            EndSwitch

    EndSwitch

 $_CLICK_DETAIL = GUIGetCursorInfo($MapBack)
  ;if $_CLICK_DETAIL[4] <> 0 Then 
  ; For $_RC = 0 To UBound($BEACON) - 1
  ;  if $_CLICK_DETAIL[4] == $BEACON[$_RC] Then MsgBox(4096, "HOVER", " Hovering over a BEACON..." & $BEACON[$_RC])
  ; Next  ;Next $_RC     
  ;EndIf  ;$_CLICK_DETAIL[4] NOT 0 (HOVER over a control) 
  if $_CLICK_DETAIL[3] == 1 Then  
   For $_RC = 0 To UBound($BEACON) - 1
    if $_CLICK_DETAIL[4] == $BEACON[$_RC] Then MsgBox(4096, "RIGHT-CLICK", " Right-Clicked a BEACON..." & $BEACON[$_RC])
   Next  ;Next $_RC  
  EndIf  ;$_CLICK_DETAIL[3] is 1 (RIGHT CLICK a control) 

Wend  

DllClose($hDLL)


Func Map_Window()

    ; get parameters for this GUI
    $aSB_Size_MapBack = _GUIScrollbars_Size(2048, 2048, 768, 576)

    Global $MapBack = GUICreate("Map Selector", 768, 576, 485, 250, BitOR($WS_MINIMIZE, $WS_DISABLED, $WS_CAPTION, $WS_EX_LAYERED), -1)  

    ; background picture
    Global $TheMap = GUICtrlCreatePic($MapFile, 9, 0, 2048, 2048, -1, -1)
    GUICtrlSetState($TheMap, $GUI_DISABLE) ; you have to disable the graphic or it overlaps all controls on it


    _GUIScrollBars_Init($MapBack)
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_HORZ, $aSB_Size_MapBack[1])
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_HORZ, $aSB_Size_MapBack[0])
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_VERT, $aSB_Size_MapBack[3])
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_VERT, $aSB_Size_MapBack[2])

    GUISetState(@SW_SHOW)


   For $x = 1 To UBound($BEACON) - 1
 
   $LOOK = FileReadLine($_Reference, $x)  ;read the line # in the 'BEACONS' file for the associated HEX...
   $result = StringInStr($LOOK, ",", 0, 1)  ; find the "1st" instance of a "," in the read line...(follows '$BEACON_X' file info, precedes '$BEACON_Y')
   $result2 = StringInStr($LOOK, ",", 0, 2)  ; find the "2nd" instance of a "," in the read line...(follows '$BEACON_Y' file info)
 
   $MARK_X_PLOT = Number(StringLeft($LOOK, $result - 1))   
   $MARK_Y_PLOT = Number(StringMid($LOOK, $result + 1, ($result2 - $result) - 1))   

   $BEACON[$x] = GUICtrlCreatePic("C:\My Documents\Cross.gif", $MARK_X_PLOT, $MARK_Y_PLOT, 11, 11, $SS_NOTIFY)
   GUICtrlSetState($BEACON[$x], $GUI_ENABLE)    
   GUI($BEACON[$x], $GUI_SHOW)

   ;**set the NEEDED "BEACON_TRAITS" INTO ARRAY POSITIONS...
   $BEACON_TRAITS[$x][$BEACON_X] = $MARK_X_PLOT
   $BEACON_TRAITS[$x][$BEACON_Y] = $MARK_Y_PLOT

   GUICtrlSetData($progressbar1, $s)  ;update the 'ProgressBar'... 
   $s += .039  ;2583 * .039 = 100 (about)...

   Next

 $s += 1  ;set to indicate 'completion' of 'ProgressBar'...

EndFunc   ;==>Map_Window


;/////////////////

Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $xChar, $xPos
    Local $Page, $Pos, $TrackPos
    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $xChar = $aSB_WindowInfo[$iIndex][2]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $xPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $xPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    Switch $nScrollCode
        Case $SB_LINELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch
    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)

    ; Move the scrollbar
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0)

    ; Now move other scrollbar
    Switch $hWnd
        Case $MapBack
            ; get fractional position of scrollbar in moved GUI
            $nPos_HORZ = _GUIScrollBars_GetScrollInfoPos($MapBack, $SB_HORZ)
            $nFraction_HORZ = $nPos_HORZ / ($aSB_Size_MapBack[1] - $aSB_Size_MapBack[0])
            ; And set other scrollbar to same fraction
            ;_GUIScrollBars_SetScrollInfoPos($MiniBack, $SB_HORZ, ($aSB_Size_MiniBack[1] - $aSB_Size_MiniBack[0]) * $nFraction_HORZ)
    EndSwitch

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_HSCROLL

Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $yChar, $yPos
    Local $Page, $Pos, $TrackPos
    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $yChar = $aSB_WindowInfo[$iIndex][3]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    Switch $nScrollCode
        Case $SB_LINEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch
    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)

    ; Move the scrollbar
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
    ; Now move other scrollbar
    Switch $hWnd
        Case $MapBack
            ; get fractional position of scrollbar in moved GUI
            $nPos_VERT = _GUIScrollBars_GetScrollInfoPos($MapBack, $SB_VERT)
            $nFraction_VERT = $nPos_VERT / ($aSB_Size_MapBack[1] - $aSB_Size_MapBack[0])
            ; And set other scrollbar to same fraction
            ;_GUIScrollBars_SetScrollInfoPos($MiniBack, $SB_VERT, ($aSB_Size_MiniBack[1] - $aSB_Size_MiniBack[0]) * $nFraction_VERT)
    EndSwitch
    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_VSCROLL

post-35979-0-44887200-1369134003_thumb.g

BEACONS_55-47.txt

post-35979-0-92413900-1369134177_thumb.j

Edited by Burgs
Link to comment
Share on other sites

  • Moderators

Burgs,

How is this different from your last thread? :huh:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hello,

  The last thread dealt with trouble positioning a control on the 'complete' (2048x2048) GUI window either by clicking or other means...here I am trying to figure why the hover and/or right-click I have coded is not returning the array index value of the clicked/hovered control...completely different and seperate issues...

Link to comment
Share on other sites

Is there no way to accomplish this in a 'clean' way?  I thought about sending a 'click' to the control when it is hovered/right-clicked in order to trigger the event function in the while loop in order to identify the correct clicked control...however that seems a bit 'messy', I had hoped there may be a better way to do it? 

Link to comment
Share on other sites

Hi Burgs,

I had to rewrite the code in my style so that I could better read & understand what you were doing.  Please don't be insulted - we just have different styles.  Anyway, I got it functioning and demonstrated how to get the Control ID of whatever you're hovering over or right-clicking.

Using GUIGetCursorInfo() isn't always the best approach since the mouse can move and land you on a different control by the time your code reacts to it (especially with how many elements you're loading in).  You may want to consider using WM_NOTIFY instead.  (See the helpfile on _GUICtrlStatusBar_Create for a good example.)

Anyway, here's my code.  Note that I'm assuming the 3 files needed are in @ScriptDir, so you'll need to update my example accordingly.  Also note that $HOVER_TIME is the time delay in milliseconds before you execute your Hover event code.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "GUIScrollBars_Size.au3"

AutoItSetOption("MustDeclareVars", 1)
Global Const $GUI_WIDTH = 768, $GUI_HEIGHT = 576, $HOVER_TIME = 1000
Global Const $BEACON_X = 0, $BEACON_Y = 1

Global $hBEACON[1], $BEACON_TRAITS[1][1]
Global $MapBack, $TheMap

Initialize()
Main()

Func Initialize()

    ; Load reference file
    Local $_Reference = FileRead(@ScriptDir & "\BEACONS_55-47.txt")
    If @error Then
        MsgBox(16, "Error", "Cannot read BEACONS_55-47.txt" & @LF & "Aborting")
        Exit
    EndIf
    $_Reference = StringSplit(StringStripCR(StringStripWS($_Reference, 2)), @LF)
    If @error Then
        MsgBox(16, "Error", "Invalid BEACONS_55-47.txt" & @LF & "Aborting")
        Exit
    EndIf
    Dim $hBEACON[$_Reference[0]]
    Dim $BEACON_TRAITS[$_Reference[0]][18]

    ; Build Loader GUI
    Local $hLoader = GUICreate("Loading Map...", 300, 100, Default, Default, $WS_BORDER)
    Local $hProgress = GUICtrlCreateProgress(20, 20, 260, 20)
    GUISetState(@SW_SHOW, $hLoader)

    ; Start building main GUI
    $MapBack = GUICreate("Map Selector", $GUI_WIDTH, $GUI_HEIGHT)
    GUISetBkColor(0xFFFFFF)
    Local $aRet = _GUIScrollbars_Size(2048, 2048, $GUI_WIDTH, $GUI_HEIGHT)
    GUIRegisterMsg($WM_HSCROLL, "_Scrollbars_WM_HSCROLL")
    GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL")
    _GUIScrollBars_Init($MapBack)
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_HORZ, $aRet[0])
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_HORZ, $aRet[1])
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_VERT, $aRet[2])
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_VERT, $aRet[3])
    GUISwitch($MapBack)
    $TheMap = GUICtrlCreatePic(@ScriptDir & "\HEXES-2048.jpg", 9, 0, 2048, 2048)
    GUICtrlSetState($TheMap, $GUI_DISABLE)

    ; Load main GUI elements
    Local $i, $x, $y, $temp
    For $i = 1 To $_Reference[0]
        $temp = StringSplit($_Reference[$i], ',', 2)
        $x = Number($temp[0])
        $y = Number($temp[1])
        $BEACON_TRAITS[$i - 1][$BEACON_X] = $x
        $BEACON_TRAITS[$i - 1][$BEACON_Y] = $y
        $hBEACON[$i - 1] = GUICtrlCreatePic(@ScriptDir & "\Cross.gif", $x, $y, 11, 11)
        GUISwitch($hLoader)
        GUICtrlSetData($hProgress, 100 * $i / $_Reference[0])
        GUISwitch($MapBack)
    Next
    GUISetState(@SW_SHOW, $MapBack)
    GUISetState(@SW_HIDE, $hLoader)
EndFunc

Func Main()
    Local $msg, $Timer, $ControlID, $ShowingToolTip = False
    $Timer = TimerInit()
    While 1
        $msg = GUIGetMsg()
        If $msg == $GUI_EVENT_CLOSE Then Exit

        ; Using GUIGetCursorInfo really isn't the best approach (can be unreliable)
        ; What if the mouse moves before you can process everything?
        ; Consider registering a WM_NOTIFY function instead
        ; The help file for _GUICtrlStatusBar_Create has an excellent example of how WM_NOTIFY works
        $msg = GUIGetCursorInfo($MapBack)

        ; Right Click
        If $msg[3] Then
            ; $msg[4] has the Control ID that you're hovering over
            ; This is just a demo to show that we can manipulate it
            GUICtrlSetState($msg[4], $GUI_HIDE)
        EndIf

        ; Hover
        If $msg[4] == $ControlID Then
            ; Still hovering - check hover time
            If TimerDiff($Timer) > $HOVER_TIME Then
                If Not $ShowingToolTip Then ToolTip("ControlID of hover item:" & @LF & $msg[4])
                $ShowingToolTip = True
                ; Again, $msg[4] has the Control ID that you're hovering over
                ; This is just a demo to show that we can manipulate it
                GUICtrlSetState($msg[4], $GUI_HIDE)
            EndIf
        Else
            ; Hovering over something else - reset timer
            $ControlID = $msg[4]
            ToolTip("")
            $ShowingToolTip = False
            $Timer = TimerInit()
        EndIf
    WEnd
EndFunc



; ////////////////////////////////////////////////

Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $yChar = $aSB_WindowInfo[$iIndex][3]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP
            DllStructSetData($tSCROLLINFO, "nPos", $Min)
        Case $SB_BOTTOM
            DllStructSetData($tSCROLLINFO, "nPos", $Max)
        Case $SB_LINEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)

    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf

    Return $GUI_RUNDEFMSG

EndFunc   ;==>_Scrollbars_WM_VSCROLL

Func _Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $xChar, $xPos
    Local $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $xChar = $aSB_WindowInfo[$iIndex][2]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $xPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $xPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    Switch $nScrollCode
        Case $SB_LINELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)

    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0)

    Return $GUI_RUNDEFMSG

EndFunc   ;==>_Scrollbars_WM_HSCROLL
Edited by Artisan
Link to comment
Share on other sites

So, yeah, silly me.  Your original code was working fine.  When Control ID's are assigned, the ID number they get is typically the same as the order they were created in.  The first control is 1, the second is 2, and so on.  You can verify this by changing your right-click message box notification into "GUICtrlSetState($BEACON[$_RC], $GUI_HIDE)".  The control you right-clicked on is the one that's hidden, which verifies you are correctly identifying the control.

Oops - I should have tried that first.  ;) 

Link to comment
Share on other sites

  • Moderators

Hi,

 

When Control ID's are assigned, the ID number they get is typically the same as the order they were created in. The first control is 1, the second is 2, and so on

Can I just clarify that a bit.

The ControlIDs are actually the index numbers to an internal AutoIt array which holds details of the actual control - that way AutoIt can use the related handle to action the correct API call. Normally the ControlIDs are in numerical succession starting at 3 (0-2 are reserved), but the internal algorithm actually looks for the first available entry in this array, so deleting previously created controls can leave "holes" which will be filled first.

A lot of people, including myself I am afraid to say, use the successive nature of ControlIDs to run loops when altering groups of controls. This is not good coding practice and you should really use an array to hold the returned values to cater for the possibility that they are not successive.

I hope that explains it clearly - please come back if not. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for that, Melba.  I think I've noticed before that it started at 3 and forgot about it.  And thanks for the tip about the internal array filling in any gaps.  That's good to know.

Quick question (and Burgs, sorry if I'm taking away from your learning).  I tried to toss in a WM_NOTIFY function just to make sure I could.  Doesn't work.  Code is below, and I have no idea what's broken.  I'm probably doing something really stupid.  Can anyone spot my mistake?

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "GUIScrollBars_Size.au3"

AutoItSetOption("MustDeclareVars", 1)
Global Const $GUI_WIDTH = 768, $GUI_HEIGHT = 576, $HOVER_TIME = 1000
Global Const $BEACON_X = 0, $BEACON_Y = 1
Global $hBEACON[1], $BEACON_TRAITS[1][1]
Global $MapBack, $TheMap
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

Initialize()
Main()

Func Initialize()

    ; Load reference file
    Local $_Reference = FileRead(@ScriptDir & "\BEACONS_55-47.txt")
    If @error Then
        MsgBox(16, "Error", "Cannot read BEACONS_55-47.txt" & @LF & "Aborting")
        Exit
    EndIf
    $_Reference = StringSplit(StringStripCR(StringStripWS($_Reference, 2)), @LF)
    If @error Then
        MsgBox(16, "Error", "Invalid BEACONS_55-47.txt" & @LF & "Aborting")
        Exit
    EndIf
    Dim $hBEACON[$_Reference[0]]
    Dim $BEACON_TRAITS[$_Reference[0]][18]

    ; Build Loader GUI
    Local $hLoader = GUICreate("Loading Map...", 300, 100, Default, Default, $WS_BORDER)
    Local $hProgress = GUICtrlCreateProgress(20, 20, 260, 20)
    GUISetState(@SW_SHOW, $hLoader)

    ; Start building main GUI
    $MapBack = GUICreate("Map Selector", $GUI_WIDTH, $GUI_HEIGHT)
    GUISetBkColor(0xFFFFFF)
    Local $aRet = _GUIScrollbars_Size(2048, 2048, $GUI_WIDTH, $GUI_HEIGHT)
    GUIRegisterMsg($WM_HSCROLL, "_Scrollbars_WM_HSCROLL")
    GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL")
    _GUIScrollBars_Init($MapBack)
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_HORZ, $aRet[0])
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_HORZ, $aRet[1])
    _GUIScrollBars_SetScrollInfoPage($MapBack, $SB_VERT, $aRet[2])
    _GUIScrollBars_SetScrollInfoMax($MapBack, $SB_VERT, $aRet[3])
    GUISwitch($MapBack)
    $TheMap = GUICtrlCreatePic(@ScriptDir & "\HEXES-2048.jpg", 9, 0, 2048, 2048)
    GUICtrlSetState($TheMap, $GUI_DISABLE)

    ; Load main GUI elements
    Local $i, $x, $y, $temp
    For $i = 1 To $_Reference[0]
        $temp = StringSplit($_Reference[$i], ',', 2)
        $x = Number($temp[0])
        $y = Number($temp[1])
        $BEACON_TRAITS[$i - 1][$BEACON_X] = $x
        $BEACON_TRAITS[$i - 1][$BEACON_Y] = $y
        $hBEACON[$i - 1] = GUICtrlCreatePic(@ScriptDir & "\Cross.gif", $x, $y, 11, 11)
        GUISwitch($hLoader)
        GUICtrlSetData($hProgress, 100 * $i / $_Reference[0])
        GUISwitch($MapBack)
    Next
    GUISetState(@SW_SHOW, $MapBack)
    GUISetState(@SW_HIDE, $hLoader)
EndFunc

Func Main()
    Local $msg, $Timer, $ControlID, $ShowingToolTip = False
    $Timer = TimerInit()
    While 1
        $msg = GUIGetMsg()
        If $msg == $GUI_EVENT_CLOSE Then Exit

        $msg = GUIGetCursorInfo($MapBack)

        ; Right Click
        If $msg[3] Then
;~          GUICtrlSetState($msg[4], $GUI_HIDE)
        EndIf

        ; Hover
        If $msg[4] == $ControlID Then
            ; Still hovering - check hover time
            If TimerDiff($Timer) > $HOVER_TIME Then
                If Not $ShowingToolTip Then ToolTip("ControlID of hover item:" & @LF & $msg[4])
                $ShowingToolTip = True
;~              GUICtrlSetState($msg[4], $GUI_HIDE)
            EndIf
        Else
            ; Hovering over something else - reset timer
            $ControlID = $msg[4]
            ToolTip("")
            $ShowingToolTip = False
            $Timer = TimerInit()
        EndIf
    WEnd
EndFunc



; ////////////////////////////////////////////////

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ; Catch notifications
    #forceref $hWnd, $iMsg, $wParam

    Local $hWndFrom, $iCode, $tNMHDR
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")

;~  If $hWndFrom == $MapBack And $iCode == $NM_CLICK Then
        ConsoleWrite("Hiya" & @LF)
;~  EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $yChar = $aSB_WindowInfo[$iIndex][3]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP
            DllStructSetData($tSCROLLINFO, "nPos", $Min)
        Case $SB_BOTTOM
            DllStructSetData($tSCROLLINFO, "nPos", $Max)
        Case $SB_LINEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGEUP
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGEDOWN
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)

    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf

    Return $GUI_RUNDEFMSG

EndFunc   ;==>_Scrollbars_WM_VSCROLL

Func _Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)

    #forceref $Msg, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $xChar, $xPos
    Local $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $xChar = $aSB_WindowInfo[$iIndex][2]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    $xPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $xPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    Switch $nScrollCode
        Case $SB_LINELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
        Case $SB_LINERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
        Case $SB_PAGELEFT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
        Case $SB_PAGERIGHT
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
        Case $SB_THUMBTRACK
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)

    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0)

    Return $GUI_RUNDEFMSG

EndFunc   ;==>_Scrollbars_WM_HSCROLL
Link to comment
Share on other sites

Interesting.  I tried replacing WM_NOTIFY with WM_COMMAND.  Left clicking works, but right-clicking doesn't.  Windows is weird...

EDIT:

Very weird.  I just tried with GUIRegisterMsg($WM_RBUTTONDOWN, "WM_RBUTTONDOWN"), and it catches right-clicks on the map, but not on the crosses.  It's very weird because the map and all the crosses are created with GUICtrlCreatePic, and also the map is disabled and the crosses are not.  Puzzled, I am.  I would stick with GUIGetCursorInfo for now.

Relevant code:

GUIRegisterMsg($WM_RBUTTONDOWN, "WM_RBUTTONDOWN")

...

Func WM_RBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) ; Catch notifications
    #forceref $hWnd, $iMsg, $wParam

;~     Local $hWndFrom, $iCode, $tNMHDR
;~     $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
;~     $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;~     $iCode = DllStructGetData($tNMHDR, "Code")

;~  If $hWndFrom == $MapBack And $iCode == $NM_CLICK Then
        ConsoleWrite("Hiya" & @LF)
;~  EndIf

    Return $GUI_RUNDEFMSG
EndFunc
Edited by Artisan
Link to comment
Share on other sites

  • 2 weeks later...

Sorry I was away from this for a bit...thanks to all those who posted, and to you Artisan for that work and info you put in.  I ended up getting around this issue by saving the control handles in an array when the image was created, and then searching thru the array when there's a 'right-click' to match the handle in the array with that which had been clicked...seems to work fine.

Thanks for that info about the 'WM_NOTIFY' along with the reference example in the Help File...I find that potentially useful as well.  I am however now experiencing a problem whereby the 'right-click' is recognized but 'left-click' is not...using essentially identical code...yes Windows is wierd, I definitely concur. 

Link to comment
Share on other sites

Hello,

  Actually no, however I do have before that an 'IsPressed' command that checks for a 'left-click'...however I wouldn't think that should cause any problems...?? 

if _IsPressed("01", $hDLL) Then
   ; Wait until key is released.
  While _IsPressed("01", $hDLL) 
  Sleep(250)
  WEnd
 ;do stuff
 EndIf  ;make sensitivity to 'left-click' within various control... 

 $_CLICK_DETAIL = GUIGetCursorInfo($MapBack)

  if $_CLICK_DETAIL[2] == 1 Then
  $aHWD = GUICtrlGetHandle($_CLICK_DETAIL[4])   
  ;do stuff
  EndIf  ;$_CLICK_DETAIL[2] is 1 (LEFT-CLICK...on $MapBack)  ;left-click doesn't seem to be working

  if $_CLICK_DETAIL[3] == 1 Then  
  $aHWD = GUICtrlGetHandle($_CLICK_DETAIL[4])    
  ;do stuff
  EndIf  ;$_CLICK_DETAIL[3] is 1 (RIGHT_CLICK...on $MapBack)  ;however right-click seems to be working?

Thanks again for your interest.  Regards.

Link to comment
Share on other sites

Hello,

  No not yet, still had been experimenting...however I will give that a shot.  Thanks for the suggestion,  It would seem, using the code I had posted in my original entry...that I need to 'break out' those Case statements individually...is there a way to combine them into a single Case statement like the one that fires when a "Beacon[$i]" is activated?  Perhaps I'm not understanding the Help File description adequately.  In addition even if that method works perfectly I'd still like to know why the other method I tried was not functioning (for left-clicks anyway)?   

Thanks again.

While 1
   
    $nMsg = GUIGetMsg(1)  ;use advanced mode when using multiple GUIs
    Switch $nMsg[1]  ;Switch on the GUI sending the message

        Case $MapBack
            Switch $nMsg[0]
            

                Case $GUI_EVENT_PRIMARYDOWN

                 For $i = 1 To UBound($BEACON) - 1 
                  if $nMsg[0] = $BEACON[$i] Then

                  ;do stuff 

                  ExitLoop
                  EndIf     
                 Next   

                Case $GUI_EVENT_SECONDARYDOWN

                 For $i = 1 To UBound($BEACON) - 1 
                  if $nMsg[0] = $BEACON[$i] Then

                  ;do stuff 

                  ExitLoop
                  EndIf     
                 Next   

                Case $BEACON[0] To $BEACON[2585]

                 For $i = 1 To UBound($BEACON) - 1 
                  if $nMsg[0] = $BEACON[$i] Then

                  ;do stuff 

                  ExitLoop
                  EndIf     
                 Next   

            EndSwitch

    EndSwitch
Link to comment
Share on other sites

Thanks for that info.  How do I then differentiate as to if a left-click was made or a right-click...with an "if" statement?  For example: 

Case $BEACON[0] To $BEACON[2585], $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_SECONDARYDOWN

 

if $GUI_EVENT_PRIMARYDOWN Then

;do stuff

EndIf

 

if $GUI_EVENT_SECONDARYDOWN Then

;do stuff

EndIf

 

...

Link to comment
Share on other sites

Thanks again, I need to be sure the correct clicked control is selected...I assume then this is valid code if I embed those Case statements?

Case $BEACON[0] To $BEACON[2585], $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_SECONDARYDOWN


                 For $i = 1 To UBound($BEACON) - 1 
                  if $nMsg[0] = $BEACON[$i] Then

                   If $nMsg[0] = $GUI_EVENT_PRIMARYDOWN Then
                   ;do stuff for left click
                   EndIf
    
                   If $nMsg[0] = $GUI_EVENT_SECONDARYDOWN Then
                   ;do differenct stuff for right-click
                   EndIf



                  ;do other stuff for any click... 

                  ExitLoop
                  EndIf     
                 Next
Link to comment
Share on other sites

I'm sure Burgs has spotted it by now, but there's a problem with the posted code.  The stuff for left-click and right-click will never happen.  The code requires $nMsg[0] to be one of the beacons.  That's fine, but in order to execute an If block, it checks to see if that same $nMsg[0] is equal to something else.  Which it won't be.

Link to comment
Share on other sites

Hello...yes that is correct it is non functional because of the beacons...so that leads me back to a frustrating question...how do I code the routine to be able to distinguish if a 'clicked' control (a beacon for example) has been either 'left-clicked' OR 'right-clicked'...?  The way I'm doing it with the Case statements would seem to not be possible because the $nMsg[0] returns the Control ID...and cannot ever return "1" for 'primarydown' or whatever...?? 

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