Jump to content

Recommended Posts

Posted (edited)

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
Posted (edited)

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
Posted

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()
Posted

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()
Posted

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!

Posted

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()

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...