Jump to content

Custom/owner drawn multi-line header in ListView


LarsJ
 Share

Recommended Posts

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.

Link to comment
Share on other sites

  • 2 weeks later...
  • 4 weeks later...
  • 2 weeks later...

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:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor 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 APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

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 * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

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) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

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 *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"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: 2023-04-24

Link to comment
Share on other sites

  • 6 months later...


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

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

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

Link to comment
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.

Link to comment
Share on other sites

  • 8 months later...
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?

Link to comment
Share on other sites

  • Moderators

dmob,

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

M23

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

Open spoiler to see 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

 

Link to comment
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.

 

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

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

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