LarsJ

Multi-line items in custom drawn ListView

13 posts in this topic




#2 ·  Posted (edited)

AutoItMagic :)

+5

btw. (little off topic)

Sorry for bothering but I think you should update your Signature, as is incomplete - I mean here:

ListView controls: Custom drawn colors and fontsVirtual listviews for huge number of rows

;)

 

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

Great work LarsJ. Thanks 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

#4 ·  Posted (edited)

9) Rearrange columns.au3

This is great.
Do you have any concept how Column order can be saved, and restored ?
I mean user change order and this should be saved for "future" program runs.

 

 

EDIT:

E) Large images in first column.au3

Is just awesome.
After a brief moment of reverie, I've got to possible use in one of my projects.

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

#5 ·  Posted (edited)

mLipok, In this version of example 9 code is added to read and save column order in "HdrItemOrder.ini".

#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <WinAPIShellEx.au3>
#include "GuiListViewEx.au3"
#include "ListViewCustomDraw.au3"

Opt( "MustDeclareVars", 1 )

Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $hLVfont, $iItems = 1000, $aLines[1][4]
Global $hHeader, $fHeaderOrderOfItem0 = 0 ; $fHeaderOrderOfItem0 is used to handle column 0 issue

Example()


Func Example()
  ; Create GUI
  $hGui = GUICreate( "Rearrange columns", 440, 320 )

  ; Create ListView
  $idListView = GUICtrlCreateListView( "", 10, 10, 420, 300, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE+$LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES+$LVS_EX_HEADERDRAGDROP )
  $hListView = GUICtrlGetHandle( $idListView )                                                                        ; Reduce flicker

  ; Increase item height
  $hLVfont = _GUICtrlListView_SetItemHeightByFont( $hListView, 26 )

  ; Add columns to ListView
  _GUICtrlListView_AddColumn( $hListView, "Column 1", 94 )
  _GUICtrlListView_AddColumn( $hListView, "Column 2", 94 )
  _GUICtrlListView_AddColumn( $hListView, "Column 3", 94 )
  _GUICtrlListView_AddColumn( $hListView, "Column 4", 94 )

  ; Fill ListView
  Local $idItem
  For $i = 0 To $iItems - 1
    $idItem = GUICtrlCreateListViewItem( $i & " Column 1|" & $i & " Column 2|" & $i & " Column 3|" & $i & " Column 4", $idListView )
    ; $idItem (controlID) is stored in ItemParam in the internal storage allocated for the ListView
    If Not $i Then ReDim $aLines[$idItem+$iItems][4] ; Second line in ListView items is stored in $aLines array
    $aLines[$idItem][0] = $i & " Line 2/1" ; $idItem (controlID, stored in ItemParam) is row index in $aLines
    $aLines[$idItem][1] = $i & " Line 2/2" ; Four item texts are stored in four columns in $aLines array
    $aLines[$idItem][2] = $i & " Line 2/3" ; If line texts are stored as strings it's easy to test for empty texts
    $aLines[$idItem][3] = $i & " Line 2/4"
  Next

  ; Adjust height of GUI and ListView to fit ten rows
  Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView, 10 )
  WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 )
  WinMove( $hListView, "", Default, Default, Default, $iLvHeight )

  ; Column 0 issue
  ; Header handle and position
  $hHeader = _GUICtrlListView_GetHeader( $hListView )
  Local $tRect = _WinAPI_GetClientRect( $hListView )
  Local $tPos = _GUICtrlHeader_Layout( $hHeader, $tRect )
  Local $aHdrPos = WinGetPos( $hHeader )                      ; Left/top corner in screen coordinates
  $aHdrPos[2] = $aHdrPos[0] + DllStructGetData( $tPos, "CX" ) ; Right/bottom corner in screen coordinates
  $aHdrPos[3] = $aHdrPos[1] + DllStructGetData( $tPos, "CY" )
  Local $bMouseClickHeader = False

  ; Read Header item order
  Local $aHdrItemOrder0 = [ 4, 0, 1, 2, 3 ], $aHdrItemOrder, $sOrder
  If FileExists( "HdrItemOrder.ini" ) Then
    $sOrder = FileReadLine( "HdrItemOrder.ini" )
    $aHdrItemOrder = StringSplit( $sOrder, "|", 2 ) ; 2 = $STR_NOCOUNT
    For $i = 1 To $aHdrItemOrder[0]
      If $aHdrItemOrder[$i] <> $aHdrItemOrder0[$i] Then ExitLoop
    Next
    If $i < $aHdrItemOrder[0] Then
      _GUICtrlHeader_SetOrderArray( $hHeader, $aHdrItemOrder )
      $aHdrItemOrder0 = $aHdrItemOrder
    EndIf
  EndIf
  
  ; Register WM_NOTIFY message handler
  ; To handle NM_CUSTOMDRAW notifications
  ; And to check when ListView receives/loses focus
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  ; Register WM_ACTIVATE message handler         ; If GUI loses focus selected listview items are drawn with a button face background color.
  ; To check when GUI receives/loses focus       ; When GUI receives focus selected items are redrawn with the dark blue background color.
  GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" )  ; Detection of received focus is faster through the WM_ACTIVATE message than directly
                                                 ; through the listview. This provides a faster and smoother redraw of selected items.
  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      ; Two Case sections to handle column 0 issue
      Case $GUI_EVENT_PRIMARYDOWN
        Local $aPos = MouseGetPos()
        If $aHdrPos[0] <= $aPos[0] And $aPos[0] <= $aHdrPos[2] And _
           $aHdrPos[1] <= $aPos[1] And $aPos[1] <= $aHdrPos[3] Then
          ; Mouse click in header
          ; 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, 0 ) ; $iSubclassId = 9999, $pData = 0
          $bMouseClickHeader = True
        EndIf
      Case $GUI_EVENT_PRIMARYUP
        If $bMouseClickHeader Then
          ; Remove callback function
          _WinAPI_RemoveWindowSubclass( $hListView, $pListViewProc, 9999 )
          $bMouseClickHeader = False
        EndIf

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Save Header item order if changed
  $aHdrItemOrder = _GUICtrlHeader_GetOrderArray( $hHeader )
  For $i = 1 To $aHdrItemOrder[0]
    If $aHdrItemOrder[$i] <> $aHdrItemOrder0[$i] Then ExitLoop
  Next
  If $i < $aHdrItemOrder[0] Then
    $sOrder = $aHdrItemOrder[0]
    For $i = 1 To $aHdrItemOrder[0]
      $sOrder &= "|" & $aHdrItemOrder[$i]
    Next
    Local $hHdrIni = FileOpen( "HdrItemOrder.ini", 2 ) ; 2 = $FO_OVERWRITE
    FileWriteLine( $hHdrIni, $sOrder )
    FileClose( $hHdrIni )
  EndIf

  ; Cleanup
  GUIDelete()
EndFunc

; ListViewProc callback function to handle column 0 issue
Func ListViewProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData )
  If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  If HWnd( DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "hWndFrom" ) ) <> $hHeader Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  #forceref $iSubclassId, $pData

  Switch DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "Code" )
    Case $HDN_ENDDRAG           ; A Header item has been dragged with the mouse
      $fHeaderOrderOfItem0 = -1 ; Recalculate order of Header item with index 0
  EndSwitch

  ; Call next function in subclass chain
  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
EndFunc

; WM_NOTIFY message handler
Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $hWnd, $iMsg, $wParam
  Local Static $iLvIndex, $iArrayIdx, $iSelected, $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $hDC
  Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  Local $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hListView
      Switch $iCode
        Case $NM_CUSTOMDRAW
          Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" )
          Switch $dwDrawStage                                ; Specifies the drawing stage
            ; Stage 1
            Case $CDDS_PREPAINT                              ; Before the paint cycle begins
              If $fHeaderOrderOfItem0 = -1 Then
                ; Handle column 0 issue
                ; Calculate order of Header item with index 0
                Local $tHdrItem = DllStructCreate( $tagHDITEM )
                DllStructSetData( $tHdrItem, "Mask", $HDI_ORDER )
                DllCall( "user32.dll", "lresult", "SendMessageW", "hwnd", $hHeader, "uint", $HDM_GETITEMW, "wparam", 0, "struct*", $tHdrItem )
                $fHeaderOrderOfItem0 = DllStructGetData( $tHdrItem, "Order" )
              EndIf
              $hDC = DllStructGetData( $tNMLVCustomDraw, "hDC" ) ; Device context
              _WinAPI_SelectObject( $hDC, $hLVfont )             ; Set original font
              _WinAPI_SetBkMode( $hDC, $TRANSPARENT )            ; Transparent background
              Return $CDRF_NOTIFYITEMDRAW+$CDRF_NEWFONT      ; Notify the parent window before an item is painted

            ; Stage 2
            Case $CDDS_ITEMPREPAINT                          ; Before an item is painted
              $iLvIndex = DllStructGetData( $tNMLVCustomDraw, "dwItemSpec" )                           ; Item index
              $iArrayIdx = DllStructGetData( $tNMLVCustomDraw, "lItemlParam" )                         ; Array index
              $iSelected = GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iLvIndex, $LVIS_SELECTED ) ; Item state
              Return $CDRF_NOTIFYSUBITEMDRAW                 ; Notify the parent window before a subitem is painted

            ; Stage 3
            Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM )  ; Before a subitem is painted: Default painting of checkbox, image, icon
              Return $CDRF_NOTIFYPOSTPAINT                   ; Notify the parent window after a subitem is painted

            ; Stage 4
            Case BitOR( $CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM ) ; After a subitem has been painted: Custom painting of text lines
              Local $iSubItem = DllStructGetData( $tNMLVCustomDraw, "iSubItem" ) ; Subitem index

              ; Subitem rectangle
              DllStructSetData( $tRect, "Top", $iSubItem )
              DllStructSetData( $tRect, "Left", $iSubItem ? $LVIR_BOUNDS : $LVIR_LABEL )
              GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iLvIndex, $pRect )

              ; Subitem text color
              DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", ( $iSelected And $fListViewHasFocus ) ? 0xFFFFFF : 0x000000 ) ; _WinAPI_SetTextColor

              ; Custom painting of first text line in subitem
              If $fHeaderOrderOfItem0 Then ; Handle column 0 issue
                ; Handle column 0 issue due to column 0 and other columns have different left margins
                RepaintFirstTextLineCol0( $idListView, $iLvIndex, $iSubItem, $iSelected, $fListViewHasFocus, $hDC, $tRect )
              Else
                RepaintFirstTextLine( $idListView, $iLvIndex, $iSubItem, $iSelected, $fListViewHasFocus, $hDC, $tRect )
              EndIf

              ; Custom painting of second text line in subitem
              If Not $aLines[$iArrayIdx][$iSubItem] Then Return $CDRF_NEWFONT
              DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 12 ) ; Top margin
              DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aLines[$iArrayIdx][$iSubItem], "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText

              Return $CDRF_NEWFONT                           ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
        Case $NM_KILLFOCUS
          If $fListViewHasFocus Then
            GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 )
            $fListViewHasFocus = 0
          EndIf
        Case $NM_SETFOCUS
          If Not $fListViewHasFocus Then _
            GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 )
          $fListViewHasFocus = 2
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

; WM_ACTIVATE message handler
Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $iMsg, $lParam
  If $hWnd = $hGui Then _
    $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0
  Return $GUI_RUNDEFMSG
EndFunc

I have obviously forgotten to update my signature for a long time. I will go through the examples and update the signature in the weekend. Thank you.

 

For everybody: Always nice to get feedback. Thank you.

Edited by LarsJ
1 person likes this

Share this post


Link to post
Share on other sites

Fantastic stuff... I was seaching for a set of complete examples like these.

But I can't figure out in scripts number 4 & 5 how to check the state of checkboxes...

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Share this post


Link to post
Share on other sites

So simple.. sure !

I forgot there is the built-in function...

Thank you.

 

Share this post


Link to post
Share on other sites

@LarsJ I want to ask you if you can provide one more example.

I use _GUICtrlListView_GetItemText.au3 example from HelpFile and I was made little modyfication.

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    Local $idListview

    GUICreate("ListView Get Item Text", 400, 300)
    $idListview = GUICtrlCreateListView("", 2, 2, 394, 268)
    GUISetState(@SW_SHOW)

    ; Add columns
    _GUICtrlListView_AddColumn($idListview, "Items", 100)

    ; Add items
    _GUICtrlListView_AddItem($idListview, "Item 1")
    _GUICtrlListView_AddItem($idListview, "Item 2")
    _GUICtrlListView_AddItem($idListview, "Item 3")

    ; Set item 2 text ; HERE I ADD NEW LINE
    _GUICtrlListView_SetItemText($idListview, 1, "New Item 2" & @CRLF & "second line")
    MsgBox($MB_SYSTEMMODAL, "Information", "Item 2 Text: " & _GUICtrlListView_GetItemText($idListview, 1))

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

How you can see Listview internally stores @CRLF char.

So I wonder how to make it possible to just check if desired ListViewItem contain NewLine character and then show them in a proper way (multiline).
In such case user do not must create any special array to store ListViewItem properties.

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

It can be done:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>

Opt( "MustDeclareVars", 1 )

Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $hLVfont, $iItems

Example()

Func Example()
  $hGui = GUICreate("ListView Get Item Text", 500, 300) ; $hGui is used in WM_ACTIVATE

  $idListView = GUICtrlCreateListView("", 2, 2, 494, 268)
  $hListView = GUICtrlGetHandle( $idListView )
  ;GUISetState(@SW_SHOW)

  ; Increase item height                                            ; Because a larger font is set for the listview, all
  $hLVfont = _GUICtrlListView_SetItemHeightByFont( $hListView, 26 ) ; items must be displayed through WM_NOTIFY function
                                                                    ; to be able to display the text with the original font.
  ; Add columns
  _GUICtrlListView_AddColumn($idListView, "Items", 100)
  _GUICtrlListView_AddColumn($idListView, "Column 2", 100)
  _GUICtrlListView_AddColumn($idListView, "Column 3", 100)
  _GUICtrlListView_AddColumn($idListView, "Column 4", 100)

  ; Add items
  ;_GUICtrlListView_AddItem($idListView, "Item 1")                  ; More columns and lines are added to be able 
  ;_GUICtrlListView_AddItem($idListView, "Item 2")                  ; to test performance with the scrollbar. If
  ;_GUICtrlListView_AddItem($idListView, "Item 3")                  ; scrolling is OK performance is OK.
  For $i = 1 To 1000
    If Mod( $i, 3 ) = 2 Then ; GUICtrlCreateListViewItem is used because of performance
      GUICtrlCreateListViewItem( "Item " & $i & @CRLF & "Second line" & "|Item " & $i & " Col 2" & @CRLF & "Second line col 2" & "|Item " & $i & " Col 3" & @CRLF & "Second line col 3" & "|Item " & $i & " Col 4" & @CRLF & "Second line col 4", $idListView )
    Else
      GUICtrlCreateListViewItem( "Item " & $i & "|Item " & $i & " Col 2" & "|Item " & $i & " Col 3" & "|Item " & $i & " Col 4", $idListView )
    EndIf
  Next

  _GUICtrlListView_SetColumnWidth( $idListView, 0, 100 ) ; The long text lines have changed the column widths
  _GUICtrlListView_SetColumnWidth( $idListView, 1, 100 )
  _GUICtrlListView_SetColumnWidth( $idListView, 2, 100 )
  _GUICtrlListView_SetColumnWidth( $idListView, 3, 100 )

  ; Set item 2 text ; HERE I ADD NEW LINE
  ;_GUICtrlListView_SetItemText($idListView, 1, "New Item 2" & @CRLF & "second line")
  ;MsgBox($MB_SYSTEMMODAL, "Information", "Item 2 Text: " & _GUICtrlListView_GetItemText($idListView, 1))

  $iItems = _GUICtrlListView_GetItemCount( $idListView )

  ; Register WM_NOTIFY message handler
  ; To handle NM_CUSTOMDRAW notifications
  ; And to check when ListView receives/loses focus
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  ; Register WM_ACTIVATE message handler         ; If GUI loses focus selected listview items are drawn with a button face background color.
  ; To check when GUI receives/loses focus       ; When GUI receives focus selected items are redrawn with the dark blue background color.
  GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" )  ; Detection of received focus is faster through the WM_ACTIVATE message than directly
                                                 ; through the listview. This provides a faster and smoother redraw of selected items.
  GUISetState(@SW_SHOW) ; Showing the GUI at this point ensures that the listview
                        ; items are displayed through the WM_NOTIFY function.

  ; Loop until the user exits.
  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE
  GUIDelete()
EndFunc   ;==>Example

; WM_NOTIFY message handler
Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $hWnd, $iMsg, $wParam

  ; Use static variables to avoid recalculating everything on each function call
  Local Static $hDC, $iItem, $iSelected, $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect )
  Local Static $tLVitem = DllStructCreate( $tagLVITEM ), $pLVitem = DllStructGetPtr( $tLVitem )
  Local Static $tBuffer = DllStructCreate( "wchar Text[4096]" ), $pBuffer = DllStructGetPtr( $tBuffer )
  Local Static $hBrushNormal = _WinAPI_CreateSolidBrush( 0xFFFFFF ), $hBrushHighLight = _WinAPI_GetSysColorBrush( $COLOR_HIGHLIGHT ), $hBrushButtonFace = _WinAPI_GetSysColorBrush( $COLOR_BTNFACE )

  Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  Local $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hListView
      Switch $iCode
        Case $NM_CUSTOMDRAW
          Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" )
          Switch $dwDrawStage                                ; Specifies the drawing stage
            ; Stage 1
            Case $CDDS_PREPAINT                              ; Before the paint cycle begins
              $hDC = DllStructGetData( $tNMLVCustomDraw, "hDC" ) ; Device context
              _WinAPI_SelectObject( $hDC, $hLVfont )             ; Set original font <<<<<<<<<<<<<<<<<<<<<<<<<<<<
              _WinAPI_SetBkMode( $hDC, $TRANSPARENT )            ; Transparent background
              Return $CDRF_NOTIFYITEMDRAW                    ; Notify the parent window before an item is painted

            ; Stage 2
            Case $CDDS_ITEMPREPAINT                          ; Before an item is painted
              $iItem = DllStructGetData( $tNMLVCustomDraw, "dwItemSpec" )                           ; Item index
              $iSelected = GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED ) ; Item state
              Return $CDRF_NOTIFYSUBITEMDRAW                 ; Notify the parent window before a subitem is painted

            ; Stage 3
            Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM )  ; Before a subitem is painted: Default painting of checkbox, image, icon
              Return $CDRF_NOTIFYPOSTPAINT                   ; Notify the parent window after a subitem is painted

            ; Stage 4
            Case BitOR( $CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM ) ; After a subitem has been painted: Custom painting of text lines
              Local $iSubItem = DllStructGetData( $tNMLVCustomDraw, "iSubItem" ) ; Subitem index

              ; Subitem rectangle
              DllStructSetData( $tRect, "Top", $iSubItem )
              DllStructSetData( $tRect, "Left", $iSubItem ? $LVIR_BOUNDS : $LVIR_LABEL )
              GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect )

              ; Subitem back ground color
              ; Delete default painting of text because it's painted in the middle of the subitem
              ; And because it paints the entire text string including any @CRLF characters
              ; The text is deleted by filling the subitem rectangle with the back ground color
              DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $iSelected ? ( $fListViewHasFocus ? $hBrushHighLight : $hBrushButtonFace ) : $hBrushNormal ) ; _WinAPI_FillRect

              ; Subitem text color (fore color)
              DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", ( $iSelected And $fListViewHasFocus ) ? 0xFFFFFF : 0x000000 ) ; _WinAPI_SetTextColor

              ; Left margin of item text
              DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + ( $iSubItem ? 6 : 2 ) )

              ; Extract text line directly from ListView
              DllStructSetData( $tLVitem, "Mask", $LVIF_TEXT )
              DllStructSetData( $tLVitem, "SubItem", $iSubItem )
              DllStructSetData( $tLVitem, "Text", $pBuffer )
              DllStructSetData( $tLVitem, "TextMax", 4096 )
              GUICtrlSendMsg( $idListView, $LVM_GETITEMTEXTW, $iItem, $pLVitem )

              ; Does the text contain a @CRLF character combination
              Local $iPos = StringInStr( DllStructGetData( $tBuffer, "Text" ), @CRLF )

              If Not $iPos Then
                ; No @CRLF characters, draw text line
                DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText
                Return $CDRF_NEWFONT                         ; $CDRF_NEWFONT must be returned after changing font or colors
              EndIf

              ; The text is divided into two lines

              ; Paint first part of the text line
              DllStructSetData( $tBuffer, "Text", 0, $iPos ) ; 0-terminate first part of the text
              DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText

              ; Paint second part of the text line
              DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 12 ) ; Top margin
              Local $tBuffer2 = DllStructCreate( "wchar Text[" & 4096-$iPos-2 & "]", $pBuffer + 2 * $iPos + 2 ) ; Buffer for second part of the text
              DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer2, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText
              Return $CDRF_NEWFONT                           ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
        Case $NM_KILLFOCUS
          If $fListViewHasFocus Then
            GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 )
            $fListViewHasFocus = 0
          EndIf
        Case $NM_SETFOCUS
          If Not $fListViewHasFocus Then _
            GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 )
          $fListViewHasFocus = 2
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

; WM_ACTIVATE message handler
Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $iMsg, $lParam
  If $hWnd = $hGui Then _
    $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0
  Return $GUI_RUNDEFMSG
EndFunc

Func _GUICtrlListView_SetItemHeightByFont( $hListView, $iHeight )
  ; Get font of ListView control
  ; Copied from _GUICtrlGetFont example by KaFu
  ; See https://www.autoitscript.com/forum/index.php?showtopic=124526
  Local $hDC = _WinAPI_GetDC( $hListView ), $hFont = _SendMessage( $hListView, $WM_GETFONT )
  Local $hObject = _WinAPI_SelectObject( $hDC, $hFont ), $lvLOGFONT = DllStructCreate( $tagLOGFONT )
  _WinAPI_GetObject( $hFont, DllStructGetSize( $lvLOGFONT ), DllStructGetPtr( $lvLOGFONT ) )
  Local $hLVfont = _WinAPI_CreateFontIndirect( $lvLOGFONT ) ; Original ListView font
  _WinAPI_SelectObject( $hDC, $hObject )
  _WinAPI_ReleaseDC( $hListView, $hDC )
  _WinAPI_DeleteObject( $hFont )

  ; Set height of ListView items by applying text font with suitable height
  $hFont = _WinAPI_CreateFont( $iHeight, 0 )
  _WinAPI_SetFont( $hListView, $hFont )
  _WinAPI_DeleteObject( $hFont )

  ; Restore font of Header control
  Local $hHeader = _GUICtrlListView_GetHeader( $hListView )
  If $hHeader Then _WinAPI_SetFont( $hHeader, $hLVfont )

  ; Return original ListView font
  Return $hLVfont
EndFunc

I'll admit it would have been easier with some kind of UDF. I'm working on that.

1 person likes this

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

 

'll admit it would have been easier with some kind of UDF. I'm working on that.

Awesome news !!!

 

EDIT:

I have one suggestion/wish/request :

Can you use this:

This should facilitate the adaptation, in existing projects.

And one question:
Are you going in the UDFs provide the ability to assign different functions to different ListView?
Because you can at the same time use multiple ListView.

 

And second question:
Do you want to combine all your "ListView magic" (Header, colors, multiline, virtual......) in this one UDF ?

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

#13 ·  Posted (edited)

A little late reply. But at that time I had simply not enough track of the details to give a proper answer. You can find a description of the ideas here (from post 19 onwards).

The UDF will be able to support multiple listviews.

At first, I'll create UDFs for a topic at a time.

Edited by LarsJ

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