Jump to content

Scrolling GDI Images


InunoTaishou
 Share

Recommended Posts

Hello again! Working on another project I'm using for a game called PokeMMO. Let me first say I am not automating any part of the game. I set the current location and the script will then display the available Pokemon in the area (In a transparent GUI, making the game the parent).

The GUI height is based on the height of the game window, setting the max number of sprites displayed based on that. If there are more sprites than can be displayed I'm trying to make it so when you hover over the top/bottom it will scroll the images up/down, wrapping around in one vertical circle. I started working on it and managed to make it scroll up but it looked messy, didn't work properly, and just didn't seem right...

Maybe it's because it's late, I've been working on this and my simple editor all day, lack of sleep, lack of food, I'm giving up for now but posting this in the hopes someone can point me in the right direction and show me what kind of algorithm I need to use to make it work lol

Here's a link to the images used: http://imgur.com/a/AMtWn

(Images in order should be named Hoothoot.png, Pidgey.png, Rattata.png, and Caterpie.png)

#include <GDIPlus.au3>
#include <Array.au3>
#include <File.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <String.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Color.au3>
#include <Misc.au3>

HotKeySet("+{Esc}", "Close")

AutoItSetOption("GuiOnEventMode", 1)
AutoItSetOption("MustDeclareVars", 1)

Global const $INI_PATH = @ScriptDir & "\PokeTracker.ini"
Global $x
Global $y
Global $max_height = 0
Global $new_size = 0
Global $sprite_width = 56
Global $sprite_height = 56
Global $current_location = "Route 1"
Global $possible_locations
Global $frmTracker
Global $frmResize
Global $lblTitleBar
Global $hWnd_graphics
Global $hWnd_bitmap
Global $hWnd_gdi_buffer
Global $hWnd_family
Global $hWnd_format
Global $hWnd_brush
Global $hWnd_pen
Global $scroll = False
Global $frm_tracker_state = @SW_HIDE
Global $pokemon_count = 4
Global $pokemon_in_location[] = [5, "Pidgey", "Rattata", "Caterpie", "Hoothoot"]
Global $hWnd_dll

WinMain()

Func WinMain()
    $hWnd_dll = DllOpen("user32.dll")
    _GDIPlus_Startup()
    
    ; Create the tracker GUI
    $frmTracker = GUICreate("PokeTracker", $sprite_width, $sprite_height * $pokemon_count, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
    ; Create a label that can be used to drag the tracker
    $lblTitleBar = GUICtrlCreateLabel("", 0, 0, $sprite_width, $sprite_height, -1, $GUI_WS_EX_PARENTDRAG)
    
    GUICtrlSetOnEvent($lblTitleBar, "Resize")
    
    ; Set colors of the GUI and label
    GUISetBkColor(0x000000, $frmTracker)
    GUICtrlSetBkColor($lblTitleBar, $GUI_BKCOLOR_TRANSPARENT)
    ; Set the GUI to transparent
    _WinAPI_SetLayeredWindowAttributes($frmTracker, 0x000000, 255)
    
    GUISetState(@SW_SHOW, $frmTracker)
    
    ; Create GDI handles used for drawing the sprites
    $hWnd_graphics = _GDIPlus_GraphicsCreateFromHWND($frmTracker)
    $hWnd_bitmap = _GDIPlus_BitmapCreateFromGraphics($sprite_width, $sprite_height * $pokemon_count, $hWnd_graphics)
    $hWnd_gdi_buffer = _GDIPlus_ImageGetGraphicsContext($hWnd_bitmap)
    
    ; Set the GDI objects to smooth
    _GDIPlus_GraphicsSetSmoothingMode($hWnd_gdi_buffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hWnd_graphics, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
    
    ; Create GDI Handles used for writing the Strings
    $hWnd_format = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hWnd_format, 1)
    $hWnd_brush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $hWnd_pen = _GDIPlus_PenCreate(0xFF1F1F1F, 1)
    $hWnd_family = _GDIPlus_FontFamilyCreate("Segoe UI")
    
    UpdateTracker()
    
    While (True)
        Sleep(100)
    WEnd
EndFunc   ;==>WinMain

Func Close()
    ; Free GDI Resources
    _GDIPlus_StringFormatDispose($hWnd_format)
    _GDIPlus_BrushDispose($hWnd_brush)
    _GDIPlus_FontFamilyDispose($hWnd_family)
    _GDIPlus_PenDispose($hWnd_pen)
    _GDIPlus_BitmapDispose($hWnd_bitmap)
    _GDIPlus_GraphicsDispose($hWnd_graphics)
    _GDIPlus_Shutdown()
    
    ; Delete the current location file
    FileDelete(@ScriptDir & "\Images\Current Location.png")
    
    Exit (0)
EndFunc   ;==>Close

Func Resize()
    If (Not _IsPressed(11, $hWnd_dll)) Then Return
    Local $abscoord_tracker = WinGetPos($frmTracker)
    $frmResize = GUICreate("", $abscoord_tracker[2] - 14, $abscoord_tracker[3], $abscoord_tracker[0], $abscoord_tracker[1], $WS_SIZEBOX, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    
    GUISetOnEvent($GUI_EVENT_CLOSE, "SetTrackerSize", $frmResize)
    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    
    GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")
    GUISetBkColor(0x000000, $frmResize)
    ;_WinAPI_SetLayeredWindowAttributes($frmResize, 0x000000, 255)
    
    GUISetState(@SW_SHOW, $frmResize)
    GUISetState(@SW_DISABLE, $frmTracker)
    GUISetState(@SW_LOCK, $frmTracker)
EndFunc

Func SetTrackerSize()
    Local $abscoord_resize = WinGetPos($frmResize)
    Local $abscoord_tracker = WinGetPos($frmTracker)
    
    GUIDelete($frmResize)
    $frmResize = Null
    
    $new_size = $abscoord_resize[3]
    $max_height = $new_size
    
    GUISetState(@SW_ENABLE, $frmTracker)
    GUISetState(@SW_UNLOCK, $frmTracker)
    
    WinMove($frmTracker, "", $abscoord_resize[0], $abscoord_resize[1], $abscoord_resize[2], $new_size)
    GUICtrlSetPos($lblTitleBar, 0, 0, $sprite_width, $new_size)
    
    _GDIPlus_GraphicsDispose($hWnd_graphics)
    _GDIPlus_BitmapDispose($hWnd_bitmap)
    
    $hWnd_graphics = _GDIPlus_GraphicsCreateFromHWND($frmTracker)
    $hWnd_bitmap = _GDIPlus_BitmapCreateFromGraphics($sprite_width, $new_size, $hWnd_graphics)
    $hWnd_gdi_buffer = _GDIPlus_ImageGetGraphicsContext($hWnd_bitmap)
    
    _GDIPlus_GraphicsSetSmoothingMode($hWnd_gdi_buffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hWnd_graphics, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
    
    UpdateTracker()
EndFunc

Func UpdateTracker()
    _GDIPlus_GraphicsClear($hWnd_gdi_buffer, 0x00000000)
    
    If ($pokemon_count >= 1 and IsArray($pokemon_in_location)) Then
        For $i = 1 To $pokemon_count
            ; Split the data for the pokemon_in_location
            Local $pokemon_data = StringSplit($pokemon_in_location[$i], ',')
            ; Rectangle for the area of the sprite and string
            Local $rect_pokemon_image[4] = [0, ($i - 1) * $sprite_height, $sprite_width, $sprite_height]
            
            ; If there is a Pokemon name in the $pokemon_data array ($pokemon_data[1] = Pokemon Name)
            If ($pokemon_data[0] >= 1) Then
                Local $hWnd_image = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\Sprites\" & $pokemon_data[1] & ".png")
                
                _GDIPlus_GraphicsDrawImageRect($hWnd_gdi_buffer, $hWnd_image, $rect_pokemon_image[0], $rect_pokemon_image[1], $rect_pokemon_image[2], $rect_pokemon_image[3])
                _GDIPlus_ImageDispose($hWnd_image)
            EndIf
            
            ; If there are 2 pieces of data for the Pokemon [1] = Pokemon name, [2] = Rarity
            If ($pokemon_data[0] = 2) Then
                Local $hWnd_path = _GDIPlus_PathCreate()
                Local $rect_layout = _GDIPlus_RectFCreate($rect_pokemon_image[0], $rect_pokemon_image[1], $rect_pokemon_image[2], $rect_pokemon_image[3] - ($sprite_height / 2))
                
                _GDIPlus_PathAddString($hWnd_path, $pokemon_data[2], $rect_layout, $hWnd_family, 0, 14, $hWnd_format)
                _GDIPlus_GraphicsDrawPath($hWnd_gdi_buffer, $hWnd_path, $hWnd_pen)
                _GDIPlus_GraphicsFillPath($hWnd_gdi_buffer, $hWnd_path, $hWnd_brush)
                _GDIPlus_GraphicsFillPath($hWnd_gdi_buffer, $hWnd_path, $hWnd_brush)
                _GDIPlus_PathDispose($hWnd_path)
            EndIf
        Next
    EndIf
    
    _GDIPlus_GraphicsDrawImage($hWnd_graphics, $hWnd_bitmap, 0, 0)
    
    Return $GUI_RUNDEFMSG
EndFunc   ;==>UpdateTracker

Func WM_PAINT($hWndFrom, $iMsg, $wParam, $lParam)
    Return UpdateTracker()
EndFunc   ;==>WM_PAINT

Func WM_WINDOWPOSCHANGING($hWndFrom, $iMsg, $wParam, $lParam)
    Local $abscoord_pokemmo = WinGetPos("[Class:LWJGL]")
    
    If (Not IsArray($abscoord_pokemmo)) Then Return $GUI_RUNDEFMSG
    
    Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
    
    Local $iLeft = DllStructGetData($stWinPos, 3)
    Local $iTop = DllStructGetData($stWinPos, 4)
    Local $iWidth = DllStructGetData($stWinPos, 5)
    Local $iHeight = DllStructGetData($stWinPos, 6)
    
    If ($iHeight > $abscoord_pokemmo[3] + 64) Then DllStructSetData($stWinPos, 6, $abscoord_pokemmo[3] - 64)
    
    If $iLeft < $abscoord_pokemmo[0] + 8 Then DllStructSetData($stWinPos, 3, $abscoord_pokemmo[0] + 8)
    If $iTop < $abscoord_pokemmo[1] + 30 Then DllStructSetData($stWinPos, 4, $abscoord_pokemmo[1] + 30)
    If $iLeft > $abscoord_pokemmo[0] + $abscoord_pokemmo[2] - $iWidth - 8 Then DllStructSetData($stWinPos, 3, $abscoord_pokemmo[0] + $abscoord_pokemmo[2] - $iWidth - 8)
    If $iTop > $abscoord_pokemmo[1] + $abscoord_pokemmo[3] - $iHeight - 8 Then DllStructSetData($stWinPos, 4, $abscoord_pokemmo[1] + $abscoord_pokemmo[3] - $iHeight - 8)
    
    If ($iLeft < $abscoord_pokemmo[0] + 167 and $iTop < $abscoord_pokemmo[1] + 64) Then
        If ($iTop < $abscoord_pokemmo[1] + 64) Then DllStructSetData($stWinPos, 4, $abscoord_pokemmo[1] + 64)
    EndIf
EndFunc   ;==>WM_WINDOWPOSCHANGING

; Not used, was going to use it for a second GUI that would dictate the size of the buffer to draw (how many rows/columns to draw and each Pokemon)
Func WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
    Local $abscoord_pokemmo = WinGetPos("[Class:LWJGL]")
    Local $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    
    DllStructSetData($tagMaxinfo,  7, $sprite_width) ; min width
    DllStructSetData($tagMaxinfo,  8, $sprite_height)  ; min height
    DllStructSetData($tagMaxinfo,  9, $sprite_width) ; max width
    DllStructSetData($tagMaxinfo,  10, $max_height)  ; max height
    
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    Local $abscoord_mouse = MouseGetPos()
    Local $abscoord_tracker = WinGetPos($frmTracker)
    Local $mouse_in_point
    
    If (Not IsArray($abscoord_tracker)) Then
        Return $GUI_RUNDEFMSG
    EndIf
    
    If (_WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1], $abscoord_tracker[0] + $abscoord_tracker[2], $abscoord_tracker[1] + $sprite_height)) Then
        $mouse_in_point = True
        While ($mouse_in_point)
            $abscoord_mouse = MouseGetPos()
            $abscoord_tracker = WinGetPos($frmTracker)
            $mouse_in_point = _WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1], $abscoord_tracker[0] + $abscoord_tracker[2], $abscoord_tracker[1] + $sprite_height)
        Wend
    ElseIf (_WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1] + $abscoord_tracker[3] - $sprite_height, $abscoord_tracker[0] + $abscoord_tracker[1], $abscoord_tracker[1] + $abscoord_tracker[3])) Then
        ToolTip("bottom", 0, 0)
    Else
        ToolTip("")
    EndIf
    
    Return $GUI_RUNDEFMSG
EndFunc

 

Link to comment
Share on other sites

Lack of sleep, I swear.... Figured it out in 15 mins when I woke up this morning.

Fortunately, since I'm  using an array to hold the values of what to draw my solution was to just move the first item to the last, or the last item to the first (depending on where I start drawing)

(Kind of dirty right now but I'll go through and clean up everything when I'm done)

It's pretty smooth, occasional flicker but I haven't found a solution for something like this because I do have to clear the main graphic since I'm using a transparent background.

The new WM_MOUSEMOVE function, tracks the mouse and if the pointer is inside the top or bottom of the GUI, scroll. Adjusting the $gdi_start_y accordingly.

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    Local $abscoord_mouse = MouseGetPos()
    Local $abscoord_tracker = WinGetPos($frmTracker)
    Local $mouse_in_point = True
    Local $scroll_speed = 2
    
    If (Not IsArray($abscoord_tracker)) Then
        Return $GUI_RUNDEFMSG
    EndIf
    
    If (_WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1], $abscoord_tracker[0] + $abscoord_tracker[2], $abscoord_tracker[1] + ($sprite_height / 2))) Then
        While ($mouse_in_point)
            $gdi_start_y -= $scroll_speed
            
            If ($gdi_start_y < ($sprite_height * -1)) Then
                $gdi_start_y = 0
                ArrayMoveValue($pokemon_in_location, 1, $pokemon_count)
            EndIf
            
            UpdateTracker(True)
            
            Sleep(10)
            
            $abscoord_mouse = MouseGetPos()
            $abscoord_tracker = WinGetPos($frmTracker)
            $mouse_in_point = _WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1], $abscoord_tracker[0] + $abscoord_tracker[2], $abscoord_tracker[1] + ($sprite_height / 2))
        Wend
    ElseIf (_WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1] + $abscoord_tracker[3] - ($sprite_height / 2), $abscoord_tracker[0] + $abscoord_tracker[1], $abscoord_tracker[1] + $abscoord_tracker[3])) Then
        While ($mouse_in_point)
            $gdi_start_y += $scroll_speed
            
            If ($gdi_start_y > $sprite_height) Then
                $gdi_start_y = 0
                ArrayMoveValue($pokemon_in_location, $pokemon_count, 1)
            EndIf
            
            UpdateTracker(True)
            
            Sleep(1)
            
            $abscoord_mouse = MouseGetPos()
            $abscoord_tracker = WinGetPos($frmTracker)
            $mouse_in_point = _WinAPI_PtInRectEx($abscoord_mouse[0], $abscoord_mouse[1], $abscoord_tracker[0], $abscoord_tracker[1] + $abscoord_tracker[3] - ($sprite_height / 2), $abscoord_tracker[0] + $abscoord_tracker[1], $abscoord_tracker[1] + $abscoord_tracker[3])
        Wend
    EndIf
    
    Return $GUI_RUNDEFMSG
EndFunc

And the ArrayMoveValue

Func ArrayMoveValue($aArray, Const $index_from, Const $index_to)
    Local const $tmp_val = $pokemon_in_location[$index_from]
    
    $aArray = $pokemon_in_location
    
    _ArrayDelete($aArray, $index_from)
    
    If ($index_to = $pokemon_count) Then
        _ArrayAdd($aArray, $tmp_val)
    Else
        _ArrayInsert($aArray, $index_to, $tmp_val)
    EndIf
    
    $pokemon_in_location = $aArray
EndFunc

 

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

×
×
  • Create New...