Jump to content

_GUICtrlListView_AddItem with image from ImageList


Recommended Posts

I'm trying to create a thumbnail type listview window, but all I'm getting is a black square. Ideas? Replace the JPG path with something on your system to test. My original image is 1920x1200, is that the problem that I haven't resized it?

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

_GDIPlus_Startup()

$hGUI = GUICreate("thumbnails", 400, 400)
$LV = GUICtrlCreateListView("", 2, 2, 396, 396)
GUICtrlSetStyle($LV, $LVS_ICON)
GUISetState()

$hImage = _GUIImageList_Create(56, 56)
$hImg = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\nin_wallpaper4.jpg")
$hGr = _GDIPlus_ImageGetGraphicsContext($hImg)
$hBmp = _GDIPlus_BitmapCreateFromGraphics(56, 56, $hGr)
$hhBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)

_GUIImageList_Add($hImage, $hhBmp)
ConsoleWrite(_GUIImageList_GetImageCount($hImage) & @CRLF)


_GUICtrlListView_SetImageList($LV, $hImage)

_GUICtrlListView_AddItem($LV, "1", 0)

Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

ConsoleWrite(_GDIPlus_GraphicsDispose($hGr) & @CRLF)
ConsoleWrite(_GDIPlus_ImageDispose($hImg) & @CRLF)
ConsoleWrite(_GDIPlus_ImageDispose($hBmp) & @CRLF)
ConsoleWrite(_WinAPI_DeleteObject($hhBmp) & @CRLF)

_GDIPlus_Shutdown()
Edited by wraithdu
Link to comment
Share on other sites

Well I got it after playing around enough. GDI+ is hard to wrap your head around with such bad documentation. There's practically nothing on MSDN, or I'm just looking in the wrong place. Anyway, run this from a directory with some JPG images.

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

_GDIPlus_Startup()

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

Global $files[1] = [0]

$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, 72, 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, 72, $hGraphics1)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBmp)
    
    ; load image
    $hImage = _GDIPlus_ImageLoadFromFile($files[$i])
    $h = 96 / (_GDIPlus_ImageGetWidth($hImage) / _GDIPlus_ImageGetHeight($hImage))
    ; draw the resized image and get handle to HBITMAP
    _GDIPlus_GraphicsDrawImageRect($hGraphics2, $hImage, 0, (72 - $h) / 2, 96, $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

Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

; final cleanup
_GUIImageList_Destroy($hiList)
_GDIPlus_Shutdown()
Edited by wraithdu
Link to comment
Share on other sites

I was not able to get your code to work as posted.

I modified it to get the image width and height outside of _GDIPlus_GraphicsDrawImageRectRect (and added Rect :) )

and then divided by 3 to try and get closer to the focal point. This could be modified more, I am going to play with it.

After that it works great! I can use this in lots of my scripts... Thanks!

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

_GDIPlus_Startup()

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

Global $files[1] = [0]

$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, 72, 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, 72, $hGraphics1)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBmp)
   
    ; load image
    $hImage = _GDIPlus_ImageLoadFromFile($files[$i])
    ; draw the resized image and get handle to HBITMAP
    $hImage_Width = _GDIPlus_ImageGetWidth($hImage)
    $hImage_Height = _GDIPlus_ImageGetHeight($hImage)
    _GDIPlus_GraphicsDrawImageRectRect($hGraphics2, $hImage, $hImage_Width / 3, $hImage_Height / 3, 96, 96 ,0,0,96,96)
    $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

Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

; final cleanup
_GUIImageList_Destroy($hiList)
_GDIPlus_Shutdown()
Link to comment
Share on other sites

Hmmm, not sure why it didn't work for you...what versions of AutoIt3? I'm using 3.2.13.3 beta. Anyway, here's another update that nicely centers the thumbs in a 96x96 square, regardless of orientation (landscape or portrait).

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

Global $files[1] = [0]

_GDIPlus_Startup()

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

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

I am using v3.2.10.0 , I have never used the beta versions. I do not have a good reason but I tend to just wait for

the official release. Looks like I should update to v3.2.12.1, anyway I only noticed the "_GDIPlus_GraphicsDrawImageRect"

is what you used but I had to use "_GDIPlus_GraphicsDrawImageRectRect"

Anyhow... this is great!

Link to comment
Share on other sites

Update to enable tooltips that show the full path of the hovered thumbnail. I think this component is finally done for what I need it for muttley

#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")
GUIRegisterMsg($WM_TIMER, "_MY_WM_TIMER")

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 _MY_WM_TIMER($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $ilParam
    Switch _Timer_GetTimerID($iwParam)
        Case $iHotTimer
            _KillHotTimer()
            
            $idx = _GUICtrlListView_HitTest($hLV)
            If $idx[0] <> -1 Then
                $path = $files[$idx[0] + 1]
                ToolTip($path)
            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func _SetHotTimer()
    $iHotTimer = _Timer_SetTimer($hGUI, 1500, "", $iHotTimer)
    If $iHotTimer == "" Then
        $iHotTimer = _Timer_SetTimer($hGUI, 1500)
    EndIf
    ConsoleWrite("Timer: " & $iHotTimer & @CRLF)
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...