Jump to content

Script crashing from _Timer_SetTimer()


Recommended Posts

This script crashes (freezes) once the timer is triggered. However if I convert it to use $WM_TIMER events it works correctly. I have no idea why it's crashing, anyone else have an idea? To use it, run the script in a directory with some JPG images, and mouseover a displayed thumbnail.

Crashing version:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <Timers.au3>

Global $files[1] = [0], $iHotItem = -1, $iHotTimer

_GDIPlus_Startup()

$hGUI = GUICreate("thumbnails", 585, 350)
$LV = GUICtrlCreateListView("", 2, 2, 581, 346)
$hLV = GUICtrlGetHandle($LV)
GUICtrlSetStyle($LV, $LVS_ICON)
_GUICtrlListView_SetExtendedListViewStyle($LV, $LVS_EX_BORDERSELECT)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "_MY_WM_NOTIFY")

Func _MY_WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $iCode, $tNMHDR, $hWndFrom, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $hWndFrom
        Case $hLV
            Switch $iCode
                Case $LVN_BEGINDRAG, $LVN_BEGINRDRAG
                    Return 1
                Case $LVN_HOTTRACK
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    $iItem = DllStructGetData($tInfo, "Item")
                    If $iItem <> $iHotItem Then
                        $iHotItem = $iItem
                        Switch $iItem
                            Case -1
                                ToolTip("")
                                _KillHotTimer()
                            Case Else
                                _SetHotTimer()
                        EndSwitch
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func _SetHotTimer()
    $iHotTimer = _Timer_SetTimer($hGUI, 1500, "_ShowHotTip", $iHotTimer)
    If $iHotTimer == "" Then
        $iHotTimer = _Timer_SetTimer($hGUI, 1500, "_ShowHotTip")
    EndIf
    ConsoleWrite("Timer: " & $iHotTimer & @CRLF)
EndFunc

Func _ShowHotTip()
    _KillHotTimer()
            
    $idx = _GUICtrlListView_HitTest($hLV)
    If $idx[0] <> -1 Then
        $path = $files[$idx[0] + 1]
        ToolTip($path)
    EndIf
EndFunc

Func _KillHotTimer()
    _Timer_KillTimer($hGUI, $iHotTimer)
    $iHotTimer = ""
EndFunc

GUISetCursor(15, 1)

$search = FileFindFirstFile("*.jpg")
If $search <> -1 Then
    While 1
        $file = FileFindNextFile($search)
        If @error Then ExitLoop
        $files[0] += 1
        _ArrayAdd($files, @ScriptDir & "\" & $file)
    WEnd
EndIf

; create image list
$hiList = _GUIImageList_Create(96, 96, 5, 0, 1, 10000)

; create parent graphic object
$hwnd = _WinAPI_GetDesktopWindow()
$hDC = _WinAPI_GetDC($hwnd)
$hGraphics1 = _GDIPlus_GraphicsCreateFromHDC($hDC)
_WinAPI_ReleaseDC($hwnd, $hDC)

For $i = 1 To $files[0]
    ; create resized graphic to place the image into
    $hBmp = _GDIPlus_BitmapCreateFromGraphics(96, 96, $hGraphics1)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBmp)
    
    ; load image
    $hImage = _GDIPlus_ImageLoadFromFile($files[$i])
    $iRatio = _GDIPlus_ImageGetWidth($hImage) / _GDIPlus_ImageGetHeight($hImage)
    $h = 96 / $iRatio
    If $h > 96 Then
        $h = 96
        $y = 0
        $w = 96 * $iRatio
        $x = (96 - $w) / 2
    Else
        $x = 0
        $w = 96
        $y = (96 - $h) / 2
    EndIf
    ; draw the resized image and get handle to HBITMAP
    _GDIPlus_GraphicsDrawImageRect($hGraphics2, $hImage, $x, $y, $w, $h)
    $hHBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)

    ; set new image into list
    _GUIImageList_Add($hiList, $hHBMP)

    ; dispose objects
    _GDIPlus_ImageDispose($hBmp)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageDispose($hImage)
    _WinAPI_DeleteObject($hHBMP)
Next

; dispose parent graphic
_GDIPlus_GraphicsDispose($hGraphics1)

; set image list to control
_GUICtrlListView_SetImageList($LV, $hiList)

For $i = 1 To $files[0]
    _GUICtrlListView_AddItem($LV, StringTrimLeft($files[$i], StringInStr($files[$i], "\", 0, -1)), $i - 1)
Next

GUISetCursor()

Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

; final cleanup
_GUIImageList_Destroy($hiList)
_GDIPlus_Shutdown()
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...