LarsJ

Custom/owner drawn multi-line header in ListView

17 posts in this topic




Excellent work!  :thumbsup:

Thx for sharing!


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

Thank you for comments and likes.

I have only used GDI functions to create the header items. But you can also use GDIPlus functions if you want something more advanced. As the number of header items are limited, it's possible to add a few more code lines.

I spent a bit of time reading documentation to figure out the details. At the same time, I found some answers to other issues also related to listviews. In the coming weeks I'll probably add a few more listview examples.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

LarsJ whether it is possible to add ComboBox in Header, and some checking, for which Combo element is choosen ?

mLipok

EDIT:
Also possibility to add ComboBox/Edit in ListView Item would be awesome Feature.

 

Edited by mLipok

Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 - BETA * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Best coding practices * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2017-06-04

Share this post


Link to post
Share on other sites


Hello
I would suggest a change to this "multi-line header" in order to simplify the way of use.
In brief, to set the rows of header text, I would use a single string for each column, and each string should also incorporate the styles to be used in a manner similar to the CSS embedding them in braces. (style directive (merely as an example)  have been copied from here http://www.w3schools.com/css/css_text.asp )
ie:

'Default font' & @CR & '{font-family: Comic Sans MS;} Comic Sans MS' & @CR & '{font-family: Courier New; color: 0xFF00FF;} Magenta Courier New '


the string above would produce a column header of 3 rows  (each row is separated by @cr) and each row will have their own style as indicated by the directives inside the braces. (Even more styles separated by ; for each line are allowed).

In this way the whole stuff could also be easly build in a form of UDF.

This 'quick' script is more a proof of concept than a finished product,
I place it here as a possible suggestion for a future version by mr. @LarsJ

#include <GUIConstants.au3>
#include <FontConstants.au3>
#include <WinAPIShellEx.au3>
#include <GuiListView.au3>
#include "GuiHeaderEx.au3"

Opt("MustDeclareVars", 1)

Global Const $tagNMCUSTOMDRAW = "struct;" & $tagNMHDR & ";dword dwDrawStage;handle hdc;" & $tagRECT & _
        ";dword_ptr dwItemSpec;uint uItemState;lparam lItemlParam;endstruct"
Global $hHeader
Global $aHdrInfo = [ _ ; one element for each column
        'Normal style' & @CR & '{font-weight:1000}Bold style' & @CR & '{font-style:1;}Italic style' & @CR & '{text-decoration:1;}Underline style', _
        'Default font' & @CR & '{font-family:Comic Sans MS;}Comic Sans MS' & @CR & '{font-family:Courier New;}Courier New' & @CR & '{font-family:Times New Roman;}Times New Roman', _
        'Default color' & @CR & '{color:0x0000FF;}Red color' & @CR & '{color:0xFF00FF;}Magenta color' & @CR & '{color:0xFF0000;}Blue color' , _
        '{background-color:0x00FF00; text-align:$DT_CENTER}Background' & @CR & '{text-align:$DT_CENTER}Green color' & @CR & '{text-align:$DT_CENTER}Line 3' & @CR & '{text-align:$DT_CENTER}Line 4']

Example()

Func Example()
    ; Create GUI
    GUICreate("Styles, fonts, colors", 420, 320)

    ; Create ListView
    Local $idListView = GUICtrlCreateListView("", 10, 10, 400, 300, -1, $WS_EX_CLIENTEDGE + $LVS_EX_FULLROWSELECT + $LVS_EX_HEADERDRAGDROP)
    Local $hListView = GUICtrlGetHandle($idListView) ; Rearrange columns

    ; Header control
    $hHeader = _GUICtrlListView_GetHeader($hListView)
    Local $iHeaderHeight = 68 ; Header height 68 pixels

    ; Get the font of the Header control
    ; Copied from the _GUICtrlGetFont example by KaFu
    ; See https://www.autoitscript.com/forum/index.php?showtopic=124526
    Local $hDC = _WinAPI_GetDC($hHeader), $hFont = _SendMessage($hHeader, $WM_GETFONT), $hObject = _WinAPI_SelectObject($hDC, $hFont)
    Global $tLogFont = DllStructCreate($tagLOGFONT) ;

    _WinAPI_GetObject($hFont, DllStructGetSize($tLogFont), DllStructGetPtr($tLogFont))
    _WinAPI_SelectObject($hDC, $hObject)
    _WinAPI_ReleaseDC($hHeader, $hDC)

    ; Set height of Header items by applying a text font with a suitable height
    Local $hHdrFont = _GUICtrlHeader_SetItemHeightByFont($hHeader, $iHeaderHeight)

    ; Add columns to ListView
    _GUICtrlListView_AddColumn($hListView, "", 99) ; Delete header texts to avoid that they are
    _GUICtrlListView_AddColumn($hListView, "", 99) ; drawn in $CDDS_ITEMPREPAINT stage below.
    _GUICtrlListView_AddColumn($hListView, "", 99)
    _GUICtrlListView_AddColumn($hListView, "", 99)

    ; Fill ListView
    For $i = 0 To 9
        GUICtrlCreateListViewItem($i & "/1|" & $i & "/2|" & $i & "/3|" & $i & "/4", $idListView)
    Next

    ; Register callback function to subclass ListView
    Local $pListViewProc = DllCallbackGetPtr(DllCallbackRegister("ListViewProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr"))
    _WinAPI_SetWindowSubclass($hListView, $pListViewProc, 9999, $hHdrFont) ; SubclassId = 9999, $pData = $hHdrFont

    ; Show GUI
    GUISetState(@SW_SHOW)

    ; Message loop
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ; Cleanup
    _WinAPI_RemoveWindowSubclass($hListView, $pListViewProc, 9999)
    GUIDelete()
EndFunc   ;==>Example

; This function receives one string for each column with embedded styles
; for each @cr  a new line will be printed on the ListView Header
; for each line the styles are embedded between { and }
; even more than one style per line can be setted, just separe more styles by a ;
Func _StyleParser(ByRef $sString) ; one string for each column
    Local $aStyles
    Local $aLines = StringSplit($sString, @CR) ; split lines for this column header
    Local $aStyleInfo[$aLines[0]][2] ; declare array $aStyleInfo

    For $i = 1 To $aLines[0]; scan all lines
        ; following regexp found here: http://www.rexegg.com/regex-cookbook.html#captureparen
        $aStyles = StringRegExp($aLines[$i], "\{([^()]*)\}", 1) ; xtract styles from between { and }
        If @error Then $aStyles = StringSplit('Style:normal;', '¦', 2) ; if no style use StringSplit just to create the array
        $aStyles[0] = StringStripWS($aStyles[0], 7)
        If StringRight($aStyles[0], 1) = ";" Then $aStyles[0] = StringLeft($aStyles[0], StringLen($aStyles[0]) - 1) ; remove last ;
        $aStyleInfo[$i - 1][0] = StringSplit($aStyles[0], ";", 2) ; array of styles to apply to this line
        $aStyleInfo[$i - 1][1] = StringMid($aLines[$i], StringInStr($aLines[$i], "}") + 1) ; text for this line
    Next
    Return $aStyleInfo ; array of styles in $aStyleInfo[n][0], text in $aStyleInfo[n][1] ( where n is line number of header)
EndFunc   ;==>_StyleParser

; ListViewProc callback function
Func ListViewProc($hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hHdrFont)
    #forceref $iSubclassId
    Switch $iMsg
        Case $WM_NOTIFY
            Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
            Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
            Local $iCode = DllStructGetData($tNMHDR, "Code")
            Switch $hWndFrom
                Case $hHeader
                    Switch $iCode
                        Case $NM_CUSTOMDRAW
                            Local $tNMCustomDraw = DllStructCreate($tagNMCUSTOMDRAW, $lParam)
                            Local $dwDrawStage = DllStructGetData($tNMCustomDraw, "dwDrawStage")
                            Switch $dwDrawStage ; Holds a value that specifies the drawing stage
                                Case $CDDS_PREPAINT ; Before the paint cycle begins
                                    Return $CDRF_NOTIFYITEMDRAW ; Notify parent window of any item related drawing operations

                                Case $CDDS_ITEMPREPAINT ; Before an item is drawn: Default painting (frames and background)
                                    Return $CDRF_NOTIFYPOSTPAINT ; Notify parent window of any post item related drawing operations

                                Case $CDDS_ITEMPOSTPAINT ; After an item is drawn: Custom painting (item texts)
                                    Local $iIndex = DllStructGetData($tNMCustomDraw, "dwItemSpec") ; Item index (column number 0 ... up)
                                    Local $hDC = DllStructGetData($tNMCustomDraw, "hdc") ; Device context
                                    _WinAPI_SelectObject($hDC, $hHdrFont) ; Set text font
                                    _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; Transparent background
                                    ; --- here we go -------------------------------------------------------------------------------------
                                    Local $aRows, $aStyles, $aSplit, $iAllign = $DT_LEFT, $iNrStls, $logicalFont, $brush
                                    Local $sDefFaceName = DllStructGetData($tLogFont, "FaceName")
                                    Local $tDefLogFont = _WinAPI_CreateFontIndirect($tLogFont)
                                    Local $iDefWeight = DllStructGetData( $tLogFont, "Weight" )

                                    $aRows = _StyleParser($aHdrInfo[$iIndex])
                                    For $iRow = 0 To UBound($aRows) - 1 ; for each line in a column header
                                        For $i = 0 To UBound($aRows[$iRow][0]) - 1 ; For all Styles within a single line
                                            $aSplit = StringSplit(($aRows[$iRow][0])[$i], ":", $STR_NOCOUNT) ; StyleName:Value pairs
                                            Switch StringStripWS($aSplit[0], 8) ; wanted action
                                                Case "color"
                                                    _WinAPI_SetTextColor($hDC, $aSplit[1])

                                                Case "font-family"
                                                    DllStructSetData($tLogFont, "FaceName", $aSplit[1])

                                                Case "font-style" ; normal, italic
                                                    DllStructSetData($tLogFont, "Italic", $aSplit[1])

                                                Case "font-weight" ; bold
                                                    DllStructSetData($tLogFont, "Weight", $aSplit[1])

                                                Case "text-align"
                                                    $iAllign = Execute($aSplit[1])

                                                Case "text-decoration" ; underline, none
                                                    DllStructSetData($tLogFont, "Underline", $aSplit[1])

                                                Case "background-color"
                                                    _WinAPI_SelectObject($hDC, $tDefLogFont)
                                                    $brush = _WinAPI_CreateSolidBrush($aSplit[1])
                                                    _WinAPI_SetBkColor($hDC, $brush)
                                                    Local $tRECT = DllStructCreate($tagRECT)
                                                    DllStructSetData($tRECT, 1, DllStructGetData($tNMCustomDraw, 6) + 1)
                                                    DllStructSetData($tRECT, 2, DllStructGetData($tNMCustomDraw, 7) + 1)
                                                    DllStructSetData($tRECT, 3, DllStructGetData($tNMCustomDraw, 8) - 2)
                                                    DllStructSetData($tRECT, 4, DllStructGetData($tNMCustomDraw, 9) - 2)

                                                    _WinAPI_FillRect($hDC, $tRECT, $brush)

                                                Case "normal"
                                                    ; do nothing

                                            EndSwitch
                                        Next ; Next Style

                                        ; _WinAPI_DrawText
                                        $logicalFont = _WinAPI_CreateFontIndirect($tLogFont)
                                        _WinAPI_SelectObject($hDC, $logicalFont)
                                        DllCall("user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aRows[$iRow][1], "int", StringLen($aRows[$iRow][1]), "struct*", DllStructGetPtr($tNMCustomDraw, "Left"), "uint", $iAllign)
                                        DllStructSetData($tNMCustomDraw, "Top", DllStructGetData($tNMCustomDraw, "Top") + Abs(DllStructGetData($tLogFont, "Height")) + 3) ; lowers the upper margin of the header
                                        ; DllStructSetData($tNMCustomDraw, "Bottom", DllStructGetData($tNMCustomDraw, "Bottom") + 16)

                                        ; reset all Styles back to normal
                                        $iAllign = $DT_LEFT
                                        _WinAPI_SelectObject($hDC, $tDefLogFont)
                                        _WinAPI_SetTextColor($hDC, 0x000000)
                                        DllStructSetData($tLogFont, "Weight", $iDefWeight)
                                        DllStructSetData($tLogFont, "Underline", False)
                                        DllStructSetData( $tLogFont, "Italic", False )
                                        DllStructSetData($tLogFont, "FaceName", $sDefFaceName)
                                    Next ; Next row
                                    Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors
                            EndSwitch
                    EndSwitch
            EndSwitch
    EndSwitch
    ; Call next function in subclass chain
    Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)[0]
EndFunc   ;==>ListViewProc

 


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

This is also one of the examples to be coded as a UDF to make it easier to use. The standard AutoIt method for transferring information to a UDF function is to use simple parameters. And that's probably the way I'll use. More or less in the same manner as is done in Colors and fonts in ListViews.

Once a UDF is provided it should be relatively easy to make a wrapper function to use a formatted string to specify all the attributes for a single header item.

I also think that the idea of being able to use eg. a combobox in the header control as proposed by mLipok in post 7 should be implemented. Then for example you can use a specific month instead of a Month column.

But right now I've no time for coding. I'm busy upgrading my Windows 7 laptop to Windows 10 and installing a new Windows 7 PC. I think I can finish it the next weekend.

Share this post


Link to post
Share on other sites

#11 ·  Posted

On 7/18/2016 at 6:17 PM, LarsJ said:

I also think that the idea of being able to use eg. a combobox in the header control as proposed by mLipok in post 7 should be implemented. Then for example you can use a specific month instead of a Month column.

Eagerly awaiting this functionality, if any development still on-going?

Share this post


Link to post
Share on other sites

#12 ·  Posted

dmob,

My GUIListViewEx UDF already has the "combo in a header" functionality.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#13 ·  Posted

Ow wow, great news since I am already using that UDF :drool:

Share this post


Link to post
Share on other sites
#include <GUIConstants.au3>
#include <WinAPIShellEx.au3>
#include <FontConstants.au3>
#include <GuiListView.au3>
#include <GuiButton.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include "GuiHeaderEx.au3"

Opt( "MustDeclareVars", 1 )

Global Const $tagNMCUSTOMDRAW = "struct;" & $tagNMHDR & ";dword dwDrawStage;handle hdc;" & $tagRECT & _
                                ";dword_ptr dwItemSpec;uint uItemState;lparam lItemlParam;endstruct"

Global $hHeader      ;                                 Left/right margin
Global $iHdrLins = 3 ; Line 1      Line 2    Line 3    |  Line height
Global $aHdrInfo = [ [ "Column 1", "",       "",       4, 16, $DT_CENTER, "Styles",     0, 0, 0], _ ; Item 1
                     [ "Column 2", "Line 2", "",       4, 16, $DT_CENTER, "Fonts",      0, 0, 0, 0], _ ; Item 2
                     [ "Column 3", "Line 2", "Line 3", 4, 16, $DT_CENTER, "ForeColors", 0, 0, 0, 0 ], _ ; Item 3
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 1", "",       "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _ ; Item 4
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ], _
                     [ "Column 4", "Line 2", "",       4, 16, $DT_CENTER, "BackColor",  0, 0, 0, 0 ]]

Example()


Func Example()
    ; Create GUI

    GUICreate(" My GUI input acceptfile", 900, 570, -1, -1)
   GUISetBkColor(0x3e65a0)
   
   ; Create ListView
     Global $idListview = GUICtrlCreateListView("", 2, 185, 900, 330, -1) ;$WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT+$LVS_EX_HEADERDRAGDROP )
     _GUICtrlListView_SetExtendedListViewStyle($idListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FLATSB, $LVS_REPORT,$LVS_EX_DOUBLEBUFFER))

    Local $hListView = GUICtrlGetHandle( $idListView )


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

    ; Header control
    $hHeader = _GUICtrlListView_GetHeader( $hListView )
    Local $iHeaderHeight = 68 ; Header height 50 pixels

    Local $hDC = _WinAPI_GetDC( $hHeader ), $hFont = _SendMessage( $hHeader, $WM_GETFONT ), $hObject = _WinAPI_SelectObject( $hDC, $hFont ), $tLogFont = DllStructCreate( $tagLOGFONT )
    _WinAPI_GetObject( $hFont, DllStructGetSize( $tLogFont ), DllStructGetPtr( $tLogFont ) )
    _WinAPI_SelectObject( $hDC, $hObject )
    _WinAPI_ReleaseDC( $hHeader, $hDC )
    
    ; Background color for Header item 4
    $aHdrInfo[3][7] = 0x00FF00                                           ; Green background, BGR
    $aHdrInfo[3][8] = _WinAPI_CreateSolidBrush( $aHdrInfo[3][7] )        ; Brush with background color

    ; Set height of Header items by applying a text font with a suitable height
    Local $hHdrFont = _GUICtrlHeader_SetItemHeightByFont( $hHeader, $iHeaderHeight )

    ; Add columns to ListView
    _GUICtrlListView_AddColumn( $hListView, "", 99 ) ; Delete header texts to avoid that they are
    _GUICtrlListView_AddColumn( $hListView, "", 99 ) ; drawn in $CDDS_ITEMPREPAINT stage below.
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    _GUICtrlListView_AddColumn( $hListView, "", 99 )
    
    Local $pListViewProc = DllCallbackGetPtr( DllCallbackRegister( "ListViewProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
    _WinAPI_SetWindowSubclass( $hListView, $pListViewProc, 9999, $hHdrFont ) ; SubclassId = 9999, $pData = $hHdrFont

    ; Show GUI
    GUISetState( @SW_SHOW )


    ; Message loop
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ; Cleanup
    _WinAPI_RemoveWindowSubclass( $hListView, $pListViewProc, 9999 )
    GUIDelete()
EndFunc


Func ListViewProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hHdrFont )
    #forceref $iSubclassId
    Switch $iMsg
        Case $WM_NOTIFY
            Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
            Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
            Local $iCode = DllStructGetData( $tNMHDR, "Code" )
            Switch $hWndFrom
                Case $hHeader
                    Switch $iCode
                        Case $NM_CUSTOMDRAW
                            Local $tNMCustomDraw = DllStructCreate( $tagNMCUSTOMDRAW, $lParam )
                            Local $dwDrawStage = DllStructGetData( $tNMCustomDraw, "dwDrawStage" )
                            Switch $dwDrawStage                  ; Holds a value that specifies the drawing stage
                                Case $CDDS_PREPAINT                ; Before the paint cycle begins
                                    Return $CDRF_NOTIFYITEMDRAW      ; Notify parent window of any item related drawing operations

                                Case $CDDS_ITEMPREPAINT            ; Before an item is drawn: Default painting (frames and background)
                                    Return $CDRF_NOTIFYPOSTPAINT     ; Notify parent window of any post item related drawing operations

                                Case $CDDS_ITEMPOSTPAINT           ; After an item is drawn: Custom painting (item texts)
                                    Local $iIndex = DllStructGetData( $tNMCustomDraw, "dwItemSpec" ) ; Item index
                                    Local $hDC = DllStructGetData( $tNMCustomDraw, "hdc" )           ; Device context
                                    _WinAPI_SelectObject( $hDC, $hHdrFont )                          ; Set text font
                                    _WinAPI_SetBkMode( $hDC, $TRANSPARENT )                          ; Transparent background
                                    Switch $aHdrInfo[$iIndex][7]
                                        Case "Styles"
                                            _WinAPI_SelectObject( $hDC, $aHdrInfo[$iIndex][8] )
                                        Case "Fonts"
                                            _WinAPI_SelectObject( $hDC, $aHdrInfo[$iIndex][8] )
                                        Case "ForeColors"
                                            _WinAPI_SelectObject( $hDC, $aHdrInfo[0][9] ) ; Bold
                                            _WinAPI_SetTextColor( $hDC, $aHdrInfo[$iIndex][8] )
                                        Case "BackColor"
                                            _WinAPI_SelectObject( $hDC, $aHdrInfo[0][8] )
                                            _WinAPI_SetBkColor( $hDC, $aHdrInfo[$iIndex][8] )
                                            Local $tRECT = DllStructCreate( $tagRECT )
                                            DllStructSetData( $tRECT, 1, DllStructGetData( $tNMCustomDraw, 6 ) + 1 )
                                            DllStructSetData( $tRECT, 2, DllStructGetData( $tNMCustomDraw, 7 ) + 1 )
                                            DllStructSetData( $tRECT, 3, DllStructGetData( $tNMCustomDraw, 8 ) - 2 )
                                            DllStructSetData( $tRECT, 4, DllStructGetData( $tNMCustomDraw, 9 ) - 2 )
                                            _WinAPI_FillRect( $hDC, $tRECT, $aHdrInfo[$iIndex][8] )
                                    EndSwitch
                                    ; First line
                                    DllStructSetData( $tNMCustomDraw, "Left",   DllStructGetData( $tNMCustomDraw, "Left" )  + $aHdrInfo[$iIndex][3] ) ; Left margin
                                    DllStructSetData( $tNMCustomDraw, "Right",  DllStructGetData( $tNMCustomDraw, "Right" ) - $aHdrInfo[$iIndex][3] ) ; Right margin
                                    DllStructSetData( $tNMCustomDraw, "Top",    DllStructGetData( $tNMCustomDraw, "Top" )   + 2 )                     ; 2 pixel top margin
                                    DllStructSetData( $tNMCustomDraw, "Bottom", DllStructGetData( $tNMCustomDraw, "Top" )   + $aHdrInfo[$iIndex][4] ) ; Line height
                                    DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrInfo[$iIndex][0], "int", StringLen( $aHdrInfo[$iIndex][0] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $aHdrInfo[$iIndex][6] ) ; _WinAPI_DrawText
                                    ; Line two, three and four
                                    For $i = 1 To 2

                                        Switch $aHdrInfo[$iIndex][6]
                                            Case "Styles"
                                                _WinAPI_SelectObject( $hDC, $aHdrInfo[$iIndex][8+$i] )
                                            Case "Fonts"
                                                _WinAPI_SelectObject( $hDC, $aHdrInfo[$iIndex][8+$i] )
                                            Case "ForeColors"
                                                _WinAPI_SetTextColor( $hDC, $aHdrInfo[$iIndex][8+$i] )

                                        EndSwitch

                                        DllStructSetData( $tNMCustomDraw, "Top",    DllStructGetData( $tNMCustomDraw, "Top" )    + $aHdrInfo[$iIndex][4] )                     ; 2 pixel top margin
                                        DllStructSetData( $tNMCustomDraw, "Bottom", DllStructGetData( $tNMCustomDraw, "Bottom" ) + $aHdrInfo[$iIndex][4] )
                                        DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrInfo[$iIndex][$i], "int", StringLen( $aHdrInfo[$iIndex][$i] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $aHdrInfo[$iIndex][5] ) ; _WinAPI_DrawText
                                    Next
                                    Return $CDRF_NEWFONT             ; $CDRF_NEWFONT must be returned after changing font or colors
                            EndSwitch
                    EndSwitch
            EndSwitch
    EndSwitch
    ; Call next function in subclass chain
    Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
EndFunc

Hi,

I am trying to give background color to the headers in the listview. I have posted the code which I tried but its not working. Please review it. thanks.

 

Share this post


Link to post
Share on other sites

If you only want background colors you don't need all the code:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <GUIConstants.au3>
#include <FontConstants.au3>
#include <WinAPIShellEx.au3>
#include <GuiListView.au3>
#include "GuiHeaderEx.au3"

Opt( "MustDeclareVars", 1 )

Global Const $tagNMCUSTOMDRAW = "struct;" & $tagNMHDR & ";dword dwDrawStage;handle hdc;" & $tagRECT & _
                                ";dword_ptr dwItemSpec;uint uItemState;lparam lItemlParam;endstruct"

Global $hHeader
Global $hHdrBrush    ;                                                    Line 4
Global $iHdrLins = 3 ; Line 1           Line 2           Line 3           (Not used)         Format
Global $aHdrInfo = [ [ "Column 1",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 1
                     [ "Column 2",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 2
                     [ "Column 3",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 3
                     [ "Column 4",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 4
                     [ "Column 5",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 5
                     [ "Column 6",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 6
                     [ "Column 7",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ], _ ; Item 7
                     [ "Column 8",      "Line 2",        "Line 3",        "Line 4",          $DT_CENTER ] ]  ; Item 8

Example()

Func Example()
  ; Create GUI
  GUICreate( "Example", 840, 420 )

  ; Create ListView
  Local $idListView = GUICtrlCreateListView( "", 10, 10, 820, 400, -1, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT+$LVS_EX_HEADERDRAGDROP )
  Local $hListView = GUICtrlGetHandle( $idListView )                                                         ; Rearrange columns

  ; Header control
  $hHeader = _GUICtrlListView_GetHeader( $hListView )
  Local $iHeaderHeight = $iHdrLins * 16 + 4

  ; Get the font of the Header control
  ; Copied from the _GUICtrlGetFont example by KaFu
  ; See https://www.autoitscript.com/forum/index.php?showtopic=124526
  Local $hDC = _WinAPI_GetDC( $hHeader ), $hFont = _SendMessage( $hHeader, $WM_GETFONT ), $hObject = _WinAPI_SelectObject( $hDC, $hFont ), $tLogFont = DllStructCreate( $tagLOGFONT )
  _WinAPI_GetObject( $hFont, DllStructGetSize( $tLogFont ), DllStructGetPtr( $tLogFont ) )
  _WinAPI_SelectObject( $hDC, $hObject )
  _WinAPI_ReleaseDC( $hHeader, $hDC )

  ; Header brush
  $hHdrBrush = _WinAPI_CreateSolidBrush( 0xCCFFFF ) ; Yellow, BGR

  ; Set height of Header items by applying a text font with a suitable height
  Local $hHdrFont = _GUICtrlHeader_SetItemHeightByFont( $hHeader, $iHeaderHeight )

  ; Add columns to ListView
  For $i = 0 To 7
    _GUICtrlListView_AddColumn( $idListView, "", 99 ) ; Delete header texts to avoid that they are
  Next                                                ; drawn in $CDDS_ITEMPREPAINT stage below.

  ; Fill ListView
  For $i = 0 To 99
    GUICtrlCreateListViewItem( $i & "/1|" & $i & "/2|" & $i & "/3|" & $i & "/4|" & _
                               $i & "/5|" & $i & "/6|" & $i & "/7|" & $i & "/8", $idListView )
  Next

  ; Register callback function to subclass ListView
  Local $pListViewProc = DllCallbackGetPtr( DllCallbackRegister( "ListViewProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
  _WinAPI_SetWindowSubclass( $hListView, $pListViewProc, 9999, $hHdrFont ) ; SubclassId = 9999, $pData = $hHdrFont

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  _WinAPI_RemoveWindowSubclass( $hListView, $pListViewProc, 9999 )
  GUIDelete()
EndFunc

; ListViewProc callback function
Func ListViewProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hHdrFont )
  Switch $iMsg
    Case $WM_NOTIFY
      Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
      Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
      Local $iCode = DllStructGetData( $tNMHDR, "Code" )
      Switch $hWndFrom
        Case $hHeader
          Switch $iCode
            Case $NM_CUSTOMDRAW
              Local $tNMCustomDraw = DllStructCreate( $tagNMCUSTOMDRAW, $lParam )
              Local $dwDrawStage = DllStructGetData( $tNMCustomDraw, "dwDrawStage" )
              Switch $dwDrawStage                  ; Holds a value that specifies the drawing stage
                Case $CDDS_PREPAINT                ; Before the paint cycle begins
                  Return $CDRF_NOTIFYITEMDRAW      ; Notify parent window of any item related drawing operations

                Case $CDDS_ITEMPREPAINT            ; Before an item is drawn: Default painting (frames and background)
                  Return $CDRF_NOTIFYPOSTPAINT     ; Notify parent window of any post item related drawing operations

                Case $CDDS_ITEMPOSTPAINT           ; After an item is drawn: Custom painting (item texts)
                  Local $iIndex = DllStructGetData( $tNMCustomDraw, "dwItemSpec" ) ; Item index
                  Local $hDC = DllStructGetData( $tNMCustomDraw, "hdc" )           ; Device context
                  _WinAPI_SelectObject( $hDC, $hHdrFont )                          ; Set text font
                  _WinAPI_SetBkMode( $hDC, $TRANSPARENT )                          ; Transparent background
                  Local $tRECT = DllStructCreate( $tagRECT )
                  DllStructSetData( $tRECT, 1, DllStructGetData( $tNMCustomDraw, 6 ) + 1 )
                  DllStructSetData( $tRECT, 2, DllStructGetData( $tNMCustomDraw, 7 ) + 1 )
                  DllStructSetData( $tRECT, 3, DllStructGetData( $tNMCustomDraw, 8 ) - 2 )
                  DllStructSetData( $tRECT, 4, DllStructGetData( $tNMCustomDraw, 9 ) - 2 )
                  _WinAPI_FillRect( $hDC, $tRECT, $hHdrBrush )                     ; Background color
                  ; First line
                  DllStructSetData( $tNMCustomDraw, "Left",   DllStructGetData( $tNMCustomDraw, "Left" )  + 4 )  ; Left margin
                  DllStructSetData( $tNMCustomDraw, "Right",  DllStructGetData( $tNMCustomDraw, "Right" ) - 4 )  ; Right margin
                  DllStructSetData( $tNMCustomDraw, "Top",    DllStructGetData( $tNMCustomDraw, "Top" )   + 2 )  ; 2 pixel top margin
                  DllStructSetData( $tNMCustomDraw, "Bottom", DllStructGetData( $tNMCustomDraw, "Top" )   + 16 ) ; Line height
                  DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrInfo[$iIndex][0], "int", StringLen( $aHdrInfo[$iIndex][0] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $aHdrInfo[$iIndex][4] ) ; _WinAPI_DrawText
                  ; Line two and three
                  For $i = 1 To 2
                    DllStructSetData( $tNMCustomDraw, "Top",    DllStructGetData( $tNMCustomDraw, "Top" )    + 16 )
                    DllStructSetData( $tNMCustomDraw, "Bottom", DllStructGetData( $tNMCustomDraw, "Bottom" ) + 16 )
                    DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrInfo[$iIndex][$i], "int", StringLen( $aHdrInfo[$iIndex][$i] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $aHdrInfo[$iIndex][4] ) ; _WinAPI_DrawText
                  Next
                  Return $CDRF_NEWFONT             ; $CDRF_NEWFONT must be returned after changing font or colors
              EndSwitch
          EndSwitch
      EndSwitch
  EndSwitch
  ; Call next function in subclass chain
  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  #forceref $iSubclassId
EndFunc

 

Share this post


Link to post
Share on other sites

Why the color code is not giving the same color for which the code is. It is for blue and it shows yellow.

And how can I give first half headers one color and second half another color.

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