Burgs Posted May 21, 2013 Share Posted May 21, 2013 (edited) 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. expandcollapse popup#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 BEACONS_55-47.txt Edited May 21, 2013 by Burgs Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted May 21, 2013 Moderators Share Posted May 21, 2013 Burgs, How is this different from your last thread? M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Burgs Posted May 21, 2013 Author Share Posted May 21, 2013 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 More sharing options...
Burgs Posted May 22, 2013 Author Share Posted May 22, 2013 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 More sharing options...
Artisan Posted May 28, 2013 Share Posted May 28, 2013 (edited) 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. expandcollapse popup#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 May 28, 2013 by Artisan Link to comment Share on other sites More sharing options...
Artisan Posted May 28, 2013 Share Posted May 28, 2013 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 More sharing options...
Moderators Melba23 Posted May 28, 2013 Moderators Share Posted May 28, 2013 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 onCan 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 wolflake 1 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Artisan Posted May 28, 2013 Share Posted May 28, 2013 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? expandcollapse popup#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 More sharing options...
Artisan Posted May 28, 2013 Share Posted May 28, 2013 I tried that. I even tried calling it in Main(), and still nothing. : Link to comment Share on other sites More sharing options...
Artisan Posted May 31, 2013 Share Posted May 31, 2013 (edited) 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 May 31, 2013 by Artisan Link to comment Share on other sites More sharing options...
Burgs Posted June 9, 2013 Author Share Posted June 9, 2013 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 More sharing options...
Artisan Posted June 10, 2013 Share Posted June 10, 2013 By any chance, is your right-click code being processed before the left-click? It's possible that it's discarding a left-click notification, if that's the case. Link to comment Share on other sites More sharing options...
Burgs Posted June 10, 2013 Author Share Posted June 10, 2013 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 More sharing options...
FireFox Posted June 10, 2013 Share Posted June 10, 2013 Hi, Have you tried the $GUI_EVENT_PRIMARYUP/DOWN events with the GUIGetMsg function? Br, FireFox. Link to comment Share on other sites More sharing options...
Burgs Posted June 10, 2013 Author Share Posted June 10, 2013 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. expandcollapse popupWhile 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 More sharing options...
Burgs Posted June 10, 2013 Author Share Posted June 10, 2013 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 More sharing options...
Burgs Posted June 11, 2013 Author Share Posted June 11, 2013 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 More sharing options...
Burgs Posted June 11, 2013 Author Share Posted June 11, 2013 OK thanks again for your help. Regards. Link to comment Share on other sites More sharing options...
Artisan Posted June 12, 2013 Share Posted June 12, 2013 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 More sharing options...
Burgs Posted June 13, 2013 Author Share Posted June 13, 2013 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now