Burgs Posted May 19, 2013 Posted May 19, 2013 (edited) Greetings, I'm having a difficult time with this. 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. Following this I create a single square image that I call "unit1"...This all works correctly. My problem is that I want to 'click' the "plus-sign" images and then have the "unit" image move to that 'clicked' location...that works fine IF the window is NOT SCROLLED...however when I do move the GUI window using the scrollbars the image placement no longer works correctly...I am at a loss to explain why. I simply want to be able to move the "unit1" image (either by clicking a location or by other code-controlled means) to an absolute screen position...even if that position is not within view as it lies in an area of the main image beyond the viewable area of the window...for example move "unit1" from x = 10, y = 30 to x = 977, y = 1589... There must be a way to move images in absolute terms to any area on the 2048x2048 image...?? Thanks in advance for any help on what I am missing here. 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 $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.bmp" ;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) $_UNIT1 = GUICtrlCreatePic("C:\My Documents\unit1.gif", 10, 10, 0, 0, $SS_NOTIFY) GuiCtrlSetState($_UNIT1, $GUI_DISABLE) 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) GuiCtrlSetState($_UNIT1, $GUI_ENABLE) Local $size = WinGetPos("Map Selector") ; Create a point structure Local $tPoint = DllStructCreate("int X;int Y") ; Insert the coords DllStructSetData($tPoint, "X", $MARK_X_PLOT) DllStructSetData($tPoint, "Y", $MARK_Y_PLOT) ; Convert the coords _WinAPI_ScreenToClient($MapBack, $tPoint) GUICtrlSetPos($_UNIT1, DllStructGetData($tPoint, "X") + $size[0], DllStructGetData($tPoint, "Y") + $size[1]) 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 Wend 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) GUICtrlSetState($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 19, 2013 by Burgs
PhoenixXL Posted May 19, 2013 Posted May 19, 2013 (edited) Change to this the main loop 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 $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) GUICtrlSetState($_UNIT1, $GUI_ENABLE) Local $aPos = ControlGetPos($MapBack, "", $nMsg[0]) GUICtrlSetPos($_UNIT1, $aPos[0], $aPos[1]) 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 WEnd Edited May 19, 2013 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
Burgs Posted May 19, 2013 Author Posted May 19, 2013 Oh sorry I forgot the other 'plus sign' image...
Burgs Posted May 19, 2013 Author Posted May 19, 2013 Thank you for that post, PhoenixXL...that seems to have fixed the problem. That is a great command to know, I didn't realize it returned a control's position relative to its window...that would be very handy to move controls around the 'grid' system I have setup. Thanks again, I really appreciate that!
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