Sign in to follow this  
Followers 0
BugFix

ListView - for every SubItem set color, backcol and font

52 posts in this topic

#1 ·  Posted (edited)

Look at the Final Version (Link)

Hi,

based on this example i've made a workaround to set/unset color and format for every SubItem in an ListView.

Edit 6, 2009-08-30

Now i want to summarize all written before.

The example shows how it's possible set different font and text-/back color for SubItems.

Really it's only one function that user need: _SetItemParam()

All other stuff works in the background.

The example is commented, so its easyer for you, to understand how it's work.

Now also fixed the problem with other IDs by shifting the IParam value.

I let stay the old examples, but current is now: LV_Format.au3

Edit 7, 2009-09-27

Some basic things are changed.

- limitation of column count are fixed

- management for items integrated - no trouble with new item, deleting and so on

- now you can sort listview with formatted item

Example in post #8.

..and 2nd edit today

For more user friendly work, i've exported functions and global vars in an include file.

Details see in post #10.

#cs ===============================================================================================
    Functions

    _SetItemParam($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
        set params for an defined SubItem
        set off by calling with defaults

    _SetRowParam($hWnd, $iItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
        set params for one Row  by calling _SetItemParam in an loop for accordingly SubItem
        set off by calling with defaults

    _SetColumnParam($hWnd, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
        set params for one Column by calling _SetItemParam in an loop for accordingly SubItem
        set off by calling with defaults

    New settings are overwriting older ones.
    It's required to create listview with:  GUICtrlCreateListView().
    The state, if SubItem are formatted, are stored in IParam of every Item.
    IParam value are shifted to avoid complications with other (lower) Control-IDs.
    In moment i use only positive Values in IParam. So the count of columns are limitd by 31.
    If you want to use more columns, feel free to modulate the IParam management. :D

#ce ===============================================================================================

#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)

#region - GUI
$GUI = GUICreate("Listview Custom Draw         [ You can choose element by leftclick ]", 600, 440)
GUISetOnEvent($GUI_EVENT_CLOSE, '_exit')
$cListView1 = GUICtrlCreateListView("", 2, 2, 290, 250, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
$hListView1 = GUICtrlGetHandle($cListView1)
_GUICtrlListView_InsertColumn($hListView1, 0, "Column 1", 90)
_GUICtrlListView_InsertColumn($hListView1, 1, "Column 2", 90)
_GUICtrlListView_InsertColumn($hListView1, 2, "Column 3", 90)
$cListView2 = GUICtrlCreateListView("", 300, 2, 290, 250, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
$hListView2 = GUICtrlGetHandle($cListView2)
_GUICtrlListView_InsertColumn($hListView2, 0, "Column 1", 90)
_GUICtrlListView_InsertColumn($hListView2, 1, "Column 2", 90)
_GUICtrlListView_InsertColumn($hListView2, 2, "Column 3", 90)
For $i = 1 To 30 ; fill both LV
    _GUICtrlListView_AddItem($hListView1, "Row" & $i & ": Col 1", $i-1)
    _GUICtrlListView_AddItem($hListView2, "Row" & $i & ": Col 1", $i-1)
    For $j = 1 To 2
        _GUICtrlListView_AddSubItem ($hListView1, $i-1, "Row" & $i & ": Col " & $j+1, $j)
        _GUICtrlListView_AddSubItem ($hListView2, $i-1, "Row" & $i & ": Col " & $j+1, $j)
    Next
Next
GUICtrlCreateGroup(' Settings for ', 2, 255, 590, 40)
$rLV1 = GUICtrlCreateRadio('ListView 1', 130, 270, 150, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
$rLV2 = GUICtrlCreateRadio('ListView 2', 430, 270, 150, 17)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup(' Settings ', 2, 315, 290, 120)
GUICtrlCreateLabel('Item', 32, 332, 50, 17)
GUICtrlCreateLabel('or Row', 32, 344, 50, 17)
$inItem = GUICtrlCreateInput('10', 80, 334, 25, 20)
GUICtrlCreateLabel('SubItem', 116, 332, 45, 17)
GUICtrlCreateLabel('or Column', 116, 344, 50, 17)
$inSubItem = GUICtrlCreateInput('1', 175, 334, 25, 20)
GUICtrlCreateLabel('( 0-Index )', 215, 337, 50, 17)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup(' Single Item ', 320, 315, 90, 120)
$btSet = GUICtrlCreateButton('Set', 340, 350, 50, 20)
GUICtrlSetOnEvent(-1, '_btSet')
$btOff = GUICtrlCreateButton('Off', 340, 390, 50, 20)
GUICtrlSetOnEvent(-1, '_btOff')
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateLabel('Bk-Color', 32, 370, 40, 17)
$inBkCol = GUICtrlCreateInput('0x3DF8FF', 80, 368, 60, 20)
GUICtrlCreateLabel('Color', 160, 370, 40, 17)
$inCol = GUICtrlCreateInput('0xFF0000', 200, 368, 60, 20)
GUICtrlCreateLabel('Font', 32, 405, 40, 17)
$inFont = GUICtrlCreateInput('14,600,Comic Sans MS', 80, 402, 180, 20)
GUICtrlCreateGroup(' Columns or rows ', 440, 315, 150, 120)
$rOneRow = GUICtrlCreateRadio('Single Row', 450, 340, 130)
GUICtrlSetState(-1, $GUI_CHECKED)
$rOneCol = GUICtrlCreateRadio('Single Column', 450, 370, 130)
$btSet2 = GUICtrlCreateButton('Set', 450, 407, 50, 18)
GUICtrlSetOnEvent(-1, '_btSetRorC')
$btOff2 = GUICtrlCreateButton('Off', 530, 407, 50, 18)
GUICtrlSetOnEvent(-1, '_btOffRorC')
GUICtrlCreateGroup('', -99, -99, 1, 1)
#endregion - GUI

#region - Global settings (needed, whenever you want to use formatting)
; create an array for every LV with same count of elements like in LV
; IMPORTANT:
; By deleting an LV-Item it's required to delete also the according item from array!
; Also by insert an item in LV or sort LV you must modulate the array!
; [Item][SubItem][0] = iBkCol
; [Item][SubItem][1] = iCol
; [Item][SubItem][2] = iSize
; [Item][SubItem][3] = iWeight
; [Item][SubItem][4] = sFont
Global $aLV1[_GUICtrlListView_GetItemCount($hListView1)][_GUICtrlListView_GetColumnCount($hListView1)][5]
Global $aLV2[_GUICtrlListView_GetItemCount($hListView2)][_GUICtrlListView_GetColumnCount($hListView2)][5]
; create array to hold ListView-handle and accordingly array
Global $ahWndSets[2][2] = [[$hListView1,$aLV1],[$hListView2,$aLV2]]
Global $lvParam, $hFont, $defColLV = 0x000000, $defBkColLV = 0xFFFFFF
Global Const $INDEXSHIFT = 9999 ; need to avoid complications with other (lower) Control-ID
#endregion - Global settings

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $GUI)

While True
    Sleep(100)
WEnd

Func _exit()
    _WinAPI_DeleteObject($hFont)
    Exit
EndFunc  ;==>_exit

Func _GetLV() ; return currently choosed listview
    If BitAND(GUICtrlRead($rLV1), $GUI_CHECKED) Then
        Return $hListView1
    Else
        Return $hListView2
    EndIf
EndFunc  ;==>_GetLV

Func _SetInput($aRet) ; in example: set radio state, item, subitem if clicked in listview
    If $aRet[0] = $hListView1 Then
        GUICtrlSetState($rLV1, $GUI_CHECKED)
    Else
        GUICtrlSetState($rLV2, $GUI_CHECKED)
    EndIf
    GUICtrlSetData($inItem, $aRet[1])
    GUICtrlSetData($inSubItem, $aRet[2])
EndFunc

Func _btSet() ; in example: set format for an single SubItem
    $setIndex = GUICtrlRead($inItem)
    $setSubIndex = GUICtrlRead($inSubItem)
    If ($setIndex <> '' And $setSubIndex <> '') Then
        Local $aFont = StringSplit(GUICtrlRead($inFont), ',')
        _SetItemParam(_GetLV(), $setIndex, $setSubIndex, GUICtrlRead($inBkCol), GUICtrlRead($inCol), $aFont[1], $aFont[2], $aFont[3])
    EndIf
EndFunc  ;==>_btSet

Func _btOff() ; in example: set format for an single SubItem off
    $setIndex = GUICtrlRead($inItem)
    $setSubIndex = GUICtrlRead($inSubItem)
    If ($setIndex <> '' And $setSubIndex <> '') And BitAND(__GUICtrlListView_GetItemParam(_GetLV(), $setIndex), 2^$setSubIndex) Then _
        _SetItemParam(_GetLV(), $setIndex, $setSubIndex, -1, -1, -1, -1, -1)
EndFunc  ;==>_btOff

Func _btSetRorC() ; in example: set format for one Row or Column
    If BitAND(GUICtrlRead($rOneRow), $GUI_CHECKED) Then
        $setIndex = GUICtrlRead($inItem)
        If $setIndex = '' Then Return
        _GUICtrlListView_BeginUpdate(_GetLV())
        Local $aFont = StringSplit(GUICtrlRead($inFont), ',')
        _SetRowParam(_GetLV(), $setIndex, GUICtrlRead($inBkCol), GUICtrlRead($inCol), $aFont[1], $aFont[2], $aFont[3])
        _GUICtrlListView_EndUpdate(_GetLV())
    Else
        $setSubIndex = GUICtrlRead($inSubItem)
        If $setSubIndex = '' Then Return
        _GUICtrlListView_BeginUpdate(_GetLV())
        Local $aFont = StringSplit(GUICtrlRead($inFont), ',')
        _SetColumnParam(_GetLV(), $setSubIndex, GUICtrlRead($inBkCol), GUICtrlRead($inCol), $aFont[1], $aFont[2], $aFont[3])
        _GUICtrlListView_EndUpdate(_GetLV())
    EndIf
EndFunc  ;==>_btSetRorC

Func _btOffRorC() ; in example: set format for one Row or Column off
    If BitAND(GUICtrlRead($rOneRow), $GUI_CHECKED) Then
        $setIndex = GUICtrlRead($inItem)
        If $setIndex = '' Then Return
        _GUICtrlListView_BeginUpdate(_GetLV())
        _SetRowParam(_GetLV(), $setIndex, -1, -1, -1, -1, -1)
        _GUICtrlListView_EndUpdate(_GetLV())
    Else
        $setSubIndex = GUICtrlRead($inSubItem)
        If $setSubIndex = '' Then Return
        _GUICtrlListView_BeginUpdate(_GetLV())
        _SetColumnParam(_GetLV(), $setSubIndex, -1, -1, -1, -1, -1)
        _GUICtrlListView_EndUpdate(_GetLV())
    EndIf
EndFunc  ;==>_btOffRorC

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView1, $hListView2
            Switch $iCode
                Case $NM_CLICK ; only to set index to input in example
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $aRet[3] = [$hWndFrom, DllStructGetData($tInfo, "Index"), DllStructGetData($tInfo, "SubItem")]
                    Return _SetInput($aRet)
                Case $NM_CUSTOMDRAW
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage, $iItem, $iSubitem, $hDC, $tRect
                    $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage')
                    Switch $iDrawStage
                        Case $CDDS_ITEMPREPAINT
                            Return $CDRF_NOTIFYSUBITEMDRAW
                        Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                            $iItem = DllStructGetData($tCustDraw, 'dwItemSpec')
                            $iSubitem = DllStructGetData($tCustDraw, 'iSubItem')
                            If BitAND(__GUICtrlListView_GetItemParam($hWndFrom, $iItem), 2^$iSubitem) Then
                                _DrawItemCol($hDC, $tCustDraw, $hWndFrom, $iItem, $iSubitem)
                            Else
                                _DrawDefault($hDC, $tCustDraw)
                            EndIf
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

; use _SetItemParam() with defaults to set off
; to mark an SubItem as set, 2^SubItem-index are stored in ItemParam as sum for all SubItem,
; so the max. count of columns are 31 !!
Func _SetItemParam($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
    Local $accArray, $sumParam = 0
    For $i = 0 To UBound($ahWndSets) -1
        If $ahWndSets[$i][0] = $hWnd Then
            $accArray = $ahWndSets[$i][1] ; temp array
            ExitLoop
        EndIf
    Next
    If $iBkCol = -1 Then
        $iBkCol = $defBkColLV
        $sumParam += 1
    EndIf
    If $iCol = -1 Then
        $iCol = $defColLV
        $sumParam += 1
    EndIf
    If $iSize = -1 Then
        $iSize = 14
        $sumParam += 1
    EndIf
    If $iWeight = -1 Then
        $iWeight = 400
        $sumParam += 1
    EndIf
    If $sFont = -1 Then
        $sFont = 'Arial'
        $sumParam += 1
    EndIf
    $accArray[$iItem][$iSubItem][0] = $iBkCol
    $accArray[$iItem][$iSubItem][1] = $iCol
    $accArray[$iItem][$iSubItem][2] = $iSize
    $accArray[$iItem][$iSubItem][3] = $iWeight
    $accArray[$iItem][$iSubItem][4] = $sFont
    $ahWndSets[$i][1] = $accArray ; write back to original array
    ; if SubItem not registered in IParam OR all values by -1 (delete Sub from IParam) ==> switch Sub value in IParam
    If ( Not BitAND(__GUICtrlListView_GetItemParam($hWnd, $iItem), 2^$iSubItem) ) Or ( $sumParam = 5 ) Then _
        __GUICtrlListView_SetItemParam($hWnd, $iItem, BitXOR(__GUICtrlListView_GetItemParam($hWnd, $iItem), 2^$iSubItem))
    If BitAND(__GUICtrlListView_GetItemParam($hWnd, $iItem), 2^$iSubItem) Then _WinAPI_InvalidateRect($hWnd) ; only if values changed
EndFunc  ;==>_SetItemParam

Func _SetRowParam($hWnd, $iItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
    For $i = 0 To _GUICtrlListView_GetColumnCount($hWnd)-1
        _SetItemParam($hWnd, $iItem, $i, $iBkCol, $iCol, $iSize, $iWeight, $sFont)
    Next
EndFunc  ;==>_SetRowParam

Func _SetColumnParam($hWnd, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd)-1
        _SetItemParam($hWnd, $i, $iSubItem, $iBkCol, $iCol, $iSize, $iWeight, $sFont)
    Next
EndFunc  ;==>_SetColumnParam

Func _DrawItemCol(ByRef $hDC, ByRef $tCustDraw, $hWnd, $iItem, $iSubitem)
    Local $accArray
    For $i = 0 To UBound($ahWndSets) -1
        If $ahWndSets[$i][0] = $hWnd Then
            $accArray = $ahWndSets[$i][1]
            ExitLoop
        EndIf
    Next
    Local $aDefFont[14] = [14,0,0,0,$FW_NORMAL,False,False,False, _
          $DEFAULT_CHARSET,$OUT_DEFAULT_PRECIS,$CLIP_DEFAULT_PRECIS,$DEFAULT_QUALITY,0,'Arial']
    $aDefFont[0]  = $accArray[$iItem][$iSubItem][2]
    $aDefFont[4]  = $accArray[$iItem][$iSubItem][3]
    $aDefFont[13] = $accArray[$iItem][$iSubItem][4]
    $hDC = DllStructGetData($tCustDraw, 'hdc')
    DllStructSetData($tCustDraw, 'clrText', RGB2BGR($accArray[$iItem][$iSubItem][1]))
    DllStructSetData($tCustDraw, 'clrTextBk', RGB2BGR($accArray[$iItem][$iSubItem][0]))
    $hFont = _WinAPI_CreateFont($aDefFont[0],$aDefFont[1],$aDefFont[2],$aDefFont[3],$aDefFont[4],$aDefFont[5],$aDefFont[6], _
             $aDefFont[7],$aDefFont[8],$aDefFont[9],$aDefFont[10],$aDefFont[11],$aDefFont[12],$aDefFont[13])
    _WinAPI_SelectObject($hDC, $hFont)
EndFunc  ;==>_DrawItemCol

Func _DrawDefault(ByRef $hDC, ByRef $tCustDraw) ; draw unformatted item
    $hDC = DllStructGetData($tCustDraw, 'hdc')
    DllStructSetData($tCustDraw, 'clrText', RGB2BGR($defColLV))
    DllStructSetData($tCustDraw, 'clrTextBk', RGB2BGR($defBkColLV))
    $hFont = _WinAPI_CreateFont(14,0,0,0,$FW_NORMAL,False,False,False,$DEFAULT_CHARSET,$OUT_DEFAULT_PRECIS, _
            $CLIP_DEFAULT_PRECIS,$DEFAULT_QUALITY,0,'Arial')
    _WinAPI_SelectObject($hDC, $hFont)
EndFunc  ;==>_DrawDefault

Func __GUICtrlListView_GetItemParam($hWnd, $iItem) ; modified for use indexshift
    Local $param = _GUICtrlListView_GetItemParam($hWnd, $iItem)
    If $param > 0 Then $param -= $INDEXSHIFT
    Return $param
EndFunc

Func __GUICtrlListView_SetItemParam($hWnd, $iItem, $iParam) ; modified for use indexshift
    _GUICtrlListView_SetItemParam($hWnd, $iItem, $INDEXSHIFT + $iParam)
EndFunc

Func RGB2BGR($iColor)
    Local $sH = Hex($iColor,6)
    Return '0x' & StringRight($sH, 2) & StringMid($sH,3,2) & StringLeft($sH, 2)
EndFunc  ;==>RGB2BGR

Posted Image

FormatSubItemLV.au3

FormatSubItemLVex.au3

FormatSubItemLV_new.au3

LV_Format.au3

Edited by BugFix
1 person likes this

Best Regards BugFix  

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Awesome!

Cant understand why no one posts.

There are countless threads where people ask for coloring custom Listviewitems. And with this you could even set Subitems and Fonts.

No more dealing with slow internal GUICtrlSetBkColor and that stuff.

It would be freaking cool if this could find a way into AutoIt built in UDF's.

But i think this wont be not so easy because you always have to store the item infos in a separate Array.

Only think of the problem when you have two or more listviews where you want to set and update items independently.

Maybe using the $iParam of an Listviewitem as an direct index to the InfoArray? _GUICtrlListView_GetItemParam/SetItemParam

This would improve very much the performance cause you dont have to search the whole array anymore.

Edited by qsek

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi, see new example in post 1 for using with more than one listview in an gui at the same time.

Thans qsek for your reply. To use $iParam to get a better performance is a good idea. I'll test it at next.

Edited by BugFix

Best Regards BugFix  

Share this post


Link to post
Share on other sites

Really awesome Script! :P

i was waiting for that kind of script.


73 108 111 118 101 65 117 116 111 105 116

Share this post


Link to post
Share on other sites

Really awesome Script! :unsure:

i was waiting for that kind of script.

Thanks for your reply.

And now the next version is on! See first post - Edit5.

Whats different: shorter, faster :D

Some informations are stored in $iParam of ListViewItem. Thanks qsek for this idea.

But all this are written in my edit. Look at this please. :P


Best Regards BugFix  

Share this post


Link to post
Share on other sites

Thanks for your reply.

And now the next version is on! See first post - Edit5.

Whats different: shorter, faster :D

Some informations are stored in $iParam of ListViewItem. Thanks qsek for this idea.

But all this are written in my edit. Look at this please. :D

Your Marvelous MAN! :unsure:

Your UDF change the whole look of my project. :P


73 108 111 118 101 65 117 116 111 105 116

Share this post


Link to post
Share on other sites

- fixed possible complications with other IDs and IParam

See 1st post.


Best Regards BugFix  

Share this post


Link to post
Share on other sites

Next step are done:

- No limitation for column count! IParam stores now an int_ptr.

- Only one array stores all informations, also if several listview exists.

- Check if an (Sub)Item are formatted is now faster.

- Now you can also sort, insert, add, delete items without trouble to manage formatting informations. I've modified some functions, so they can do it for you. (i.e. _GUICtrlListView_SimpleSort - now it sorts also IParam!)

Enjoy it and give me please some feedback.

#cs
    To have no trouble with management of information about formatting, it's required to respect following:
    I've made or modified some functions, so that all information are accordingly with an Item all times will
    be connected with them. Wether if a new one created, an other deleted, position changed or listview are sorted.

    Add or insert new Listview Item:
        _GUICtrlListView_AddOrIns_Item($hWnd, $sText, $iItem=-1)
            $hWnd   Listview handle
            $sText  lonely string to set only Item text (than SubItem must set with _GUICtrlListView_AddSubItem)
                    or
                    "Item|SubItem|SubItem.." to set all text at once
            $iItem  Item index, if -1 a new Item will add at the end
                    otherwise
                    the Item will insert at index position

    Delete one, selected or all Item:
        __GUICtrlListView_DeleteItem($hWnd, $iIndex)
        __GUICtrlListView_DeleteItemsSelected($hWnd)
        __GUICtrlListView_DeleteAllItems($hWnd)

    Format Listview Item
        _SetItemParam($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
            $hWnd       Listview handle
            $iItem      Item index
            $iSubItem   SubItem index
            $iBkCol     back color (-1 = default BkCol)
            $iCol       text color (-1 = default txtCol)
            $iSize      height of font (-1 = 14)
            $iWeight    font weight    (-1 = 400)
            $sFont      typefont name  (-1 = Arial)

    Sort Listview:
        By default SimpleSort doesn't really sort Items - only Item-/SubItem text moves. Because that, IParam stands at same
        position like before. I've modified this function, so that IParam also will sorted.
        __GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol)


    NEW:
        - No limitation by column count!
        - All information stored in one array, also if severally Listview exists.
          That's why an variable is set as $maxColumn to hold maximum number of columns from all Listview.
        - Get index from array is now faster. An dictionary object stores IParam,array-index.
#ce
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>

Local $col = ''
For $i = 1 To 6
    $col &= $i & '|'
Next

$GUI = GUICreate('')
$lv = GUICtrlCreateListView(StringTrimRight($col,1), 10, 10, 300, 150)
$hLV = GUICtrlGetHandle($lv)
For $i = 0 To 5
    _GUICtrlListView_SetColumnWidth($hLV, $i, 49)
Next

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hLV)]


; if more than one LV get count column from LV with most columns
Global $maxColumn = _GUICtrlListView_GetColumnCount($hLV)
; Array to store infos about format, only one array - also if several LV
; [n][0][0]=ItemStruct, [n][1..Count][0..4]=SubItemValue
Global $aIParam[1][$maxColumn+1][5]
Global $oParamSearch = ObjCreate('Scripting.Dictionary') ; store for faster search (iParam, arrayIndex)
Global $hFont, $defColLV = 0x000000, $defBkColLV = 0xFFFFFF

; add new Items
_GUICtrlListView_AddOrIns_Item($hLV, 'Test0|Test1|Test2|Test3|Test4|Test5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blub0|Blub1|Blub2|Blub3|Blub4|Blub5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Club0|Club1|Club2|Club3|Club4|Club5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blab0|Blab1|Blab2|Blab3|Blab4|Blab5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Bumm0|Bumm1|Bumm2|Bumm3|Bumm4|Bumm5')

; set format
_SetItemParam($hLV, 0, 2, 0xff0000, -1, -1, 600, 'Times New Roman')
_SetItemParam($hLV, 1, 4, 0xffff00, -1, -1, 600, 'Comic Sans MS')
_SetItemParam($hLV, 1, 3, 0xff0000, -1, -1, 600, 'Times New Roman')


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $GUI)

Sleep(1000)
_SetItemParam($hLV, 1, 4) ; set format to default for Item at index 1, column-index 4

Sleep(1000)
__GUICtrlListView_DeleteItem($hLV, 1) ; delete Item at index 1

Sleep(1000)
__GUICtrlListView_DeleteAllItems($hLV)

Sleep(1000)
_GUICtrlListView_BeginUpdate($hLV)
_GUICtrlListView_AddOrIns_Item($hLV, 'Test0|Test1|Test2|Test3|Test4|Test5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blub0|Blub1|Blub2|Blub3|Blub4|Blub5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Club0|Club1|Club2|Club3|Club4|Club5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blab0|Blab1|Blab2|Blab3|Blab4|Blab5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Bumm0|Bumm1|Bumm2|Bumm3|Bumm4|Bumm5')
_GUICtrlListView_EndUpdate($hLV)
_SetItemParam($hLV, 0, 1, 0xff0000, -1, -1, 600, 'Times New Roman')
_SetItemParam($hLV, 1, 2, 0xffff00, -1, -1, 600, 'Comic Sans MS')
_SetItemParam($hLV, 2, 3, 0xff0000, -1, -1, 600, 'Times New Roman')

WinSetTitle($GUI, '', 'Now click column header to sort')

Do
Until GUIGetMsg() = -3
_WinAPI_DeleteObject($hFont)


#region - Listview handling (add/insert, delete)
Func _GUICtrlListView_AddOrIns_Item($hWnd, $sText, $iItem=-1)
    If Not IsHWnd($hWnd) Then
        $hWnd = GUICtrlGetHandle($hWnd)
    EndIf
    $sText = StringSplit($sText, '|')
    If $iItem < -1 Then
        $iItem = 0
    EndIf
    If $iItem > _GUICtrlListView_GetItemCount($hWnd)-1 Then
        $iItem = -1
    EndIf
    Local $cntCOL = _GUICtrlListView_GetColumnCount($hWnd)
    If $aIParam[UBound($aIParam)-1][0][0] <> '' Then
        ReDim $aIParam[UBound($aIParam)+1][$maxColumn+1][5]
    EndIf
    Local $tagITEMPARAM = "int_ptr;byte[" & $cntCOL & "];"
    Local $tITEMPARAM = DllStructCreate($tagITEMPARAM)
    DllStructSetData($tITEMPARAM, 1, DllStructGetPtr($tITEMPARAM, 2)) ; byte[col]
    $aIParam[UBound($aIParam)-1][0][0] = $tITEMPARAM
    $oParamSearch.Add(DllStructGetData($tITEMPARAM, 1), UBound($aIParam)-1) ; key=IParam, val=array-index
    For $i = 1 To $cntCOL
        DllStructSetData($tITEMPARAM, 2, 0, $i)
    Next
    If $iItem = -1 Then
        $iItem = _GUICtrlListView_AddItem($hWnd, $sText[1])
        _GUICtrlListView_SetItemParam($hWnd, $iItem, DllStructGetData($tITEMPARAM, 1))
    Else
        _GUICtrlListView_InsertItem($hWnd, $sText[1], $iItem)
        _GUICtrlListView_SetItemParam($hWnd, $iItem, DllStructGetData($tITEMPARAM, 1))
    EndIf
    If $sText[0] > 1 Then
        For $i = 2 To UBound($sText) -1
            _GUICtrlListView_AddSubItem($hWnd, $iItem, $sText[$i], $i-1)
        Next
    EndIf
EndFunc  ;==>_GUICtrlListView_AddOrIns_Item

Func __GUICtrlListView_DeleteItem($hWnd, $iIndex)
    Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $iIndex)
    $aIParam[$oParamSearch.Item($iParam)][0][0] = ''
    $oParamSearch.Remove($iParam)
    _GUICtrlListView_DeleteItem($hWnd, $iIndex)
EndFunc  ;==>__GUICtrlListView_DeleteItem

Func __GUICtrlListView_DeleteItemsSelected($hWnd)
    Local $aSelected = _GUICtrlListView_GetSelectedIndices($hWnd, True)
    For $i = 1 To $aSelected[0]
        Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $aSelected[$i])
        $aIParam[$oParamSearch.Item($iParam)][0][0] = ''
        $oParamSearch.Remove($iParam)
        _GUICtrlListView_DeleteItem($hWnd, $aSelected[$i])
    Next
EndFunc  ;==>__GUICtrlListView_DeleteItemsSelected

Func __GUICtrlListView_DeleteAllItems($hWnd)
    Local $item = _GUICtrlListView_GetItemCount($hWnd)
    For $i = 0 To $item -1
        Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $i)
        $aIParam[$oParamSearch.Item($iParam)][0][0] = ''
        $oParamSearch.Remove($iParam)
    Next
    _GUICtrlListView_DeleteAllItems($hWnd)
EndFunc  ;==>__GUICtrlListView_DeleteAllItems

#endregion

Func _SetItemParam($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
    Local $sumParam = 0
    Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $iItem)
    Local $index = $oParamSearch.Item($iParam)
    If $iBkCol = -1 Then
        $iBkCol = $defBkColLV
        $sumParam += 1
    EndIf
    If $iCol = -1 Then
        $iCol = $defColLV
        $sumParam += 1
    EndIf
    If $iSize = -1 Then
        $iSize = 14
        $sumParam += 1
    EndIf
    If $iWeight = -1 Then
        $iWeight = 400
        $sumParam += 1
    EndIf
    If $sFont = -1 Then
        $sFont = 'Arial'
        $sumParam += 1
    EndIf
    $aIParam[$index][$iSubItem+1][0] = $iBkCol
    $aIParam[$index][$iSubItem+1][1] = $iCol
    $aIParam[$index][$iSubItem+1][2] = $iSize
    $aIParam[$index][$iSubItem+1][3] = $iWeight
    $aIParam[$index][$iSubItem+1][4] = $sFont
    ; if SubItem not registered in IParam OR all values by -1 (delete Sub from IParam) ==> switch Sub value in IParam
    Local $mark = DllStructGetData($aIParam[$index][0][0], 2, $iSubItem+1)
    If Not $mark Or $sumParam = 5 Then
        DllStructSetData($aIParam[$index][0][0], 2, BitXOR($mark, 1), $iSubItem+1)
    EndIf
    If DllStructGetData($aIParam[$index][0][0], 2, $iSubItem+1) <> $mark Then
        _GUICtrlListView_RedrawItems($hWnd, $iItem, $iItem)
    EndIf
EndFunc  ;==>_SetItemParam

Func _DrawItemCol(ByRef $hDC, ByRef $tCustDraw, $hWnd, $iItem, $iSubitem) ; draw formatted item
    Local $aDefFont[14] = [14,0,0,0,$FW_NORMAL,False,False,False, _
          $DEFAULT_CHARSET,$OUT_DEFAULT_PRECIS,$CLIP_DEFAULT_PRECIS,$DEFAULT_QUALITY,0,'Arial']
    $aDefFont[0]  = $aIParam[$iItem][$iSubItem+1][2]
    $aDefFont[4]  = $aIParam[$iItem][$iSubItem+1][3]
    $aDefFont[13] = $aIParam[$iItem][$iSubItem+1][4]
    $hDC = DllStructGetData($tCustDraw, 'hdc')
    DllStructSetData($tCustDraw, 'clrText', RGB2BGR($aIParam[$iItem][$iSubItem+1][1]))
    DllStructSetData($tCustDraw, 'clrTextBk', RGB2BGR($aIParam[$iItem][$iSubItem+1][0]))
    $hFont = _WinAPI_CreateFont($aDefFont[0],$aDefFont[1],$aDefFont[2],$aDefFont[3],$aDefFont[4],$aDefFont[5],$aDefFont[6], _
             $aDefFont[7],$aDefFont[8],$aDefFont[9],$aDefFont[10],$aDefFont[11],$aDefFont[12],$aDefFont[13])
    _WinAPI_SelectObject($hDC, $hFont)
EndFunc  ;==>_DrawItemCol

Func _DrawDefault(ByRef $hDC, ByRef $tCustDraw) ; draw unformatted item
    $hDC = DllStructGetData($tCustDraw, 'hdc')
    DllStructSetData($tCustDraw, 'clrText', RGB2BGR($defColLV))
    DllStructSetData($tCustDraw, 'clrTextBk', RGB2BGR($defBkColLV))
    $hFont = _WinAPI_CreateFont(14,0,0,0,$FW_NORMAL,False,False,False,$DEFAULT_CHARSET,$OUT_DEFAULT_PRECIS, _
            $CLIP_DEFAULT_PRECIS,$DEFAULT_QUALITY,0,'Arial')
    _WinAPI_SelectObject($hDC, $hFont)
EndFunc  ;==>_DrawDefault

Func _getMarked($hWnd, $iItem, $iSubItem)
    If Not IsHWnd($hWnd) Then
        $hWnd = GUICtrlGetHandle($hWnd)
    EndIf
    Local $cntCOL = _GUICtrlListView_GetColumnCount($hWnd)
    Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $iItem)
    Local $struct = DllStructCreate("byte[" & $cntCOL & "]", $iParam)
    If DllStructGetData($struct, 1, $iSubItem+1) Then
        Return $oParamSearch.Item($iParam)
    Else
        Return -1
    EndIf
EndFunc  ;==>_getMarked

Func RGB2BGR($iColor)
    Local $sH = Hex($iColor,6)
    Return '0x' & StringRight($sH, 2) & StringMid($sH,3,2) & StringLeft($sH, 2)
EndFunc  ;==>RGB2BGR

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hLV
            Switch $iCode
                Case $LVN_COLUMNCLICK
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    __GUICtrlListView_SimpleSort($hWndFrom, $B_DESCENDING, DllStructGetData($tInfo, "SubItem"))
                Case $NM_CUSTOMDRAW
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage, $iItem, $iSubitem, $hDC, $tRect
                    $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage')
                    Switch $iDrawStage
                        Case $CDDS_ITEMPREPAINT
                            Return $CDRF_NOTIFYSUBITEMDRAW
                        Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                            $iItem = DllStructGetData($tCustDraw, 'dwItemSpec')
                            $iSubitem = DllStructGetData($tCustDraw, 'iSubItem')
                            Local $index = _getMarked($hWndFrom, $iItem, $iSubitem)
                            If $index = -1 Then
                                _DrawDefault($hDC, $tCustDraw)
                            Else
                                _DrawItemCol($hDC, $tCustDraw, $hWndFrom, $index, $iSubitem)
                            EndIf
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func __GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol) ; modified to sort also IParam
    If $Debug_LV Then _GUICtrlListView_ValidateClassName($hWnd)
    Local $x, $Y, $Z, $b_desc, $columns, $items, $v_item, $temp_item, $iFocused = -1
    Local $SeparatorChar = Opt('GUIDataSeparatorChar')
    If _GUICtrlListView_GetItemCount($hWnd) Then
        If (IsArray($vDescending)) Then
            $b_desc = $vDescending[$iCol]
        Else
            $b_desc = $vDescending
        EndIf
        $columns = _GUICtrlListView_GetColumnCount($hWnd)
        $items = _GUICtrlListView_GetItemCount($hWnd)
        For $x = 1 To $columns
            $temp_item = $temp_item & " " & $SeparatorChar
        Next
        $temp_item = StringTrimRight($temp_item, 1)
;~      Local $a_lv[$items][$columns + 1], $i_selected
        Local $a_lv[$items][$columns + 2], $i_selected ; add column for IParam  ### MODIFIED ###

        $i_selected = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $SeparatorChar)
        For $x = 0 To UBound($a_lv) - 1 Step 1
            If $iFocused = -1 Then
                If _GUICtrlListView_GetItemFocused($hWnd, $x) Then $iFocused = $x
            EndIf
            _GUICtrlListView_SetItemSelected($hWnd, $x, False)
;~          _GUICtrlListView_SetItemState($hWnd, $x, 0, BitOR($LVIS_SELECTED, $LVIS_FOCUSED))
;~          For $Y = 0 To UBound($a_lv, 2) - 2 Step 1
            For $Y = 0 To UBound($a_lv, 2) - 3 Step 1  ;  ### MODIFIED ###
                $v_item = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $x, $Y), 2)
                If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then
                    $a_lv[$x][$Y] = Number($v_item)
                Else
                    $a_lv[$x][$Y] = $v_item
                EndIf
            Next
            $a_lv[$x][$Y] = $x
            $a_lv[$x][$Y+1] = _GUICtrlListView_GetItemParam($hWnd, $x)  ;  ### NEW ###
        Next
        _ArraySort($a_lv, $b_desc, 0, 0, $iCol)
        For $x = 0 To UBound($a_lv) - 1 Step 1
;~          For $Y = 0 To UBound($a_lv, 2) - 2 Step 1
            For $Y = 0 To UBound($a_lv, 2) - 3 Step 1  ;  ### MODIFIED ###
;~              _GUICtrlListViewSetItemText($hWnd, $x, $Y, $a_lv[$x][$Y])
                _GUICtrlListView_SetItemText($hWnd, $x, $a_lv[$x][$Y], $Y)
            Next
            _GUICtrlListView_SetItemParam($hWnd, $x, $a_lv[$x][$Y+1])  ;  ### NEW ###
            For $Z = 1 To $i_selected[0]
;~              If $a_lv[$x][UBound($a_lv, 2) - 1] = $i_selected[$Z] Then
                If $a_lv[$x][UBound($a_lv, 2) - 2] = $i_selected[$Z] Then  ;  ### MODIFIED ###
;~                  If $a_lv[$x][UBound($a_lv, 2) - 1] = $iFocused Then
                    If $a_lv[$x][UBound($a_lv, 2) - 2] = $iFocused Then  ;  ### MODIFIED ###
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True, True)
                    Else
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True)
                    EndIf
;~                  _GUICtrlListView_SetItemState($hWnd, $x, $LVIS_SELECTED, BitOR($LVIS_SELECTED, $LVIS_FOCUSED))
;~                  If $a_lv[$x][UBound($a_lv, 2) - 1] = $iFocused Then _GUICtrlListView_SetItemState($hWnd, $x, $LVIS_FOCUSED, $LVIS_FOCUSED)
                    ExitLoop
                EndIf
            Next
        Next
        If (IsArray($vDescending)) Then
            $vDescending[$iCol] = Not $b_desc
        Else
            $vDescending = Not $b_desc
        EndIf
    EndIf
EndFunc   ;==>__GUICtrlListView_SimpleSort

5_LV_Format.au3


Best Regards BugFix  

Share this post


Link to post
Share on other sites

Thanks for your stars. :D

But it was too much code in one script.

Because that i've done all management functions and global vars in an include file.

So it will more user friendly and easy to use.

You must only

- include 'LV_Format_include.au3'

- startup (initialize global vars)

- add, insert, delete..

- set format

- write WM_NOTIFY

- at end: shutdown

I think, so can everyone use this.

Example:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
#include 'LV_Format_include.au3'


Local $col = ''
For $i = 1 To 6
    $col &= $i & '|'
Next

$GUI = GUICreate('')
$lv = GUICtrlCreateListView(StringTrimRight($col,1), 10, 10, 300, 150)
$hLV = GUICtrlGetHandle($lv)
For $i = 0 To 5
    _GUICtrlListView_SetColumnWidth($hLV, $i, 49)
Next

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hLV)]

; initialize Global vars
_LVFormatting_Startup($hLV)

; add new Items
_GUICtrlListView_AddOrIns_Item($hLV, 'Test0|Test1|Test2|Test3|Test4|Test5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blub0|Blub1|Blub2|Blub3|Blub4|Blub5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Club0|Club1|Club2|Club3|Club4|Club5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blab0|Blab1|Blab2|Blab3|Blab4|Blab5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Bumm0|Bumm1|Bumm2|Bumm3|Bumm4|Bumm5')

; set format
_SetItemParam($hLV, 0, 2, 0xff0000, -1, -1, 600, 'Times New Roman')
_SetItemParam($hLV, 1, 4, 0xffff00, -1, -1, 600, 'Comic Sans MS')
_SetItemParam($hLV, 1, 3, 0xff0000, -1, -1, 600, 'Times New Roman')


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $GUI)

Sleep(1000)
_SetItemParam($hLV, 1, 4) ; set format to default for Item at index 1, column-index 4

Sleep(1000)
__GUICtrlListView_DeleteItem($hLV, 1) ; delete Item at index 1

Sleep(1000)
__GUICtrlListView_DeleteAllItems($hLV)

Sleep(1000)
_GUICtrlListView_BeginUpdate($hLV)
_GUICtrlListView_AddOrIns_Item($hLV, 'Test0|Test1|Test2|Test3|Test4|Test5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blub0|Blub1|Blub2|Blub3|Blub4|Blub5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Club0|Club1|Club2|Club3|Club4|Club5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Blab0|Blab1|Blab2|Blab3|Blab4|Blab5')
_GUICtrlListView_AddOrIns_Item($hLV, 'Bumm0|Bumm1|Bumm2|Bumm3|Bumm4|Bumm5')
_GUICtrlListView_EndUpdate($hLV)
_SetItemParam($hLV, 0, 1, 0xff0000, -1, -1, 600, 'Times New Roman')
_SetItemParam($hLV, 1, 2, 0xffff00, -1, -1, 600, 'Comic Sans MS')
_SetItemParam($hLV, 2, 3, 0xff0000, -1, -1, 600, 'Times New Roman')

WinSetTitle($GUI, '', 'Now click column header to sort')

Do
Until GUIGetMsg() = -3
; clear ressources
_LVFormatting_Shutdown()


Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hLV
            Switch $iCode
                Case $LVN_COLUMNCLICK
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    __GUICtrlListView_SimpleSort($hWndFrom, $B_DESCENDING, DllStructGetData($tInfo, "SubItem"))
                Case $NM_CUSTOMDRAW
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage, $iItem, $iSubitem, $hDC, $tRect
                    $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage')
                    Switch $iDrawStage
                        Case $CDDS_ITEMPREPAINT
                            Return $CDRF_NOTIFYSUBITEMDRAW
                        Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                            $iItem = DllStructGetData($tCustDraw, 'dwItemSpec')
                            $iSubitem = DllStructGetData($tCustDraw, 'iSubItem')
                            Local $index = _getMarked($hWndFrom, $iItem, $iSubitem)
                            If $index = -1 Then
                                _DrawDefault($hDC, $tCustDraw)
                            Else
                                _DrawItemCol($hDC, $tCustDraw, $hWndFrom, $index, $iSubitem)
                            EndIf
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

LV_Format_include.au3

Example_LV_Format.au3


Best Regards BugFix  

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Hi,

i think, this should be an Final Version. :)

Function names now also like in Listview-UDF. All things exported to an include file, WM_NOTIFY also.

You can formatting one or more listview at the same time. They can be at several GUI, only function to change default values needs the GUI handle.

Functions

Initialize Global vars at startup

_GUICtrlListView_Formatting_Startup($hGUI, $hListView)

$hGUI Handle of your GUI

$hListView Listview handle, for several LV commit handle's as array

Clean up ressources

_GUICtrlListView_Formatting_Shutdown() now automatically called on AutoIt exit

Add or insert new Listview Item

_GUICtrlListView_AddOrIns_Item($hWnd, $vText, $iItem=-1)

$hWnd Listview handle

$vText lonely string to set only Item text (than SubItem must set with _GUICtrlListView_AddSubItem)

or

"Item|SubItem|SubItem.." to set all text at once

or

an array with this strings to set more than one item at once

$iItem Item index, if -1 a new Item/Item-array will add at the end (default)

otherwise

the Item/Item-array will insert at index position

Delete one, selected or all Item

_GUICtrlListView_FormattedDeleteItem($hWnd, $iIndex)

_GUICtrlListView_FormattedDeleteItemsSelected($hWnd)

_GUICtrlListView_FormattedDeleteAllItems($hWnd)

Set defaults

_GUICtrlListView_DefaultsSet($iBkCol=0xFFFFFF, $iCol=0x000000, $iSize=14, $iWeight=400, $sFont='Arial')

$iBkCol back color default white

$iCol text color default black

$iSize font size default 14

$iWeight font weight default 400

$sFont font name default Arial

Get defaults

_GUICtrlListView_DefaultsGet()

Return: [$iBkCol, $iCol, $iSize, $iWeight, $sFont]

Format Listview Item

_GUICtrlListView_FormattingCell($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)

$hWnd Listview handle

$iItem Item index

$iSubItem SubItem index

$iBkCol back color (-1 = default BkCol)

$iCol text color (-1 = default txtCol)

$iSize height of font (-1 = 14)

$iWeight font weight (-1 = 400)

$sFont typefont name (-1 = Arial)

Edit

Now i've added a little script to complete your SciTE calltips with this functions.

Edit 06.08.2011

Important!

I've made some changes to avoid possible conflicts and make working easier.

- I hook now WM_NOTIFY, so that this message also can used with GuiRegisterMsg in the main script.

- The value to store with "_GUICtrlListView_SetItemParam" is now always increased at 2000. If you have a lot of controls (i.e. hundreds of item in other listviews), you could collide with an ItemParam lower as 2000.

- Now you have a Global array variable ( $FORMATLV_aITEM_INDEX ), filled with values in WM_NOTIFY() by right click at an item. It holds information about the clicked item. For details and using, see function _RightClick() inside "Example_LV_Format.au3".

- Function _GUICtrlListView_Formatting_Shutdown() now automatically called on AutoIt exit.

Edit 10.08.2011

current version: 1.3

- Sorry for an mistake: in version 1.1 i've "lost" one script line and so the text object has had no DC-handle :)

Some changes to get better speed:

- Function to create Listview entries (_GUICtrlListView_AddOrIns_Item) accepts now arrays.

I've tested with 10000 item (6 column). In single call mode it needs 2240 sec, commit an array needs the same only 87 sec.

- Painting cells again, now only happens if there is an different style or color to the previous cell.

- Always in version 1.1, but I've forgot to say:

Get defaults with: _GUICtrlListView_DefaultsGet()

Return: [$iBkCol, $iCol, $iSize, $iWeight, $sFont]

LV_Format_calltips.au3

LV_Format_include1.3.au3

Example_LV_Format1.1.au3

Edited by BugFix

Best Regards BugFix  

Share this post


Link to post
Share on other sites

Hi, haven't tried it yet..

But wow, nice job.

You can see that great thought has been given to the way you've written it all.

I can't believe there hasn't been more feedback as of yet.

I could have used exactly this a few times in the past already.

Can't wait till I do a project where I need it.

Thank You 'n' Cheers

Share this post


Link to post
Share on other sites

I'm getting an error when running with the latest beta. It happens as soon as I click a header.

C:\Program Files (x86)\AutoIt3\beta\Include\Array.au3 (1171) : ==> Array variable subscript badly formatted.:

Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[int(($iStart + $iEnd) / 2)][$iSubItem], $fNum = IsNumber($vPivot)

Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[int(($iStart + $iEnd) / 2)][^ ERROR

Also, I'm not seeing any colors before that :) I think a few things might have changed in the latest beta..

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites

I'm getting an error when running with the latest beta. It happens as soon as I click a header.

Also, I'm not seeing any colors before that :) I think a few things might have changed in the latest beta..

I don't use beta for scripts, which i publish. And so i have not tested it with beta version.

But its more interesting to see, which code u've used. The error description gives not enough information to localize the problem.


Best Regards BugFix  

Share this post


Link to post
Share on other sites

This works great on my Win XP 32b machine.

Doesn't work with my Vista 64b one.

I'm guessing the WinAPI doesn't work with Vista?

Share this post


Link to post
Share on other sites

I'm getting an error when running with the latest beta.

So, now i've tested with beta version too. (current 3.3.1.5)

My example works fine. I got some error messages from AU3Check, but i think this function is'nt actualized for current version. If i ignore this messages, it works without errors.


Best Regards BugFix  

Share this post


Link to post
Share on other sites

Wow, these scripts are certainly my best forum downloads till this date!

A remark for the author: I think it would be better/safer if the supplied au3 had a (internal) version number.

Two remarks for interested users:

1) Although amazing this script is. It is not perfect. Sometimes the applied colours do not show. But the applied colours are really there! Only after (partitial) scrolling they show.

2) In the script is a "GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_LV_FORMAT")" !

So if you've written (or downloaded ;-)) another "GUIRegisterMsg($WM_NOTIFY" ,"own_function"), you can expect problems. In my case the doubleclick-on-a-row did not function any more (I've programmed it to show some more details that the listview contains). Using both different "$WM_NOTIFY"-functions was not a succes. Finally I copied (and modified) my own coding into LV_Format_include.au3. This seems to work fine.

Share this post


Link to post
Share on other sites

Hi BugFix,

I'm so happy about the listview formatter you prepared.

Really appreciate your effort on that, this is good stuff.

However, I'm having problem on redrawing/memory overflow, I was wondering if you could help me on this...

I wanted to give stress to the interface, and when massively resizing the GUI to force the listview to redraw for 10-20 seconds,

screen becomes all gray/interface top menu bar become gray,... like it needs a redrawing.

So, I added a winapi_redraw window in a 15 seconds timer.

But it won't do it.

Tried disabling resizing option, then stress scrolling the listview,... strange result too, top menu subitems background was black. Tried to take a screenshot, but got a Insufficient Memory error message from Windows...

I prepared a standalone snippets so you can try it and give me your impression..

All you gotta go is to scroll massively for 10-15 seconds and then change the focus to another window...

All your help/comment will be appreciated. Thanks in advance.

hench :(

#include "GuiListView.au3"
#include "ListViewConstants.au3"
#include <WindowsConstants.au3>
#include <Constants.au3>
#include "LV_Format_include.au3"

Global $hGui = GUICreate("Test",750,600,200,200)

Global $MAIN_lvNoSerie = GUICtrlCreateListView("", 5, 24, 715, 475, BitOR($LVS_SINGLESEL, $LVS_REPORT), $LVS_EX_FULLROWSELECT)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

For $x = 0 To 16
    _GUICtrlListView_InsertColumn($MAIN_lvNoSerie, $x, $x, 50)
Next

Local $nMsg, $aArray[11][18]
$aArray[0][0]=0

For $x = 1 To 10
    $aArray[0][0]+=1
    For $y = 1 To 16
        $aArray[$x][$y] = Random(10000,99999,1)
    Next
Next

__Remplir_ListView_NoSerie($aArray)
GUISetState(@SW_SHOW)
while 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
                ExitLoop

    EndSwitch
    Sleep(10)
WEnd

_GUICtrlListView_Formatting_Shutdown()
Exit

Func __Remplir_ListView_NoSerie($Array)

    GUICtrlSetState($MAIN_lvNoSerie, $GUI_HIDE)

    _GUICtrlListView_BeginUpdate($MAIN_lvNoSerie)
    _GUICtrlListView_DeleteAllItems($MAIN_lvNoSerie)
    If $Array[0][0] > 0 Then
        Local $sStringAjout = ""

        _GUICtrlListView_Formatting_Startup($hGui, $MAIN_lvNoSerie)
        For $x = 1 To $Array[0][0]
            ;_GUICtrlListView_InsertItem($MAIN_lvNoSerie,$Array[$x][0])
            For $y = 0 To 16
                If $y = 16 Then
                    If $Array[$x][$y] <> "" Then
                        $sStringAjout &= $Array[$x][$y]
                    Else
                        $sStringAjout &= "-"
                    EndIf
                Else
                    If $Array[$x][$y] <> "" Then
                        $sStringAjout &= $Array[$x][$y] & "|"
                    Else
                        $sStringAjout &= "-" & "|"
                    EndIf
                EndIf
            Next


            _GUICtrlListView_AddOrIns_Item($MAIN_lvNoSerie, $sStringAjout)


            $sStringAjout = ""

        Next

    EndIf
    _GUICtrlListView_EndUpdate($MAIN_lvNoSerie)
    GUICtrlSetState($MAIN_lvNoSerie, $GUI_SHOW)

EndFunc   ;==>__Remplir_ListView_NoSerie

Share this post


Link to post
Share on other sites

Ah, Can't edit my english mispelling/mistakes, sorry about it.

-hench

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

bumping!

What I tried so far:

- A WinApi_RedrawWindow on the Gui periodically

- Redraw visible items of the Listview periodiocally

- When GUI loses focus, I unregister ListView Messages Monitoring and disable the listview control to try to give a break to the process a bit..

What I realised is that this is caused by the scrollling action of the listview... memory gets overloaded ??, most of the screen become gray, the GUI Menu disappears partially, If I can click one item, the subitems zone is black

.. I clear this by hitting WINKEY-D to go to desktop..

I'm not really good about managing memory, and I'm a newcomer @ the WinApi world. I believe managing Listviews is quite a challenge !!!!

I will appreciate any constructive comments !!!!!

By the way, I'm running WinXP Sp3, Autoit v3.3.6.0

Thanks, and please ask for any informations that would prove useful to fix the problem. I will provide as much as I can, I really gotta solve this!!!

Dômo arigatô gozaimasu !

Hench

Edited by hench

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
Sign in to follow this  
Followers 0