footswitch

Custom ListView - icons / checkboxes / multiline / edit in place

27 posts in this topic

#1 ·  Posted (edited)

EDIT: Along the following posts you will encounter a series of examples, tricks and workarounds, showing you how to accomplish:

- custom fonts, font colors and row colors (selected/unselected)

- icons / checkboxes on items and subitems

- multiline rows in listviews

- themed listviews

Performance-wise, rover's example in post #17 is very optimized.

Working examples of Edit in Place are postponed for now.

________________________

Hi guys,

I'm trying to find some example code of a List with several sub-items (columns), with the possibility of including icons (preferably embedded in the compiled executable) and more than one checkbox per row.

A while back (maybe a year or so), I came across an example of a ListView that had all this customization: icons / colored boxes, checkboxes and edit in place.

But I'm not entirely sure if it had all three combined.

I mean, I'm not even sure if the control was actually a ListView, but it surely resembled one.

Maybe I'm just going insane and I THINK I saw it, because I've been searching for 2 hours and haven't found it yet.

Anyway, if this description reminds you of a post with such code, I would deeply appreciate any links you feel like sharing.

If not, well, I'll just have to pursue another route.

Thanks in advance for your time.

footswitch

edited 2012-04-10: updated topic title

Edited by footswitch

Share this post


Link to post
Share on other sites



Share this post


Link to post
Share on other sites

Yup. A good start indeed. Still don't understand even half of it ;)

The embedding technique is pretty awesome and also an eye opener for me. Up until now I was using exclusively icons.

Many thanks. I guess I'll be spending my free time around these UDFs :)

Just a little question, if you don't mind. Can you tell why the checkboxes shift one or two pixels down when the row is selected? This happens regardless of their state (checked or unchecked).

(Windows XP Pro 32-bit, don't know if the behavior persists on other OS)

Thanks again.

footswitch


Share this post


Link to post
Share on other sites

You're right, I've noticed the one pixel gap before and forgot about it. It seems there's a difference in positioning between XP and Vista+. Not sure what the reason is and the proper handling would be, but these this work-around lines seem to do the job:

Local $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+

_LV_Checkboxes.zip

Share this post


Link to post
Share on other sites

Thanks, your fix works nicely.

I ended up setting that as a Global variable on the beginning of the script, since the calculation only needs to occur once.

Right now I'm trying to get this to work together with the Extended Style $LVS_OWNERDRAWFIXED.

It seems like one overrides the other, but I'm still unsure.

A lot of this code is beyond my knowledge so I'm just trying to figure out things as I go.


Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

For embedding/using icons in compiled EXE script use

#AutoIt3Wrapper_Res_Icon_Add=C:Program FilesAutoIt3Iconsau3.ico
#AutoIt3Wrapper_Res_Icon_Add=C:Program FilesAutoIt3Iconssecond_ico.ico

and for loading

_WinAPI_GetModuleHandle("")

_WinAPI_LoadImage() + IMAGE_ICON type as parameter or LoadIcon API function

or you can use GUICtrlSetImage() + @ScriptFullPath

You can look at my Resource to some similar using of resources. Icons are so simple that my Resources UDF is not needed.

Edited by Zedna
1 person likes this

Share this post


Link to post
Share on other sites

@Zedna,

#AutoIt3Wrapper_Res_Icon_Add

that's what I've been doing up until now. At this point we can agree that there are several ways to skin this cat.

I really appreciate your help guys, but it seems that it doesn't do what I imagined it would.

I just can't get it to play along with ownerdraw.

I'll post an example script as soon as I can, to demonstrate what I'm talking about.

It's just taking a bit longer than I expected because I'm still cleaning up the code. (plus I need to get all the necessary functions in a single file)

Thanks again.


Share this post


Link to post
Share on other sites

So I ended up reusing KaFu's example to reproduce the problem:

(you need WinAPIEx.au3 : )

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Array.au3>
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

;#include <APIConstants.au3>
#include <WinAPIEx.au3> ; from http://www.autoitscript.com/forum/topic/98712-winapiex-udf/

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1

; ####################################
; adjustment of the icon positioning, according to windows version
Global $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+
; ####################################

_GDIPlus_Startup()

$hGUI = GUICreate("ListView Set Item State", 400, 300)

$cButton_CheckAll = GUICtrlCreateButton("Check All", 10, 275, 100, 20)
$cButton_UncheckAll = GUICtrlCreateButton("UnCheck All", 120, 275, 100, 20)
$cButton_StatesToArray = GUICtrlCreateButton("States to Array", 230, 275, 100, 20)

; comment one of the lines below to reproduce each example (don't leave both uncommented!)
; EXAMPLE 1 (WITH OWNERDRAW):
$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS))
; EXAMPLE 2 (WITHOUT OWNERDRAW):
;$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS))

$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))

$hIml_Listview = _GUIImageList_Create(16, 16, 5, 3)

$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Unchecked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Checked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

_GUICtrlListView_SetImageList($hListView, $hIml_Listview, 1)

; Add columns
For $i=1 To 3
    _GUICtrlListView_AddColumn($hListView, "Column " & $i, 120)
Next

; Add items
For $row = 1 To 3
    _GUICtrlListView_AddItem($hListView, "Row " & $row & ": Col 1", 0)
    _GUICtrlListView_AddSubItem($hListView, $row - 1, "Row " & $row & ": Col 2", 1, 0)
    _GUICtrlListView_AddSubItem($hListView, $row - 1, "Row " & $row & ": Col 3", 2, 0)
Next


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()

; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $cButton_CheckAll
            _LV_ImgCheckboxes_CheckAll($hListView)

        Case $cButton_UncheckAll
            _LV_ImgCheckboxes_UncheckAll($hListView)

        Case $cButton_StatesToArray
            $aLVStates = _LV_ImgCheckboxes_StatesToArray($hListView)
            _ArrayDisplay($aLVStates)

    EndSwitch
WEnd

GUIDelete()
_GUIImageList_Destroy($hIml_Listview)
_GDIPlus_Shutdown()
Exit

Func _LV_ImgCheckboxes_CheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 1, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_CheckAll

Func _LV_ImgCheckboxes_UncheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 0, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_UncheckAll

Func _LV_ImgCheckboxes_StatesToArray($hWnd)
    Local $iColumns = _GUICtrlListView_GetColumnCount($hWnd)
    If $iColumns = 0 Then Return SetError(1)
    Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
    If $iItems = 0 Then Return SetError(2)
    Local $aStates[$iItems][$iColumns]
    For $i = 0 To $iItems - 1
        For $y = 0 To $iColumns - 1
            $aStates[$i][$y] = _GUICtrlListView_GetItemImage($hWnd, $i, $y)
        Next
    Next
    Return $aStates
EndFunc   ;==>_LV_ImgCheckboxes_StatesToArray

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $nNotifyCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hListView
            Switch $nNotifyCode
                Case $NM_CUSTOMDRAW
                    ; http://www.autoitscript.com/forum/topic/123757-focushighlight-a-certain-item-in-a-listview/page__view__findpost__p__859598
                    ; Mat & Siao

                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG ; Not in details mode

                    Local $tCustDraw, $iDrawStage, $iItem, $iSubitem, $hDC, $tRect, $iColor1, $iColor2, $iColor3

                    $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage')

                    Switch $iDrawStage
                        Case $CDDS_PREPAINT
                            Return $CDRF_NOTIFYITEMDRAW
                        Case $CDDS_ITEMPREPAINT
                            Return $CDRF_NOTIFYSUBITEMDRAW
                        Case $CDDS_ITEMPOSTPAINT
                            ; Not handled
                        Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                            Local $iItem = DllStructGetData($tCustDraw, 'dwItemSpec')
                            Local $iSubitem = DllStructGetData($tCustDraw, 'iSubItem')

                            If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then ; Item to draw is selected
                                Local $hDC = _WinAPI_GetDC($hWndFrom)
                                Local $tRect = DllStructCreate($tagRECT)
                                Local $pRect = DllStructGetPtr($tRect)

                                ; We draw the background when we draw the first item.
                                If $iSubitem = 0 Then
                                    ; We must send the message as we want to use the struct. _GUICtrlListView_GetSubItemRect returns an array.
                                    _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, $pRect)
                                    DllStructSetData($tRect, "Left", 0)
                                    _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), _WinAPI_GetStockObject(0)) ; NULL_PEN to overwrite default highlighting
                                EndIf

                                DllStructSetData($tRect, "Left", 2)
                                DllStructSetData($tRect, "Top", $iSubitem)
                                _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect))
                                Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem)
                                _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; It uses the background drawn for the first item.

                                ; Select the font we want to use
                                _WinAPI_SelectObject($hDC, _SendMessage($hWndFrom, $WM_GETFONT))

                                Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem))

                                If $iSubitem = 0 Then
                                    _WinAPI_DrawIconEx($hDC, DllStructGetData($tRect, "Left") - 16, DllStructGetData($tRect, "Top") + $iAdjustV, $hIcon, 16, 16)
                                    DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 2)
                                Else
                                    _WinAPI_DrawIconEx($hDC, DllStructGetData($tRect, "Left"), DllStructGetData($tRect, "Top") + $iAdjustV, $hIcon, 16, 16)
                                    DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 6 + 18)
                                EndIf

                                _GUIImageList_DestroyIcon($hIcon)
                                _WinAPI_DrawText($hDC, $sText, $tRect, BitOR($DT_VCENTER, $DT_END_ELLIPSIS, $DT_SINGLELINE))

                                _WinAPI_ReleaseDC($hWndFrom, $hDC)

                                Return $CDRF_SKIPDEFAULT ; Don't do default processing

                            EndIf

                            Return $CDRF_NEWFONT ; Let the system do the drawing for non-selected items
                        Case BitOR($CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM)
                            ; Not handled
                    EndSwitch

                Case $NM_CLICK

                    Local $tINFO = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iItem = DllStructGetData($tINFO, "Index")
                    Local $iSubitem = DllStructGetData($tINFO, "SubItem")
                    _GUICtrlListView_SetItemImage($hListView, $iItem, Not _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem), $iSubitem)

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC

    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "hwnd hDC;" & _
            "int itmRect[4];" & _
            "dword itmData" _
            , $lParam)

    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG

    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")

    Local $aDefaultVariables[9] = [$tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC]
    Switch $cID ; will look for ControlID, not window handle.
        Case $cListView
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    ConsoleWrite("test"&@CRLF)
                    Local $aRowColors[2] = [0xFDFDFD, 0xEEDDBB]
                    Local $aRectMargins[4] = [6, -1, 0, 0]
                    Local $aTextFormatting[3] = [BitOR($DT_VCENTER, $DT_SINGLELINE), _
                    BitOR($DT_VCENTER, $DT_SINGLELINE), _
                    BitOR($DT_VCENTER, $DT_SINGLELINE)]
                    __WM_DRAWITEM_ListView($hListView, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

Func __WM_DRAWITEM_ListView(ByRef $hListView, ByRef $aDefaultVariables, ByRef $aRowColors, ByRef $aRectMargins, ByRef $aTextFormatting)
    Local $iSubItemCount = _GUICtrlListView_GetColumnCount($hListView)
    If UBound($aTextFormatting) < $iSubItemCount Then
        ConsoleWrite("!> Error: invalid parameters in __WM_DRAWITEM_ListView()"&@CRLF)
        Return
    EndIf

    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC

    $tagDRAWITEMSTRUCT = $aDefaultVariables[0]
    $iBrushColor = $aDefaultVariables[1]
    $cID = $aDefaultVariables[2]
    $itmID = $aDefaultVariables[3]
    $itmAction = $aDefaultVariables[4]
    $itmState = $aDefaultVariables[5]
    $hItm = $aDefaultVariables[6]
    $hDC = $aDefaultVariables[7]


    If _GUICtrlListView_GetItemSelected($hListView, $itmID) Then
        $iBrushColor = $aRowColors[1]
    Else
        $iBrushColor = $aRowColors[0]
    EndIf

    ; create a brush with the desired color:
    Local $aBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)

    ; get the rectangle for the whole row and fill it:
    Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
    DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 0, 1) ; +0 is the left margin
    _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0])

    ; draw the text in each subitem
    For $i = 0 To $iSubItemCount - 1
        ; get subitem text:
        Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, $i)
        ; get subitem coordinates for drawing its respective text:
        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, $i)
        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
        ; pass the coordinates to a DLL struct:
        Local $iSubItmRect = DllStructCreate("int[4]")
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + $aRectMargins[0], 1) ; left margin
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] + $aRectMargins[1], 2) ; upper margin
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[2] + $aRectMargins[2], 3) ; right margin
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[3] + $aRectMargins[3], 4) ; bottom margin
        Local $tRect = DllStructGetPtr($iSubItmRect)
        If $aTextFormatting[$i] = -1 Then
            ; do nothing (don't draw)
        Else
            _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
        EndIf
    Next
EndFunc







; Based on File to Base64 String Code Generator
; by UEZ
; http://www.autoitscript.com/forum/topic/134350-file-to-base64-string-code-generator-v103-build-2011-11-21/

;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:        Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:          $bImage:    the binary string which contains any valid image which is supported by GDI+
; Optional:          $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:              hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;                      Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown()
;
; Requirement(s):      GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Return Value(s):    Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format),
;                      Error: 0
; Error codes:        1: $bImage is not a binary string
;                      2: unable to create stream on HGlobal
;                      3: unable to create bitmap from stream
;
; Author(s):            UEZ
; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines and
;                      Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Version:            v0.97 Build 2012-01-04 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then SetError(2, 0, 0)
    Local Const $hStream = $aResult[3]
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    If @error Then SetError(3, 0, 0)
    Local Const $hBitmap = $aResult[2]
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem

Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
    Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
    $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
    If (@error) Or ($Ret[0]) Then Return 0
    $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $pBits = DllStructGetData($tData, 'Scan0')
    If Not $pBits Then Return 0
    $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
    DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 2, $Ret[2])
    DllStructSetData($tBIHDR, 3, $Ret[3])
    DllStructSetData($tBIHDR, 4, 1)
    DllStructSetData($tBIHDR, 5, 32)
    DllStructSetData($tBIHDR, 6, 0)
    $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    If (Not @error) And ($hResult[0]) Then
        DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
        $hResult = $hResult[0]
    Else
        $hResult = 0
    EndIf
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData)
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap

Func _Decompress_Binary_String_to_Bitmap($Base64String)
    $Base64String = Binary($Base64String)
    Local $iSize_Source = BinaryLen($Base64String)
    Local $pBuffer_Source = _WinAPI_CreateBuffer($iSize_Source)
    DllStructSetData(DllStructCreate('byte[' & $iSize_Source & ']', $pBuffer_Source), 1, $Base64String)
    Local $pBuffer_Decompress = _WinAPI_CreateBuffer(8388608)
    Local $Size_Decompressed = _WinAPI_DecompressBuffer($pBuffer_Decompress, 8388608, $pBuffer_Source, $iSize_Source)
    Local $b_Result = Binary(DllStructGetData(DllStructCreate('byte[' & $Size_Decompressed & ']', $pBuffer_Decompress), 1))
    _WinAPI_FreeMemory($pBuffer_Source)
    _WinAPI_FreeMemory($pBuffer_Decompress)
    Return $b_Result
EndFunc   ;==>_Decompress_Binary_String_to_Bitmap

Func _Icon_Image_Checkbox_Unchecked()
    Local $Base64String
    $Base64String &= '7rBIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAANfc3ADZ3t4AANvg4ADe4uIAAOLl5QDl6OgAAOns7ADs7+8AAO/x8QDx8/MAAPT19QD29/cAAPj5+QD6+/sAAPz9/QD+/v7wAP///xNc/wB/AD8A/z8APwA/AD8APwA/AD8ACAAb4HYLAAEJAOEBCgsMAA0ODxAREhISbeIBCQcC4gEIBwLiAQfbBwLiAQYHAuIBBQcC4gG2BAcC4gEDBwLiAQIHAv/jAQcC5AEGAuIB7BceAOCfHgN/AG0A4QZhAA=='
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Unchecked

Func _Icon_Image_Checkbox_Checked()
    Local $Base64String
    $Base64String &= 'z7BIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAAISEhADe3t5AAN7n5wDnAQbvCO8A7wEG9/cA9/EABv///xN4/wE/AD8A/z8APwA/AD8AHwAMAOB6CwAGAQkA4QEHCAkJCR4KAgDjAQcC5AEHCAKDAwLiAQYHBwICAwI54gEFBsABAwLjAQUCxgIkBOIBBAUCRQbjAVgEBQUCAuQBAwUCCPPkAQUCBwjkAQYC4gHsF3seAOCfA38AbQDhBmEA'
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Checked

Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

As you can see, I can only display one of the effects: either OWNERDRAW or the other 'dwDrawStage' method.

When I hoped it would be possible to blend them together.

Have you guys ever tried something like this?


Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Looks good on Win7 ;)...

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Array.au3>
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

;#include <APIConstants.au3>
#include <WinAPIEx.au3> ; from http://www.autoitscript.com/forum/topic/98712-winapiex-udf/

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1

; ####################################
; adjustment of the icon positioning, according to windows version
Global $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+
; ####################################

_GDIPlus_Startup()

$hGUI = GUICreate("ListView Set Item State", 400, 300)

$cButton_CheckAll = GUICtrlCreateButton("Check All", 10, 275, 100, 20)
$cButton_UncheckAll = GUICtrlCreateButton("UnCheck All", 120, 275, 100, 20)
$cButton_StatesToArray = GUICtrlCreateButton("States to Array", 230, 275, 100, 20)

; comment one of the lines below to reproduce each example (don't leave both uncommented!)
; EXAMPLE 1 (WITH OWNERDRAW):
$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS))
; EXAMPLE 2 (WITHOUT OWNERDRAW):
;$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS))

$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))

$hIml_Listview = _GUIImageList_Create(16, 16, 5, 3)

$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Unchecked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Checked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

_GUICtrlListView_SetImageList($hListView, $hIml_Listview, 1)

; Add columns
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView, "Column " & $i, 120)
Next

; Add items
For $row = 1 To 3
    _GUICtrlListView_AddItem($hListView, "Row " & $row & ": Col 1", 0)
    _GUICtrlListView_AddSubItem($hListView, $row - 1, "Row " & $row & ": Col 2", 1, 0)
    _GUICtrlListView_AddSubItem($hListView, $row - 1, "Row " & $row & ": Col 3", 2, 0)
Next


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()

; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $cButton_CheckAll
            _LV_ImgCheckboxes_CheckAll($hListView)

        Case $cButton_UncheckAll
            _LV_ImgCheckboxes_UncheckAll($hListView)

        Case $cButton_StatesToArray
            $aLVStates = _LV_ImgCheckboxes_StatesToArray($hListView)
            _ArrayDisplay($aLVStates)

    EndSwitch
WEnd

GUIDelete()
_GUIImageList_Destroy($hIml_Listview)
_GDIPlus_Shutdown()
Exit

Func _LV_ImgCheckboxes_CheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 1, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_CheckAll

Func _LV_ImgCheckboxes_UncheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 0, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_UncheckAll

Func _LV_ImgCheckboxes_StatesToArray($hWnd)
    Local $iColumns = _GUICtrlListView_GetColumnCount($hWnd)
    If $iColumns = 0 Then Return SetError(1)
    Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
    If $iItems = 0 Then Return SetError(2)
    Local $aStates[$iItems][$iColumns]
    For $i = 0 To $iItems - 1
        For $y = 0 To $iColumns - 1
            $aStates[$i][$y] = _GUICtrlListView_GetItemImage($hWnd, $i, $y)
        Next
    Next
    Return $aStates
EndFunc   ;==>_LV_ImgCheckboxes_StatesToArray

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $nNotifyCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hListView
            Switch $nNotifyCode
                #cs
                    Case $NM_CUSTOMDRAW
                    ConsoleWrite(TimerInit() & @TAB & "$NM_CUSTOMDRAW" & @CRLF)
                    ; http://www.autoitscript.com/forum/topic/...listview/page__view__findpost_
                    ; Mat & Siao
                    
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG ; Not in details mode
                    
                    Local $tCustDraw, $iDrawStage, $iItem, $iSubitem, $hDC, $tRect, $iColor1, $iColor2, $iColor3
                    
                    $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage')
                    
                    Switch $iDrawStage
                    Case $CDDS_PREPAINT
                    Return $CDRF_NOTIFYITEMDRAW
                    Case $CDDS_ITEMPREPAINT
                    Return $CDRF_NOTIFYSUBITEMDRAW
                    Case $CDDS_ITEMPOSTPAINT
                    ; Not handled
                    Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                    
                    Local $iItem = DllStructGetData($tCustDraw, 'dwItemSpec')
                    Local $iSubitem = DllStructGetData($tCustDraw, 'iSubItem')
                    
                    If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then ; Item to draw is selected
                    Local $hDC = _WinAPI_GetDC($hWndFrom)
                    Local $tRect = DllStructCreate($tagRECT)
                    Local $pRect = DllStructGetPtr($tRect)
                    
                    ; We draw the background when we draw the first item.
                    If $iSubitem = 0 Then
                    ; We must send the message as we want to use the struct. _GUICtrlListView_GetSubItemRect returns an array.
                    _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, $pRect)
                    DllStructSetData($tRect, "Left", 0)
                    _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), _WinAPI_GetStockObject(0)) ; NULL_PEN to overwrite default highlighting
                    EndIf
                    
                    DllStructSetData($tRect, "Left", 2)
                    DllStructSetData($tRect, "Top", $iSubitem)
                    _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect))
                    Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem)
                    _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; It uses the background drawn for the first item.
                    
                    ; Select the font we want to use
                    _WinAPI_SelectObject($hDC, _SendMessage($hWndFrom, $WM_GETFONT))
                    
                    Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem))
                    
                    If $iSubitem = 0 Then
                    _WinAPI_DrawIconEx($hDC, DllStructGetData($tRect, "Left") - 16, DllStructGetData($tRect, "Top") + $iAdjustV, $hIcon, 16, 16)
                    DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 2)
                    Else
                    _WinAPI_DrawIconEx($hDC, DllStructGetData($tRect, "Left"), DllStructGetData($tRect, "Top") + $iAdjustV, $hIcon, 16, 16)
                    DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 6 + 18)
                    EndIf
                    
                    _GUIImageList_DestroyIcon($hIcon)
                    _WinAPI_DrawText($hDC, $sText, $tRect, BitOR($DT_VCENTER, $DT_END_ELLIPSIS, $DT_SINGLELINE))
                    
                    _WinAPI_ReleaseDC($hWndFrom, $hDC)
                    
                    Return $CDRF_SKIPDEFAULT ; Don't do default processing
                    
                    EndIf
                    
                    Return $CDRF_NEWFONT ; Let the system do the drawing for non-selected items
                    Case BitOR($CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM)
                    ; Not handled
                    EndSwitch
                #ce

                Case $NM_CLICK

                    Local $tINFO = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iItem = DllStructGetData($tINFO, "Index")
                    Local $iSubitem = DllStructGetData($tINFO, "SubItem")
                    _GUICtrlListView_SetItemImage($hListView, $iItem, Not _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem), $iSubitem)

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC

    ;ConsoleWrite(TimerInit() & @TAB & "WM_DRAWITEM" & @CRLF)

    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "hwnd hDC;" & _
            "int itmRect[4];" & _
            "dword itmData" _
            , $lParam)

    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG

    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")

    Local $aDefaultVariables[9] = [$tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC]
    Switch $cID ; will look for ControlID, not window handle.
        Case $cListView
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    ConsoleWrite("test" & @CRLF)
                    Local $aRowColors[2] = [0xFDFDFD, 0xEEDDBB]
                    Local $aRectMargins[4] = [6, -1, 0, 0]
                    Local $aTextFormatting[3] = [BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE)]
                    __WM_DRAWITEM_ListView($hListView, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)



            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

Func __WM_DRAWITEM_ListView(ByRef $hListView, ByRef $aDefaultVariables, ByRef $aRowColors, ByRef $aRectMargins, ByRef $aTextFormatting)
    Local $iSubItemCount = _GUICtrlListView_GetColumnCount($hListView)
    If UBound($aTextFormatting) < $iSubItemCount Then
        ConsoleWrite("!> Error: invalid parameters in __WM_DRAWITEM_ListView()" & @CRLF)
        Return
    EndIf

    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC

    $tagDRAWITEMSTRUCT = $aDefaultVariables[0]
    $iBrushColor = $aDefaultVariables[1]
    $cID = $aDefaultVariables[2]
    $itmID = $aDefaultVariables[3]
    $itmAction = $aDefaultVariables[4]
    $itmState = $aDefaultVariables[5]
    $hItm = $aDefaultVariables[6]
    $hDC = $aDefaultVariables[7]

    If _GUICtrlListView_GetItemSelected($hListView, $itmID) Then
        $iBrushColor = $aRowColors[1]
    Else
        $iBrushColor = $aRowColors[0]
    EndIf

    ; create a brush with the desired color:
    Local $aBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)

    ; get the rectangle for the whole row and fill it:
    Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
    DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 0, 1) ; +0 is the left margin
    _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0])

    ; draw the text in each subitem
    For $i = 0 To $iSubItemCount - 1
        ; get subitem text:
        Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, $i)
        ; get subitem coordinates for drawing its respective text:
        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, $i)
        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
        ; pass the coordinates to a DLL struct:
        Local $iSubItmRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + $aRectMargins[0]) ; left margin
        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1]) ; upper margin
        DllStructSetData($iSubItmRect, 3, $aSubItmRect[2] + $aRectMargins[2]) ; right margin
        DllStructSetData($iSubItmRect, 4, $aSubItmRect[3] + $aRectMargins[3]) ; bottom margin
        Local $tRect = DllStructGetPtr($iSubItmRect)

        Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hListView, $itmID, $i))

        If $i = 0 Then
            DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 12)
            _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left") - 16, DllStructGetData($iSubItmRect, "Top") + $iAdjustV, $hIcon, 16, 16)
            DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 2)
        Else
            _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left"), DllStructGetData($iSubItmRect, "Top") + $iAdjustV, $hIcon, 16, 16)
            DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 6 + 18)
        EndIf

        _GUIImageList_DestroyIcon($hIcon)

        If $aTextFormatting[$i] = -1 Then
            ; do nothing (don't draw)
        Else
            _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
        EndIf

    Next
EndFunc   ;==>__WM_DRAWITEM_ListView







; Based on File to Base64 String Code Generator
; by UEZ
; http://www.autoitscript.com/forum/topic/...ng-code-generator-v103-build-2

;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:      Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:         $bImage:    the binary string which contains any valid image which is supported by GDI+
; Optional:       $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:             hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;                     Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown()
;
; Requirement(s):     GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Return Value(s):    Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format),
;                     Error: 0
; Error codes:      1: $bImage is not a binary string
;                     2: unable to create stream on HGlobal
;                     3: unable to create bitmap from stream
;
; Author(s):            UEZ
; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines and
;                     Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Version:          v0.97 Build 2012-01-04 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then SetError(2, 0, 0)
    Local Const $hStream = $aResult[3]
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    If @error Then SetError(3, 0, 0)
    Local Const $hBitmap = $aResult[2]
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem

Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
    Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
    $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
    If (@error) Or ($Ret[0]) Then Return 0
    $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $pBits = DllStructGetData($tData, 'Scan0')
    If Not $pBits Then Return 0
    $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
    DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 2, $Ret[2])
    DllStructSetData($tBIHDR, 3, $Ret[3])
    DllStructSetData($tBIHDR, 4, 1)
    DllStructSetData($tBIHDR, 5, 32)
    DllStructSetData($tBIHDR, 6, 0)
    $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    If (Not @error) And ($hResult[0]) Then
        DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
        $hResult = $hResult[0]
    Else
        $hResult = 0
    EndIf
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData)
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap

Func _Decompress_Binary_String_to_Bitmap($Base64String)
    $Base64String = Binary($Base64String)
    Local $iSize_Source = BinaryLen($Base64String)
    Local $pBuffer_Source = _WinAPI_CreateBuffer($iSize_Source)
    DllStructSetData(DllStructCreate('byte[' & $iSize_Source & ']', $pBuffer_Source), 1, $Base64String)
    Local $pBuffer_Decompress = _WinAPI_CreateBuffer(8388608)
    Local $Size_Decompressed = _WinAPI_DecompressBuffer($pBuffer_Decompress, 8388608, $pBuffer_Source, $iSize_Source)
    Local $b_Result = Binary(DllStructGetData(DllStructCreate('byte[' & $Size_Decompressed & ']', $pBuffer_Decompress), 1))
    _WinAPI_FreeMemory($pBuffer_Source)
    _WinAPI_FreeMemory($pBuffer_Decompress)
    Return $b_Result
EndFunc   ;==>_Decompress_Binary_String_to_Bitmap

Func _Icon_Image_Checkbox_Unchecked()
    Local $Base64String
    $Base64String &= '7rBIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAANfc3ADZ3t4AANvg4ADe4uIAAOLl5QDl6OgAAOns7ADs7+8AAO/x8QDx8/MAAPT19QD29/cAAPj5+QD6+/sAAPz9/QD+/v7wAP///xNc/wB/AD8A/z8APwA/AD8APwA/AD8ACAAb4HYLAAEJAOEBCgsMAA0ODxAREhISbeIBCQcC4gEIBwLiAQfbBwLiAQYHAuIBBQcC4gG2BAcC4gEDBwLiAQIHAv/jAQcC5AEGAuIB7BceAOCfHgN/AG0A4QZhAA=='
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Unchecked

Func _Icon_Image_Checkbox_Checked()
    Local $Base64String
    $Base64String &= 'z7BIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAAISEhADe3t5AAN7n5wDnAQbvCO8A7wEG9/cA9/EABv///xN4/wE/AD8A/z8APwA/AD8AHwAMAOB6CwAGAQkA4QEHCAkJCR4KAgDjAQcC5AEHCAKDAwLiAQYHBwICAwI54gEFBsABAwLjAQUCxgIkBOIBBAUCRQbjAVgEBQUCAuQBAwUCCPPkAQUCBwjkAQYC4gHsF3seAOCfA38AbQDhBmEA'
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Checked

Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

Edit: Upsa, wrong include path for WinAPIEx...

Edited by KaFu
1 person likes this

Share this post


Link to post
Share on other sites

OOOOhhhhh...

;)

Thanks a bunch.

I think I'm starting to get it now :)


Share this post


Link to post
Share on other sites

Glad to know! So... do you feel like extending its functionality even more? ;)

Here are a couple of things I wasn't expecting.

----------

A )

I'm using $WM_MEASUREITEM to set the row height.

But _GUICtrlListView_SetImageList() somehow breaks this.

If I don't use _GUICtrlListView_SetImageList() then the rows have the desired height, and the images show up fine, but the ones in the first column need to be forcibly drawn when clicked. The first column behaves differently than the other subitems in many functions, so I decided to "hide" it (size=0), thus solving all my problems with it.

So, is it wrong not to use _GUICtrlListView_SetImageList()?

----------

B )

In the example below I'm showing two ways of freezing the script when using $LVS_EX_SUBITEMIMAGES.

- One of them is a consequence of using _GUICtrlListView_AddArray() to populate. It must be a function that doesn't perform the same steps as _GUICtrlListView_AddItem(). Also it won't draw icons unless you click the respective subitem.

- The other is when you don't populate the rows entirely, that is, if you skip a subitem.

I'm quite stuck with this at this point.

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Array.au3>
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
;#include <APIConstants.au3>
#include <WinAPIEx.au3> ; from http://www.autoitscript.com/forum/topic/98712-winapiex-udf/

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
; ####################################
; adjustment of the icon positioning, according to windows version
Global $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+
; ####################################

; WM_MEASUREITEM allows setting the row height
Global $iListView_row_height = 50
GUIRegisterMsg($WM_MEASUREITEM, "WM_MEASUREITEM") ; place before listview creation - message sent once for each ownerdrawn control created
;GUIRegisterMsg($WM_MEASUREITEM, "") ; call this after last ownerdrawn listview created
; ---------------------------------------------------

_GDIPlus_Startup()
$hGUI = GUICreate("ListView Set Item State", 700, 300)
$cButton_CheckAll = GUICtrlCreateButton("Check All", 10, 275, 100, 20)
$cButton_UncheckAll = GUICtrlCreateButton("UnCheck All", 120, 275, 100, 20)
$cButton_StatesToArray = GUICtrlCreateButton("States to Array", 230, 275, 100, 20)
; listview 1 -----------------------------------------------
$iListView_row_height = 25
$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS, $LVS_SINGLESEL))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES, $LVS_EX_SUBITEMIMAGES))
$hIml_Listview = _GUIImageList_Create(16, 16, 5, 3)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Unchecked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Checked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

; ##########################################################
; this "breaks" WM_MEASUREITEM
;_GUICtrlListView_SetImageList($hListView, $hIml_Listview, 1)
; why do we need this anyway?
; ##########################################################
; Add columns
_GUICtrlListView_AddColumn($hListView, " ", 0)
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView, "Column " & $i, 100)
Next
Local $aItems[30][4]
For $row = 1 To 30
$aItems[$row-1][0] = "this won't show up"
$aItems[$row-1][1] = "Row " & $row & ": Col 1"
$aItems[$row-1][2] = "Row " & $row & ": Col 2"
$aItems[$row-1][3] = "Row " & $row & ": Col 3"
Next
; if you add items via _GUICtrlListView_AddArray(), the drawing will become unstable.
; also, the checkboxes don't appear unless you click their respective subitem.
_GUICtrlListView_DeleteAllItems($hListView)
_GUICtrlListView_AddArray($hListView, $aItems)
; -----------------------------------------------------------

; listview 2 -----------------------------------------------
$iListView_row_height = 40
$cListView_2 = GUICtrlCreateListView("", 400, 2, 298, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView_2 = GUICtrlGetHandle($cListView_2)
_GUICtrlListView_SetExtendedListViewStyle($hListView_2, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
; Add columns
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView_2, "2 - Column " & $i, 90)
Next
; Add items
For $row = 1 To 20
    _GUICtrlListView_AddItem($hListView_2, "Row " & $row & ": Col 0", 0)
    _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ": Col 1", 1, 0)
    If $row <> 3 Then
  _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ": Col 2", 2, 0)
Else
  ; if you comment the line below and click+drag to resize this ListView's columns, the drawing will become unstable
  ;_GUICtrlListView_AddSubItem($hListView_2, $row - 1, "", 2, 0)
EndIf
Next
; -----------------------------------------------------------

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()

; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $cButton_CheckAll
            _LV_ImgCheckboxes_CheckAll($hListView)
        Case $cButton_UncheckAll
            _LV_ImgCheckboxes_UncheckAll($hListView)
        Case $cButton_StatesToArray
            $aLVStates = _LV_ImgCheckboxes_StatesToArray($hListView)
            _ArrayDisplay($aLVStates)
    EndSwitch
WEnd
GUIDelete()
_GUIImageList_Destroy($hIml_Listview)
_GDIPlus_Shutdown()
Exit
Func _LV_ImgCheckboxes_CheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 1, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_CheckAll
Func _LV_ImgCheckboxes_UncheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 0, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_UncheckAll
Func _LV_ImgCheckboxes_StatesToArray($hWnd)
    Local $iColumns = _GUICtrlListView_GetColumnCount($hWnd)
    If $iColumns = 0 Then Return SetError(1)
    Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
    If $iItems = 0 Then Return SetError(2)
    Local $aStates[$iItems][$iColumns]
    For $i = 0 To $iItems - 1
        For $y = 0 To $iColumns - 1
            $aStates[$i][$y] = _GUICtrlListView_GetItemImage($hWnd, $i, $y)
        Next
    Next
    Return $aStates
EndFunc   ;==>_LV_ImgCheckboxes_StatesToArray
Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $nNotifyCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $nNotifyCode
                Case $NM_CLICK
                    Local $tINFO = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iItem = DllStructGetData($tINFO, "Index")
                    Local $iSubitem = DllStructGetData($tINFO, "SubItem")
                    If $iSubitem == 2 And StringLen(_GUICtrlListView_GetItemText($hListView, $iItem, $iSubitem)) > 0 Then
      ;ConsoleWrite("painting row "&$iItem+1&"   col "&$iSubitem+1&@CRLF)
      _GUICtrlListView_SetItemImage($hListView, $iItem, Not _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem), $iSubitem)
     EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
$timer = TimerInit()
    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "hwnd hDC;" & _
            "int itmRect[4];" & _
            "dword itmData" _
            , $lParam)
    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
    Local $aDefaultVariables[9] = [$tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC]
    Switch $cID ; will look for ControlID, not window handle.
        Case $cListView
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0xEEDDBB]
                    Local $aRectMargins[4] = [6, -1, -4, 0]
                    Local $aTextFormatting[5] = [-1, _
       BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_RIGHT, $DT_END_ELLIPSIS), _
       BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_END_ELLIPSIS)]
                    __WM_DRAWITEM_ListView($hListView, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
    ; end case
   EndSwitch
  ; end case
  Case $cListView_2
   Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0x00FFFF]
                    Local $aRectMargins[4] = [6, -1, 0, 0]
                    Local $aTextFormatting[3] = [BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE)]
                    __WM_DRAWITEM_ListView($hListView_2, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
    ; end case
   EndSwitch
  ; end case
    EndSwitch
ConsoleWrite(Round(TimerDiff($timer),2) & @TAB & "WM_DRAWITEM" & @CRLF)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM
Func __WM_DRAWITEM_ListView($hListView, ByRef $aDefaultVariables, ByRef $aRowColors, ByRef $aRectMargins, ByRef $aTextFormatting)
    Local $iSubItemCount = _GUICtrlListView_GetColumnCount($hListView)
    If UBound($aTextFormatting) < $iSubItemCount Then
        ConsoleWrite("!> Error: invalid parameters in __WM_DRAWITEM_ListView()" & @CRLF)
        Return
    EndIf
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
    $tagDRAWITEMSTRUCT = $aDefaultVariables[0]
    $iBrushColor = $aDefaultVariables[1]
    $cID = $aDefaultVariables[2]
    $itmID = $aDefaultVariables[3]
    $itmAction = $aDefaultVariables[4]
    $itmState = $aDefaultVariables[5]
    $hItm = $aDefaultVariables[6]
    $hDC = $aDefaultVariables[7]
    If _GUICtrlListView_GetItemSelected($hListView, $itmID) Then
        $iBrushColor = $aRowColors[1]
    Else
        $iBrushColor = $aRowColors[0]
    EndIf
    ; create a brush with the desired color:
    Local $aBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)
    ; get the rectangle for the whole row and fill it:
    Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
    DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 0, 1) ; +0 is the left margin
    _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0])
    ; draw the text in each subitem
    For $i = 0 To $iSubItemCount - 1
        ; get subitem text:
        Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, $i)
        ; get subitem coordinates for drawing its respective text:
        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, $i)
        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
  ; pass the coordinates to a DLL struct:
        Local $iSubItmRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + $aRectMargins[0]) ; left margin
        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1]) ; upper margin
        DllStructSetData($iSubItmRect, 3, $aSubItmRect[2] + $aRectMargins[2]) ; right margin
        DllStructSetData($iSubItmRect, 4, $aSubItmRect[3] + $aRectMargins[3]) ; bottom margin
        Local $tRect = DllStructGetPtr($iSubItmRect)
  If $cID == $cListView And StringLen($iSubItmText) > 0 And $aTextFormatting[$i] <> -1 Then
   Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hListView, $itmID, $i))
   If @error Then ConsoleWrite("error 1" & @CRLF)
   If $i = 0 Then ; the first column of a listview needs more handling than the other columns (sub-items)
    #cs
    ; positioning for the icon:
    DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 12)
    _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left") - 16, Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16)/2) + $iAdjustV, $hIcon, 16, 16)
    ; positioning for the text:
    DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 4)
    #ce
   Else
    If $i == 2 Then
     _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left"), Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16)/2) + $iAdjustV, $hIcon, 16, 16)
     ; positioning for the text:
     DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 20)
    EndIf
   EndIf
   _GUIImageList_DestroyIcon($hIcon)
  EndIf
        If $aTextFormatting[$i] = -1 Then
   ; do nothing (don't draw any text)
        Else
            _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
        EndIf
    Next
EndFunc   ;==>__WM_DRAWITEM_ListView
Func WM_MEASUREITEM($hWnd, $Msg, $wParam, $lParam)
Local $tMEASUREITEMS = DllStructCreate("uint cType;uint cID;uint itmID;uint itmW;uint itmH;ulong_ptr itmData", $lParam)
If DllStructGetData($tMEASUREITEMS, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
DllStructSetData($tMEASUREITEMS, "itmH", $iListView_row_height) ; row height
Return 1
EndFunc   ;==>WM_MEASUREITEM

; Based on File to Base64 String Code Generator
; by UEZ
; http://www.autoitscript.com/forum/topic/...ng-code-generator-v103-build-2
;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:    Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:        $bImage:    the binary string which contains any valid image which is supported by GDI+
; Optional:    $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:            hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;                    Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown()
;
; Requirement(s):    GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Return Value(s):    Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format),
;                    Error: 0
; Error codes:    1: $bImage is not a binary string
;                    2: unable to create stream on HGlobal
;                    3: unable to create bitmap from stream
;
; Author(s):            UEZ
; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines and
;                    Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Version:        v0.97 Build 2012-01-04 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then SetError(2, 0, 0)
    Local Const $hStream = $aResult[3]
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    If @error Then SetError(3, 0, 0)
    Local Const $hBitmap = $aResult[2]
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem
Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
    Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
    $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
    If (@error) Or ($Ret[0]) Then Return 0
    $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $pBits = DllStructGetData($tData, 'Scan0')
    If Not $pBits Then Return 0
    $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
    DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 2, $Ret[2])
    DllStructSetData($tBIHDR, 3, $Ret[3])
    DllStructSetData($tBIHDR, 4, 1)
    DllStructSetData($tBIHDR, 5, 32)
    DllStructSetData($tBIHDR, 6, 0)
    $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    If (Not @error) And ($hResult[0]) Then
        DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
        $hResult = $hResult[0]
    Else
        $hResult = 0
    EndIf
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData)
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap
Func _Decompress_Binary_String_to_Bitmap($Base64String)
    $Base64String = Binary($Base64String)
    Local $iSize_Source = BinaryLen($Base64String)
    Local $pBuffer_Source = _WinAPI_CreateBuffer($iSize_Source)
    DllStructSetData(DllStructCreate('byte[' & $iSize_Source & ']', $pBuffer_Source), 1, $Base64String)
    Local $pBuffer_Decompress = _WinAPI_CreateBuffer(8388608)
    Local $Size_Decompressed = _WinAPI_DecompressBuffer($pBuffer_Decompress, 8388608, $pBuffer_Source, $iSize_Source)
    Local $b_Result = Binary(DllStructGetData(DllStructCreate('byte[' & $Size_Decompressed & ']', $pBuffer_Decompress), 1))
    _WinAPI_FreeMemory($pBuffer_Source)
    _WinAPI_FreeMemory($pBuffer_Decompress)
    Return $b_Result
EndFunc   ;==>_Decompress_Binary_String_to_Bitmap
Func _Icon_Image_Checkbox_Unchecked()
    Local $Base64String
    $Base64String &= '7rBIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAANfc3ADZ3t4AANvg4ADe4uIAAOLl5QDl6OgAAOns7ADs7+8AAO/x8QDx8/MAAPT19QD29/cAAPj5+QD6+/sAAPz9/QD+/v7wAP///xNc/wB/AD8A/z8APwA/AD8APwA/AD8ACAAb4HYLAAEJAOEBCgsMAA0ODxAREhISbeIBCQcC4gEIBwLiAQfbBwLiAQYHAuIBBQcC4gG2BAcC4gEDBwLiAQIHAv/jAQcC5AEGAuIB7BceAOCfHgN/AG0A4QZhAA=='
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Unchecked
Func _Icon_Image_Checkbox_Checked()
    Local $Base64String
    $Base64String &= 'z7BIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAAISEhADe3t5AAN7n5wDnAQbvCO8A7wEG9/cA9/EABv///xN4/wE/AD8A/z8APwA/AD8AHwAMAOB6CwAGAQkA4QEHCAkJCR4KAgDjAQcC5AEHCAKDAwLiAQYHBwICAwI54gEFBsABAwLjAQUCxgIkBOIBBAUCRQbjAVgEBQUCAuQBAwUCCPPkAQUCBwjkAQYC4gHsF3seAOCfA38AbQDhBmEA'
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Checked
Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

Any thoughts?

Once again, thanks.


Share this post


Link to post
Share on other sites

Okay so here is my alternative for _GUI_ListView_AddArray().

It is of course slower but it's working flawlessly for me ;)

Func __GUI_ListView_Add_Array($hListView, ByRef $array)
If Not IsArray($array) Then Return SetError(1, 0, 0) ; not an array
Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView)
; if the number of columns between the array and the listview doesn't match:
If UBound($array,2) <> $iColumnCount Then Return SetError(3, 1, 0)
Switch UBound($array, 0)
  Case 1 ; 1-dimensioned array
   _GUICtrlListView_BeginUpdate($hListView)
   For $r = 0 To UBound($array, 1) - 1
    _GUICtrlListView_AddItem($hListView, $array[$r], 0)
   Next
   _GUICtrlListView_EndUpdate($hListView)
  Case 2 ; 2-dimensioned array
   _GUICtrlListView_BeginUpdate($hListView)
   Local $first_row
   For $r = 0 To UBound($array, 1) - 1
    If $r = 0 Then
     $first_row = _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
    Else
     _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
    EndIf
   Next
   For $r = 0 To UBound($array, 1) - 1
    For $c = 1 To UBound($array, 2) - 1
     _GUICtrlListView_AddSubItem($hListView, $first_row + $r, $array[$r][$c], $c, 0)
    Next
   Next
   _GUICtrlListView_EndUpdate($hListView)
  Case Else
   Return SetError(2, 0, 0) ; invalid array (over 2 dimensions)
EndSwitch
Return
EndFunc

Share this post


Link to post
Share on other sites

Instead of creating a new topic I chose to post here. This way we may be able to gather the necessary code to demonstrate all the personalizations in a single ListView.

Edit in Place isn't for now one of the things I need or have in mind for my current project.

One awesome example:

And this example that I remember seeing working in the past, but now the code is outdated; haven't looked at it in a while:

As for the multiline, I found a trick:

Display multiline content with fly-over tooltips:

It does what it says, but it's not very helpful (visually) and it's a bit annoying.

I have an idea, though. I just need a little help: ;)

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Array.au3>
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
;#include <APIConstants.au3>
#include <WinAPIEx.au3> ; from http://www.autoitscript.com/forum/topic/98712-winapiex-udf/

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
; ####################################
; adjustment of the icon positioning, according to windows version
Global $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+
; ####################################

; WM_MEASUREITEM allows setting the row height
Global $iListView_row_height = 50
GUIRegisterMsg($WM_MEASUREITEM, "WM_MEASUREITEM") ; place before listview creation - message sent once for each ownerdrawn control created
;GUIRegisterMsg($WM_MEASUREITEM, "") ; call this after last ownerdrawn listview created
; ---------------------------------------------------

_GDIPlus_Startup()
$hGUI = GUICreate("ListView Set Item State", 700, 300)
$cButton_CheckAll = GUICtrlCreateButton("Check All", 10, 275, 100, 20)
$cButton_UncheckAll = GUICtrlCreateButton("UnCheck All", 120, 275, 100, 20)
$cButton_StatesToArray = GUICtrlCreateButton("States to Array", 230, 275, 100, 20)
; listview 1 -----------------------------------------------
$iListView_row_height = 25
$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS, $LVS_SINGLESEL))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES, $LVS_EX_SUBITEMIMAGES))
$hIml_Listview = _GUIImageList_Create(16, 16, 5, 3)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Unchecked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Checked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

; ##########################################################
; this "breaks" WM_MEASUREITEM
;_GUICtrlListView_SetImageList($hListView, $hIml_Listview, 1)
; why do we need this anyway?
; ##########################################################
; Add columns
_GUICtrlListView_AddColumn($hListView, " ", 0)
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView, "Column " & $i, 100)
Next
Local $aItems[30][4]
For $row = 1 To 30
$aItems[$row-1][0] = "this won't show up"
$aItems[$row-1][1] = "Row " & $row & ": Col 1"
$aItems[$row-1][2] = "Row " & $row & ": Col 2"
$aItems[$row-1][3] = "Row " & $row & ": Col 3"
Next
; if you add items via _GUICtrlListView_AddArray(), the drawing will become unstable.
; also, the checkboxes don't appear unless you click their respective subitem.
_GUICtrlListView_DeleteAllItems($hListView)
;_GUICtrlListView_AddArray($hListView, $aItems)
__GUI_ListView_Add_Array($hListView, $aItems) ; workaround
; -----------------------------------------------------------

; listview 2 -----------------------------------------------
$iListView_row_height = 40
$cListView_2 = GUICtrlCreateListView("", 400, 2, 298, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView_2 = GUICtrlGetHandle($cListView_2)
_GUICtrlListView_SetExtendedListViewStyle($hListView_2, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
; Add columns
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView_2, "2 - Column " & $i, 90)
Next
; Add items
For $row = 1 To 20
    _GUICtrlListView_AddItem($hListView_2, "Row " & $row & ": Col 0", 0)
    _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ", resize me!" & @CRLF & "-----------Col 1", 1, 0)
    If $row <> 3 Then
  _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ": Col 2", 2, 0)
Else
  ; if you comment the line below and click+drag to resize this ListView's columns, the drawing will become unstable
  _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "", 2, 0)
EndIf
Next
; -----------------------------------------------------------

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()

; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $cButton_CheckAll
            _LV_ImgCheckboxes_CheckAll($hListView)
        Case $cButton_UncheckAll
            _LV_ImgCheckboxes_UncheckAll($hListView)
        Case $cButton_StatesToArray
            $aLVStates = _LV_ImgCheckboxes_StatesToArray($hListView)
            _ArrayDisplay($aLVStates)
    EndSwitch
WEnd
GUIDelete()
_GUIImageList_Destroy($hIml_Listview)
_GDIPlus_Shutdown()
Exit
Func _LV_ImgCheckboxes_CheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 1, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_CheckAll
Func _LV_ImgCheckboxes_UncheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 0, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_UncheckAll
Func _LV_ImgCheckboxes_StatesToArray($hWnd)
    Local $iColumns = _GUICtrlListView_GetColumnCount($hWnd)
    If $iColumns = 0 Then Return SetError(1)
    Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
    If $iItems = 0 Then Return SetError(2)
    Local $aStates[$iItems][$iColumns]
    For $i = 0 To $iItems - 1
        For $y = 0 To $iColumns - 1
            $aStates[$i][$y] = _GUICtrlListView_GetItemImage($hWnd, $i, $y)
        Next
    Next
    Return $aStates
EndFunc   ;==>_LV_ImgCheckboxes_StatesToArray
Func __GUI_ListView_Add_Array($hListView, ByRef $array)
If Not IsArray($array) Then Return SetError(1, 0, 0) ; not an array
Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView)
; if the number of columns between the array and the listview doesn't match:
If UBound($array,2) <> $iColumnCount Then Return SetError(3, 1, 0)
Switch UBound($array, 0)
  Case 1 ; 1-dimensioned array
   _GUICtrlListView_BeginUpdate($hListView)
   For $r = 0 To UBound($array, 1) - 1
    _GUICtrlListView_AddItem($hListView, $array[$r], 0)
   Next
   _GUICtrlListView_EndUpdate($hListView)
  Case 2 ; 2-dimensioned array
   _GUICtrlListView_BeginUpdate($hListView)
   Local $first_row
   For $r = 0 To UBound($array, 1) - 1
    If $r = 0 Then
     $first_row = _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
    Else
     _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
    EndIf
   Next
   For $r = 0 To UBound($array, 1) - 1
    For $c = 1 To UBound($array, 2) - 1
     _GUICtrlListView_AddSubItem($hListView, $first_row + $r, $array[$r][$c], $c, 0)
    Next
   Next
   _GUICtrlListView_EndUpdate($hListView)
  Case Else
   Return SetError(2, 0, 0) ; invalid array (over 2 dimensions)
EndSwitch
Return
EndFunc

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $nNotifyCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $nNotifyCode
                Case $NM_CLICK
                    Local $tINFO = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iItem = DllStructGetData($tINFO, "Index")
                    Local $iSubitem = DllStructGetData($tINFO, "SubItem")
                    If $iSubitem == 2 And StringLen(_GUICtrlListView_GetItemText($hListView, $iItem, $iSubitem)) > 0 Then
      ;ConsoleWrite("painting row "&$iItem+1&"   col "&$iSubitem+1&@CRLF)
      _GUICtrlListView_SetItemImage($hListView, $iItem, Not _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem), $iSubitem)
     EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
$timer = TimerInit()
    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "hwnd hDC;" & _
            "int itmRect[4];" & _
            "dword itmData" _
            , $lParam)
    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
    Local $aDefaultVariables[9] = [$tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC]
    Switch $cID ; will look for ControlID, not window handle.
        Case $cListView
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0xEEDDBB]
                    Local $aRectMargins[4] = [6, -1, -4, 0]
                    Local $aTextFormatting[5] = [-1, _
       BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_RIGHT, $DT_END_ELLIPSIS), _
       BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_END_ELLIPSIS)]
                    __WM_DRAWITEM_ListView($hListView, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
    ; end case
   EndSwitch
  ; end case
  Case $cListView_2
   Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0x00FFFF]
                    Local $aRectMargins[4] = [6, -1, 0, 0]
                    Local $aTextFormatting[3] = [BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_EDITCONTROL, $DT_WORDBREAK), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE)]
                    __WM_DRAWITEM_ListView($hListView_2, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
    ; end case
   EndSwitch
  ; end case
    EndSwitch
ConsoleWrite(Round(TimerDiff($timer),2) & @TAB & "WM_DRAWITEM" & @CRLF)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM
Func __WM_DRAWITEM_ListView($hListView, ByRef $aDefaultVariables, ByRef $aRowColors, ByRef $aRectMargins, ByRef $aTextFormatting)
Local $iSubItemCount = _GUICtrlListView_GetColumnCount($hListView)
If UBound($aTextFormatting) < $iSubItemCount Then
  ConsoleWrite("!> Error: invalid parameters in __WM_DRAWITEM_ListView()" & @CRLF)
  Return
EndIf
Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
$tagDRAWITEMSTRUCT = $aDefaultVariables[0]
$iBrushColor = $aDefaultVariables[1]
$cID = $aDefaultVariables[2]
$itmID = $aDefaultVariables[3]
$itmAction = $aDefaultVariables[4]
$itmState = $aDefaultVariables[5]
$hItm = $aDefaultVariables[6]
$hDC = $aDefaultVariables[7]
If _GUICtrlListView_GetItemSelected($hListView, $itmID) Then
  $iBrushColor = $aRowColors[1]
Else
  $iBrushColor = $aRowColors[0]
EndIf
; create a brush with the desired color:
Local $aBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)
; get the rectangle for the whole row and fill it:
Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 0, 1) ; +0 is the left margin
_WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0])
; draw the text in each subitem
For $i = 0 To $iSubItemCount - 1
  ; get subitem text:
  Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, $i)
  ; get subitem coordinates for drawing its respective text:
  Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, $i)
  ; the function above accepts not only subitems (one-based index), but also main item (index=0)
  ; pass the coordinates to a DLL struct:
  Local $iSubItmRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
  DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + $aRectMargins[0]) ; left margin
  DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1]) ; upper margin
  DllStructSetData($iSubItmRect, 3, $aSubItmRect[2] + $aRectMargins[2]) ; right margin
  DllStructSetData($iSubItmRect, 4, $aSubItmRect[3] + $aRectMargins[3]) ; bottom margin
  Local $tRect = DllStructGetPtr($iSubItmRect)
  ;#cs
  If $cID == $cListView And StringLen($iSubItmText) > 0 And $aTextFormatting[$i] <> - 1 Then
   Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hListView, $itmID, $i))
   If $i = 0 Then ; the first column of a listview needs more handling than the other columns (sub-items)
    #cs
     ; positioning for the icon:
     DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 12)
     _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left") - 16, Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16)/2) + $iAdjustV, $hIcon, 16, 16)
     ; positioning for the text:
     DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 4)
    #ce
   ElseIf $i == 2 Then
    _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left"), Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16) / 2) - 1 + $iAdjustV, $hIcon, 16, 16)
    ; positioning for the text:
    DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 20)
   EndIf
   _GUIImageList_DestroyIcon($hIcon)
  EndIf
  ;#ce
  If $aTextFormatting[$i] = -1 Then
   ; do nothing (don't draw any text)
  Else
   _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
  EndIf
Next
EndFunc   ;==>__WM_DRAWITEM_ListView
Func WM_MEASUREITEM($hWnd, $Msg, $wParam, $lParam)
Local $tMEASUREITEMS = DllStructCreate("uint cType;uint cID;uint itmID;uint itmW;uint itmH;ulong_ptr itmData", $lParam)
If DllStructGetData($tMEASUREITEMS, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
DllStructSetData($tMEASUREITEMS, "itmH", $iListView_row_height) ; row height
Return 1
EndFunc   ;==>WM_MEASUREITEM


; Based on File to Base64 String Code Generator
; by UEZ
; http://www.autoitscript.com/forum/topic/...ng-code-generator-v103-build-2
;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:    Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:        $bImage:    the binary string which contains any valid image which is supported by GDI+
; Optional:    $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:            hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;                    Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown()
;
; Requirement(s):    GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Return Value(s):    Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format),
;                    Error: 0
; Error codes:    1: $bImage is not a binary string
;                    2: unable to create stream on HGlobal
;                    3: unable to create bitmap from stream
;
; Author(s):            UEZ
; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines and
;                    Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Version:        v0.97 Build 2012-01-04 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then SetError(2, 0, 0)
    Local Const $hStream = $aResult[3]
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    If @error Then SetError(3, 0, 0)
    Local Const $hBitmap = $aResult[2]
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem
Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
    Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
    $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
    If (@error) Or ($Ret[0]) Then Return 0
    $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $pBits = DllStructGetData($tData, 'Scan0')
    If Not $pBits Then Return 0
    $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
    DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 2, $Ret[2])
    DllStructSetData($tBIHDR, 3, $Ret[3])
    DllStructSetData($tBIHDR, 4, 1)
    DllStructSetData($tBIHDR, 5, 32)
    DllStructSetData($tBIHDR, 6, 0)
    $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    If (Not @error) And ($hResult[0]) Then
        DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
        $hResult = $hResult[0]
    Else
        $hResult = 0
    EndIf
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData)
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap
Func _Decompress_Binary_String_to_Bitmap($Base64String)
    $Base64String = Binary($Base64String)
    Local $iSize_Source = BinaryLen($Base64String)
    Local $pBuffer_Source = _WinAPI_CreateBuffer($iSize_Source)
    DllStructSetData(DllStructCreate('byte[' & $iSize_Source & ']', $pBuffer_Source), 1, $Base64String)
    Local $pBuffer_Decompress = _WinAPI_CreateBuffer(8388608)
    Local $Size_Decompressed = _WinAPI_DecompressBuffer($pBuffer_Decompress, 8388608, $pBuffer_Source, $iSize_Source)
    Local $b_Result = Binary(DllStructGetData(DllStructCreate('byte[' & $Size_Decompressed & ']', $pBuffer_Decompress), 1))
    _WinAPI_FreeMemory($pBuffer_Source)
    _WinAPI_FreeMemory($pBuffer_Decompress)
    Return $b_Result
EndFunc   ;==>_Decompress_Binary_String_to_Bitmap
Func _Icon_Image_Checkbox_Unchecked()
    Local $Base64String
    $Base64String &= '7rBIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAANfc3ADZ3t4AANvg4ADe4uIAAOLl5QDl6OgAAOns7ADs7+8AAO/x8QDx8/MAAPT19QD29/cAAPj5+QD6+/sAAPz9/QD+/v7wAP///xNc/wB/AD8A/z8APwA/AD8APwA/AD8ACAAb4HYLAAEJAOEBCgsMAA0ODxAREhISbeIBCQcC4gEIBwLiAQfbBwLiAQYHAuIBBQcC4gG2BAcC4gEDBwLiAQIHAv/jAQcC5AEGAuIB7BceAOCfHgN/AG0A4QZhAA=='
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Unchecked
Func _Icon_Image_Checkbox_Checked()
    Local $Base64String
    $Base64String &= 'z7BIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAAISEhADe3t5AAN7n5wDnAQbvCO8A7wEG9/cA9/EABv///xN4/wE/AD8A/z8APwA/AD8AHwAMAOB6CwAGAQkA4QEHCAkJCR4KAgDjAQcC5AEHCAKDAwLiAQYHBwICAwI54gEFBsABAwLjAQUCxgIkBOIBBAUCRQbjAVgEBQUCAuQBAwUCCPPkAQUCBwjkAQYC4gHsF3seAOCfA38AbQDhBmEA'
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Checked
Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

For me this is awesome already.

But how would I draw different font sizes, or even different fonts, within the same subitem? In essential trying to resemble the Outlook lists (From, Subject, Body, all into one "cell").

And then there's the vertical alignment. $DT_VCENTER only seems to work with single line.

1 person likes this

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

It's ownerdrawing, and you have the items DC, so the world's your oyster.

A rough outline of how to set multiline text fonts/colour.

You could probably compose an items image in an off-screen DC, then bitblit to the item DC

Includes a gratuitous example of using a theme part for item selection.

Edit: corrected ODS_SELECTED multiple item selection

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Array.au3>
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
;#include <APIConstants.au3>
#include <WinAPIEx.au3> ; from http://www.autoitscript.com/forum/topic/98712-winapiex-udf/
#include <FontConstants.au3>

Global $aFont[3]
$aFont[0] = _WinAPI_CreateFont(20, 0, 0, 0, $FW_MEDIUM, False, False, False, _
        $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, 'Times New Roman')
$aFont[1] = _WinAPI_CreateFont(18, 0, 0, 0, $FW_MEDIUM, False, False, False, _
        $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, 'Tahoma')
$aFont[2] = _WinAPI_CreateFont(32, 6, 0, 0, $FW_BOLD, False, False, False, _
        $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, 'Comic Sans MS')
Global $hThemex = DllCall('uxtheme.dll', 'ptr', 'OpenThemeData', 'hwnd', 0, 'wstr', 'Button')
$hThemex = $hThemex[0]

Global Const $ODS_SELECTED = 0x0001
Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1

; ####################################
; adjustment of the icon positioning, according to windows version
Global $iAdjustV = 0
If $__WINVER > 0x0600 Then $iAdjustV = 1 ; $__WINVER defined in WinAPIEx, $__WINVER > 0x0600 means Vista+
; ####################################
; WM_MEASUREITEM allows setting the row height
Global $iListView_row_height = 50
GUIRegisterMsg($WM_MEASUREITEM, "WM_MEASUREITEM") ; place before listview creation - message sent once for each ownerdrawn control created
;GUIRegisterMsg($WM_MEASUREITEM, "") ; call this after last ownerdrawn listview created
; ---------------------------------------------------

_GDIPlus_Startup()
$hGUI = GUICreate("ListView Set Item State", 700, 300)
$cButton_CheckAll = GUICtrlCreateButton("Check All", 10, 275, 100, 20)
$cButton_UncheckAll = GUICtrlCreateButton("UnCheck All", 120, 275, 100, 20)
$cButton_StatesToArray = GUICtrlCreateButton("States to Array", 230, 275, 100, 20)

; listview 1 -----------------------------------------------
$iListView_row_height = 25
$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS, $LVS_SINGLESEL))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES, $LVS_EX_SUBITEMIMAGES))
$hIml_Listview = _GUIImageList_Create(16, 16, 5, 3)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Unchecked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)
$hBitmap_Icon = _Load_BMP_From_Mem(_Icon_Image_Checkbox_Checked(), True)
_GUIImageList_Add($hIml_Listview, $hBitmap_Icon)
_WinAPI_DeleteObject($hBitmap_Icon)

; ##########################################################
; this "breaks" WM_MEASUREITEM
;_GUICtrlListView_SetImageList($hListView, $hIml_Listview, 1)
; why do we need this anyway?
; ##########################################################

; Add columns
_GUICtrlListView_AddColumn($hListView, " ", 0)
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView, "Column " & $i, 100)
Next
Local $aItems[30][4]
For $row = 1 To 30
    $aItems[$row - 1][0] = "this won't show up"
    $aItems[$row - 1][1] = "Row " & $row & ": Col 1"
    $aItems[$row - 1][2] = "Row " & $row & ": Col 2"
    $aItems[$row - 1][3] = "Row " & $row & ": Col 3"
Next

; if you add items via _GUICtrlListView_AddArray(), the drawing will become unstable.
; also, the checkboxes don't appear unless you click their respective subitem.
_GUICtrlListView_DeleteAllItems($hListView)
;_GUICtrlListView_AddArray($hListView, $aItems)
__GUI_ListView_Add_Array($hListView, $aItems) ; workaround
; -----------------------------------------------------------

; listview 2 -----------------------------------------------
$iListView_row_height = 80
$cListView_2 = GUICtrlCreateListView("", 400, 2, 298, 268, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_SHOWSELALWAYS))
GUICtrlSetFont(-1, 11, 400, 0, "Calibri", 5)
$hListView_2 = GUICtrlGetHandle($cListView_2)
_GUICtrlListView_SetExtendedListViewStyle($hListView_2, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
; Add columns
For $i = 1 To 3
    _GUICtrlListView_AddColumn($hListView_2, "2 - Column " & $i, 90)
Next
; Add items
For $row = 1 To 20
    _GUICtrlListView_AddItem($hListView_2, "Row " & $row & ": Col 0", 0)
    _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ", resize me!" & @CRLF & "-----------Col 1", 1, 0)
    If $row <> 3 Then
        _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "Row " & $row & ": Col 2", 2, 0)
    Else
        ; if you comment the line below and click+drag to resize this ListView's columns, the drawing will become unstable
        _GUICtrlListView_AddSubItem($hListView_2, $row - 1, "", 2, 0)
    EndIf
Next
; -----------------------------------------------------------

_GUICtrlListView_SetItemSelected($cListView_2, 0)


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()
; Loop until user exits

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $cButton_CheckAll
            _LV_ImgCheckboxes_CheckAll($hListView)
        Case $cButton_UncheckAll
            _LV_ImgCheckboxes_UncheckAll($hListView)
        Case $cButton_StatesToArray
            $aLVStates = _LV_ImgCheckboxes_StatesToArray($hListView)
            _ArrayDisplay($aLVStates)
    EndSwitch
WEnd

GUIDelete()
DllCall('uxtheme.dll', 'uint', 'CloseThemeData', 'ptr', $hThemex)
_GUIImageList_Destroy($hIml_Listview)
_GDIPlus_Shutdown()
For $i = 0 To UBound($aFont) - 1
    If $aFont[$i] Then _WinAPI_DeleteObject($aFont[$i])
Next
Exit

Func _LV_ImgCheckboxes_CheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 1, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_CheckAll

Func _LV_ImgCheckboxes_UncheckAll($hWnd)
    _GUICtrlListView_BeginUpdate($hWnd)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) - 1
        For $y = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1
            _GUICtrlListView_SetItemImage($hWnd, $i, 0, $y)
        Next
    Next
    _GUICtrlListView_EndUpdate($hWnd)
EndFunc   ;==>_LV_ImgCheckboxes_UncheckAll

Func _LV_ImgCheckboxes_StatesToArray($hWnd)
    Local $iColumns = _GUICtrlListView_GetColumnCount($hWnd)
    If $iColumns = 0 Then Return SetError(1)
    Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
    If $iItems = 0 Then Return SetError(2)
    Local $aStates[$iItems][$iColumns]
    For $i = 0 To $iItems - 1
        For $y = 0 To $iColumns - 1
            $aStates[$i][$y] = _GUICtrlListView_GetItemImage($hWnd, $i, $y)
        Next
    Next
    Return $aStates
EndFunc   ;==>_LV_ImgCheckboxes_StatesToArray

Func __GUI_ListView_Add_Array($hListView, ByRef $array)
    If Not IsArray($array) Then Return SetError(1, 0, 0) ; not an array
    Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView)
    ; if the number of columns between the array and the listview doesn't match:
    If UBound($array, 2) <> $iColumnCount Then Return SetError(3, 1, 0)
    Switch UBound($array, 0)
        Case 1 ; 1-dimensioned array
            _GUICtrlListView_BeginUpdate($hListView)
            For $r = 0 To UBound($array, 1) - 1
                _GUICtrlListView_AddItem($hListView, $array[$r], 0)
            Next
            _GUICtrlListView_EndUpdate($hListView)
        Case 2 ; 2-dimensioned array
            _GUICtrlListView_BeginUpdate($hListView)
            Local $first_row
            For $r = 0 To UBound($array, 1) - 1
                If $r = 0 Then
                    $first_row = _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
                Else
                    _GUICtrlListView_AddItem($hListView, $array[$r][0], 0)
                EndIf
            Next
            For $r = 0 To UBound($array, 1) - 1
                For $c = 1 To UBound($array, 2) - 1
                    _GUICtrlListView_AddSubItem($hListView, $first_row + $r, $array[$r][$c], $c, 0)
                Next
            Next
            _GUICtrlListView_EndUpdate($hListView)
        Case Else
            Return SetError(2, 0, 0) ; invalid array (over 2 dimensions)
    EndSwitch
    Return
EndFunc   ;==>__GUI_ListView_Add_Array

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $nNotifyCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $nNotifyCode
                Case $NM_CLICK
                    Local $tINFO = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iItem = DllStructGetData($tINFO, "Index")
                    Local $iSubitem = DllStructGetData($tINFO, "SubItem")
                    If $iSubitem == 2 And StringLen(_GUICtrlListView_GetItemText($hListView, $iItem, $iSubitem)) > 0 Then
                        ;ConsoleWrite("painting row "&$iItem+1&"   col "&$iSubitem+1&@CRLF)
                        _GUICtrlListView_SetItemImage($hListView, $iItem, Not _GUICtrlListView_GetItemImage($hListView, $iItem, $iSubitem), $iSubitem)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
    $timer = TimerInit()
    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "hwnd hDC;" & _
            "int itmRect[4];" & _
            "dword itmData" _
            , $lParam)
    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
    Local $aDefaultVariables[9] = [$tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC]
    Switch $cID ; will look for ControlID, not window handle.
        Case $cListView
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0xEEDDBB]
                    Local $aRectMargins[4] = [6, -1, -4, 0]
                    Local $aTextFormatting[5] = [-1, _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_CENTER, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_RIGHT, $DT_END_ELLIPSIS), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE, $DT_END_ELLIPSIS)]
                    __WM_DRAWITEM_ListView($hListView, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
                    ; end case
            EndSwitch
            ; end case
        Case $cListView_2
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    Local $aRowColors[2] = [0xFDFDFD, 0x00FFFF]
                    Local $aRectMargins[4] = [6, -1, 0, 0]
                    Local $aTextFormatting[3] = [BitOR($DT_VCENTER, $DT_SINGLELINE), _
                            BitOR($DT_EDITCONTROL, $DT_WORDBREAK), _
                            BitOR($DT_VCENTER, $DT_SINGLELINE)]
                    __WM_DRAWITEM_ListView($hListView_2, $aDefaultVariables, $aRowColors, $aRectMargins, $aTextFormatting)
                    ; end case
            EndSwitch
            ; end case
    EndSwitch
    ConsoleWrite(Round(TimerDiff($timer), 2) & @TAB & "WM_DRAWITEM" & @CRLF)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

Func __WM_DRAWITEM_ListView($hLV, ByRef $aDefaultVariables, ByRef $aRowColors, ByRef $aRectMargins, ByRef $aTextFormatting)
    Local $iSubItemCount = _GUICtrlListView_GetColumnCount($hLV)
    If UBound($aTextFormatting) < $iSubItemCount Then
        ConsoleWrite("!> Error: invalid parameters in __WM_DRAWITEM_ListView()" & @CRLF)
        Return
    EndIf
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC
    $tagDRAWITEMSTRUCT = $aDefaultVariables[0]
    $iBrushColor = $aDefaultVariables[1]
    $cID = $aDefaultVariables[2]
    $itmID = $aDefaultVariables[3]
    $itmAction = $aDefaultVariables[4]
    $itmState = $aDefaultVariables[5]
    $hItm = $aDefaultVariables[6]
    $hDC = $aDefaultVariables[7]


    If BitAND($itmState, $ODS_SELECTED) Then
        $iBrushColor = $aRowColors[1]
        DllCall('uxtheme.dll', 'uint', 'DrawThemeBackground', 'ptr', $hThemex, 'hwnd', $hDC, 'int', 1, 'int', 3, 'ptr', DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), 'ptr', 0)
    Else
        $iBrushColor = $aRowColors[0]
        ; create a brush with the desired color:
        Local $aBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)
        ; get the rectangle for the whole row and fill it:
        Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
        DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 0, 1) ; +0 is the left margin
        _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0])
        _WinAPI_DeleteObject($aBrush[0])
    EndIf

    ; draw the text in each subitem
    For $i = 0 To $iSubItemCount - 1
        ; get subitem text:
        Local $iSubItmText = _GUICtrlListView_GetItemText($hLV, $itmID, $i)
        ; get subitem coordinates for drawing its respective text:
        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hLV, $itmID, $i)
        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
        ; pass the coordinates to a DLL struct:
        Local $iSubItmRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + $aRectMargins[0]) ; left margin
        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1]) ; upper margin
        DllStructSetData($iSubItmRect, 3, $aSubItmRect[2] + $aRectMargins[2]) ; right margin
        DllStructSetData($iSubItmRect, 4, $aSubItmRect[3] + $aRectMargins[3]) ; bottom margin
        Local $tRect = DllStructGetPtr($iSubItmRect)
        ;#cs
        If $cID == $cListView And StringLen($iSubItmText) > 0 And $aTextFormatting[$i] <> -1 Then
            Local $hIcon = _GUIImageList_GetIcon($hIml_Listview, _GUICtrlListView_GetItemImage($hLV, $itmID, $i))
            If $i = 0 Then ; the first column of a listview needs more handling than the other columns (sub-items)
                #cs
                    ; positioning for the icon:
                    DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 12)
                    _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left") - 16, Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16)/2) + $iAdjustV, $hIcon, 16, 16)
                    ; positioning for the text:
                    DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 4)
                #ce
            ElseIf $i == 2 Then
                _WinAPI_DrawIconEx($hDC, DllStructGetData($iSubItmRect, "Left"), Int((DllStructGetData($iSubItmRect, "Bottom") + DllStructGetData($iSubItmRect, "Top") - 16) / 2) - 1 + $iAdjustV, $hIcon, 16, 16)
                ; positioning for the text:
                DllStructSetData($iSubItmRect, "Left", DllStructGetData($iSubItmRect, "Left") + 20)
            EndIf
            _GUIImageList_DestroyIcon($hIcon)
        EndIf
        ;#ce
        If $aTextFormatting[$i] = -1 Then
            ; do nothing (don't draw any text)
        Else
            Switch $hLV
                Case $hListView
                    _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
                Case $hListView_2
                    If $i = 0 Then
                        Local $iColPrev = _WinAPI_SetTextColor($hDC, 0x0000FF)
                        Local $hFontOld = _WinAPI_SelectObject($hDC, $aFont[0])
                        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1] + 2)
                        _WinAPI_DrawText($hDC, "Times", $tRect, $aTextFormatting[1])
                        _WinAPI_SetTextColor($hDC, 0x00FF00)
                        _WinAPI_SelectObject($hDC, $aFont[1])
                        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1] + 26)
                        _WinAPI_DrawText($hDC, "Tahoma", $tRect, $aTextFormatting[1])
                        _WinAPI_SetTextColor($hDC, 0xFF0000)
                        _WinAPI_SelectObject($hDC, $aFont[2])
                        DllStructSetData($iSubItmRect, 2, $aSubItmRect[1] + $aRectMargins[1] + 48)
                        _WinAPI_DrawText($hDC, "Comic Sans", $tRect, $aTextFormatting[1])
                        _WinAPI_SelectObject($hDC, $hFontOld)
                        _WinAPI_SetTextColor($hDC, $iColPrev)
                    Else
                        _WinAPI_DrawText($hDC, $iSubItmText, $tRect, $aTextFormatting[$i])
                    EndIf
            EndSwitch

        EndIf
    Next
EndFunc   ;==>__WM_DRAWITEM_ListView

Func WM_MEASUREITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tMEASUREITEMS = DllStructCreate("uint cType;uint cID;uint itmID;uint itmW;uint itmH;ulong_ptr itmData", $lParam)
    If DllStructGetData($tMEASUREITEMS, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    DllStructSetData($tMEASUREITEMS, "itmH", $iListView_row_height) ; row height
    Return 1
EndFunc   ;==>WM_MEASUREITEM

; Based on File to Base64 String Code Generator
; by UEZ
; http://www.autoitscript.com/forum/topic/...ng-code-generator-v103-build-2
;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:  Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:       $bImage:    the binary string which contains any valid image which is supported by GDI+
; Optional: $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:           hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;                   Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown()
;
; Requirement(s):   GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Return Value(s):  Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format),
;                   Error: 0
; Error codes:  1: $bImage is not a binary string
;                   2: unable to create stream on HGlobal
;                   3: unable to create bitmap from stream
;
; Author(s):            UEZ
; Additional Code:  thanks to progandy for the MemGlobalAlloc and tVARIANT lines and
;                   Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3
; Version:      v0.97 Build 2012-01-04 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then SetError(2, 0, 0)
    Local Const $hStream = $aResult[3]
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    If @error Then SetError(3, 0, 0)
    Local Const $hBitmap = $aResult[2]
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem

Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
    Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
    $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
    If (@error) Or ($Ret[0]) Then Return 0
    $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $pBits = DllStructGetData($tData, 'Scan0')
    If Not $pBits Then Return 0
    $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
    DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 2, $Ret[2])
    DllStructSetData($tBIHDR, 3, $Ret[3])
    DllStructSetData($tBIHDR, 4, 1)
    DllStructSetData($tBIHDR, 5, 32)
    DllStructSetData($tBIHDR, 6, 0)
    $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    If (Not @error) And ($hResult[0]) Then
        DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
        $hResult = $hResult[0]
    Else
        $hResult = 0
    EndIf
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData)
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap

Func _Decompress_Binary_String_to_Bitmap($Base64String)
    $Base64String = Binary($Base64String)
    Local $iSize_Source = BinaryLen($Base64String)
    Local $pBuffer_Source = _WinAPI_CreateBuffer($iSize_Source)
    DllStructSetData(DllStructCreate('byte[' & $iSize_Source & ']', $pBuffer_Source), 1, $Base64String)
    Local $pBuffer_Decompress = _WinAPI_CreateBuffer(8388608)
    Local $Size_Decompressed = _WinAPI_DecompressBuffer($pBuffer_Decompress, 8388608, $pBuffer_Source, $iSize_Source)
    Local $b_Result = Binary(DllStructGetData(DllStructCreate('byte[' & $Size_Decompressed & ']', $pBuffer_Decompress), 1))
    _WinAPI_FreeMemory($pBuffer_Source)
    _WinAPI_FreeMemory($pBuffer_Decompress)
    Return $b_Result
EndFunc   ;==>_Decompress_Binary_String_to_Bitmap

Func _Icon_Image_Checkbox_Unchecked()
    Local $Base64String
    $Base64String &= '7rBIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAANfc3ADZ3t4AANvg4ADe4uIAAOLl5QDl6OgAAOns7ADs7+8AAO/x8QDx8/MAAPT19QD29/cAAPj5+QD6+/sAAPz9/QD+/v7wAP///xNc/wB/AD8A/z8APwA/AD8APwA/AD8ACAAb4HYLAAEJAOEBCgsMAA0ODxAREhISbeIBCQcC4gEIBwLiAQfbBwLiAQYHAuIBBQcC4gG2BAcC4gEDBwLiAQIHAv/jAQcC5AEGAuIB7BceAOCfHgN/AG0A4QZhAA=='
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Unchecked

Func _Icon_Image_Checkbox_Checked()
    Local $Base64String
    $Base64String &= 'z7BIAAABABAQEAFwCAAAaAUAABYAAMwAKAAYAJAAIAAYAVwZAQBAAQIYDgCAgAAAAISEhADe3t5AAN7n5wDnAQbvCO8A7wEG9/cA9/EABv///xN4/wE/AD8A/z8APwA/AD8AHwAMAOB6CwAGAQkA4QEHCAkJCR4KAgDjAQcC5AEHCAKDAwLiAQYHBwICAwI54gEFBsABAwLjAQUCxgIkBOIBBAUCRQbjAVgEBQUCAuQBAwUCCPPkAQUCBwjkAQYC4gHsF3seAOCfA38AbQDhBmEA'
    Return _Decompress_Binary_String_to_Bitmap(_Base64Decode($Base64String))
EndFunc   ;==>_Icon_Image_Checkbox_Checked

Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
    If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode
Edited by rover
1 person likes this

I see fascists...

Share this post


Link to post
Share on other sites

@rover

What kind of sourcery is this??!? ;)

Posted Image

Once again, thank you thank you thank you.


Share this post


Link to post
Share on other sites

I've added _GUICtrlListView_GetStringWidth to the example


I see fascists...

Share this post


Link to post
Share on other sites

Very nice examples rover! ;)

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

ahahahah that was exactly what I was trying to figure out ;)

your approach here is very interesting!


Share this post


Link to post
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