AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

Post your working scripts, libraries and tools.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

26 Sep 2021, 04:20

Edit: Fixed SubItemHitTest on 2024-02-13.


Inspired by GuiControl_Ex by @TheArkive i started to convert some of my v1.1 scripts like LV_EX to v2. I didn't want to change the built-in GuiControl object directly, so you have to assign the extensions manually after control creation.

I didn't really test many of the methods so the class may contain many bugs. If you find some, please report them here. I'll try to fix them as soon as possible.

Sample script:

Code: Select all

; Create an ImageList to hold 10 small icons.
HIML := IL_Create(10)
; Load the ImageList with a series of icons from the DLL.
Loop 10
    IL_Add(HIML, "shell32.dll", A_Index)
BkgImages := []
Loop Files, A_WinDir . "\Web\Wallpaper\*.jpg", "RF"
   BkgImages.Push(A_LoopFileFullPath)
Rows := 20
; Create the main Gui window
Main := Gui( , "ListViewExtensions")
Main.MarginX := 20
Main.MarginY := 20
Main.AddButton("ym" , "Order 1, 2, 3, 4").OnEvent("Click", Order123)
Main.AddButton("ym", "Order 3, 2, 1, 4").OnEvent("Click", Order321)
Main.AddButton("ym", "Remove BkImage").OnEvent("Click", RemoveImage)
Main.AddButton("ym", "New BkImage").OnEvent("Click", NewImage)
Main.AddText("xm Section h20", "First visible row:")
Main.AddText("hp y+0", "Is row 20 visible?")
Main.AddText("hp y+0", "Number of visible rows:")
Main.AddText("ys hp vFVR", "00")
Main.AddText("hp y+0 vIRV", "00")
Main.AddText("hp y+0 vNOVR", "00")
Main.AddButton("ys", "New Check").OnEvent("Click", Check)
Main.AddButton("xm", "Report View").OnEvent("Click", SetView.Bind("Report"))
Main.AddButton("x+20 yp wp", "Tile View").OnEvent("Click", SetView.Bind("Tile"))
Main.AddButton("x+20 yp wp", "Black Text").OnEvent("Click", SetTxtColor.Bind("Black"))
Main.AddButton("x+20 yp wp", "White Text").OnEvent("Click", SetTxtColor.Bind("White"))
LV := Main.AddListview("xm w500 r10 Grid BackgroundFFFFD0", ["Col 1","Col 2","Col 3", "Icon"])
SB := Main.AddStatusBar()
ListViewExtensions_Add(LV)
LV.SetImageList(HIML)
Loop Rows {
   Zeroes := Format("{:03}", A_Index)
   LV.Add("Icon0", "A" . Zeroes . A_Index, "B" . Zeroes . A_Index, "C" . Zeroes . A_Index)
}
; Put an icon into column 4
Loop Rows
   LV.SetSubitemImage(A_Index, 4, Mod(A_Index, 10) + 1)
; Auto-size the columns
Loop LV.GetCount("Col")
   LV.ModifyCol(A_Index, "AutoHdr")
; Add a random background image
Index := Random(1, BkgImages.Length)
LV.SetBkImage(BkgImages[Index])
SB.SetText("   BkImage: " . BkgImages[Index])
; Set the columns for tile view
LV.SetTileInfo(0, 3, 2) ; needed only once
Check()
Main.Show()
; ----------------------------------------------------------------------------------------------------------------------
Order123(*) {
   LV.Opt("-Redraw")
   ColArr := []
   Loop LV.GetCount("Col")
      ColArr.Push(A_Index)
   LV.SetColumnOrder(ColArr)
   ColArr := LV.GetColumnOrder()
   For Each, C In ColArr
      LV.ModifyCol(C, "AutoHdr")
   LV.Opt("+Redraw")
}
; ----------------------------------------------------------------------------------------------------------------------
Order321(*) {
   LV.Opt("-Redraw")
   ColArr := [3, 2, 1]
   Loop LV.GetCount("Col")
      If (A_Index > 3)
         ColArr.Push(A_Index)
   LV.SetColumnOrder(ColArr)
   ColArr := LV.GetColumnOrder()
   For Each, C In ColArr
      LV.ModifyCol(C, "AutoHdr")
   LV.Opt("+Redraw")
}
; ----------------------------------------------------------------------------------------------------------------------
Check(*) {
   Main["FVR"].Text := LV.GetTopIndex()
   Main["IRV"].Text := LV.IsRowVisible(20)
   Main["NOVR"].Text := LV.GetRowsPerPage()
}
; ----------------------------------------------------------------------------------------------------------------------
NewImage(*) {
   LV.Opt("-Redraw")
   Index := Random(1, BkgImages.Length)
   LV.SetBkImage(BkgImages[Index])
   LV.Opt("+Redraw")
   LV.Focus()
   SB.SetText("   BkImage: " . BkgImages[Index])
}
; ----------------------------------------------------------------------------------------------------------------------
RemoveImage(*) {
   LV.Opt("-Redraw")
   LV.SetBkImage(0)
   LV.Opt("+Redraw")
   LV.Focus()
   SB.SetText("")
}
; ----------------------------------------------------------------------------------------------------------------------
SetTxtColor(Color, *) {
   LV.Opt("-Redraw")
   LV.Opt("+c" . Color)
   LV.Opt("+Redraw")
   LV.Focus()
}
; ======================================================================================================================
; Tile view changes
; ======================================================================================================================
SetView(View, *) {
   If (View = LV.GetView())
      Return
   LV.Opt("-Redraw")
   LV.Opt("+" . View)
   LV.Opt("+Redraw")
}
; ----------------------------------------------------------------------------------------------------------------------
MainClose(*) {
   ExitApp
}
; ----------------------------------------------------------------------------------------------------------------------
#Include ListViewExtensions.ahk
ListViewExtensions.ahk:

Code: Select all

#Requires AutoHotKey v2.0-beta.1
; ======================================================================================================================
; Namespace:      ListViewExtensions
; Function:       Add some more or less useful methods to Gui.ListView controls.
;                 Most of them just wrap the common list view control messages.
;                 For the purpose and the usage of the messages see:
;                 https://docs.microsoft.com/en-us/windows/win32/controls/bumper-list-view-control-reference-messages
;                 To add the methods
;                 -  create a Gui.ListView control:
;                    LV := Gui.AddListView("...", "...")
;                 -  set ListViewExtensions.Prototype as the base of this control:
;                    LV.Base := ListViewExtensions.Prototype
;                 -  or call the helper function ListViewExtensions_Add(LV).
; Tested with:    AHK 2.0-beta.1
; Tested on:      Win 10 (x64)
; Changelog:
;     0.0.00.00/20210925/just me     -  initial alpha release.
; Notes:
;     In terms of Microsoft
;        Item     stands for the whole row or the first column of the row
;        SubItem  stands for the second to last column of a row
; Credits:
;     Thanks to
;     -  TheArkive for GuiControl_Ex showing me the basic concepts.
;        -> www.autohotkey.com/boards/viewtopic.php?f=83&t=86124
;     LV_EX tile view functions:
;        Initial idea by segalion (old forum: /board/topic/80754-listview-with-multiline-in-report-mode-help/)
;        based on code from Fabio Lucarelli (http://users.skynet.be/oleole/ListView_Tiles.htm).
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
; Adds the extensions to an existing ListView control.
ListViewExtensions_Add(LV) {
   LV.Base := ListViewExtensions.Prototype
}
; ======================================================================================================================
Class ListViewExtensions Extends Gui.ListView {
   ; ===================================================================================================================
   ; Type shown by GuiControl.Type
   ; ===================================================================================================================
   Type => "ListViewX"
   ; ===================================================================================================================
   ; Additional methods
   ; ===================================================================================================================
   ; Calculates the approximate width and height required to display a given number of items.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-approximateviewrect
   CalcViewSize(Rows := 0) {
      Local Size
      Size := DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1040, "Ptr", Rows - 1, "Ptr", 0, "UInt")
      Return {W: (Size & 0xFFFF), H: (Size >> 16) & 0xFFFF}
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Enables or disables whether the items in a list-view control display as a group.
   EnableGroupView(Enable := True) {
      Return !(DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x109D, "Ptr", !!Enable, "Ptr", 0, "Int") < 0)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Searches the first column for an item containing the specified string.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-finditem
   FindString(Str, Start := 0, Partial := False) {
      Static SizeOfLVFI := 40
      LVFI := Buffer(SizeOfLVFI, 0)
      Flags := 0x0002 ; LVFI_STRING
      If (Partial)
         Flags |= 0x0008 ; LVFI_PARTIAL
      NumPut("UInt", Flags, LVFI)
      NumPut("Ptr", StrPtr(Str),  LVFI, A_PtrSize)
      Return (DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1053, "Ptr", Start - 1, "Ptr", LVFI, "Int") + 1)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Searches all columns or the specified column for a subitem containing the specified string.
   FindStringEx(Str, Column := 0, Start := 0, Partial := False) {
      If !IsInteger(Column) || (Column < 0) || (Column > This.GetCount("Col"))
         Throw ValueError("Parameter Column is invalid!", A_ThisFunc, Column)
      If !IsInteger(Start) || (Start < 0)
         Throw ValueError("Parameter Start is invalid!", A_ThisFunc, Start)
      Len := StrLen(Str)
      Row := Col := 0
      ItemList := ListViewGetContent("", This.HWND)
      Loop Parse, ItemList, "`n"
      {
         If (A_Index > Start) {
            Row := A_Index
            Columns := StrSplit(A_LoopField, "`t")
            If (Column > 0) {
               If (Partial) {
                  If (SubStr(Columns[Column], 1, Len) = Str)
                     Col := Column
               }
               Else {
                  If (Columns[Column] = Str)
                     Col := Column
               }
            }
            Else {
               For Index, ColumnText In Columns {
                  If (Partial) {
                     If (SubStr(ColumnText, 1, Len) = Str)
                        Col := Index
                  }
                  Else {
                     If (ColumnText = Str)
                        Col := Index
                  }
               } Until (Col > 0)
            }
         }
      } Until (Col > 0)
      Return (Col > 0) ? {Row: Row, Col: Col} : 0
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the background color of a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getbkcolor
   GetBkColor() {
      BC := DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1000, "Ptr", 0, "Ptr", 0, "UInt")
      Return Format("0x{:06X}", ((BC & 0x0000FF) << 16) | (BC & 0X00FF00) | ((BC & 0xFF0000) >> 16))
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the current left-to-right order of columns in a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getcolumnorderarray
   GetColumnOrder() {
      Cols := This.GetCount("Col")
      COA := Buffer(Cols * 4, 0)
      If !DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x103B, "Ptr", Cols, "Ptr", COA, "UInt")
         Return False
      ColArray := []
      Off := -4
      Loop Cols
         ColArray.Push(NumGet(COA, Off += 4, "Int") + 1)
      Return ColArray
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the width of a column in report or list view.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getcolumnwidth
   GetColumnWidth(Column) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x101D, "Ptr", Column - 1, "Ptr", 0, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; GetEditControl     -> 0x1018 - not supported as yet
   ; GetEmptyText       -> 0x10CC - not supported as yet
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the extended styles that are currently in use for a given list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getextendedlistviewstyle
   GetExtendedStyle() {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1037, "Ptr", 0, "Ptr", 0, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; GetFocusedGroup    -> 0x105D - not supported as yet
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the ID of the group the list-view item belongs to.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getitem
   GetGroup(Row) {
      Static OffGroupID := 28 + (A_PtrSize * 3)
      This.Create_LVITEM(&LVITEM, 0x00000100, Row) ; LVIF_GROUPID
      DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104B, "Ptr", 0, "Ptr", LVITEM, "UInt")
      Return NumGet(LVITEM, OffGroupID, "UPtr")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the handle of the header control used by the list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getheader
   GetHeader() {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x101F, "Ptr", 0, "Ptr", 0, "UPtr")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Determines the spacing between icons in the icon view.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getitemspacing
   GetIconSpacing(SmallIcon := 1, &CX := 0, &CY := 0) {
      CX := CY := 0
      SP := DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1033, "Ptr", !!SmallIcon, "Ptr", 0, "UInt")
      CX := SP & 0xFFFF, CY := (SP >> 16) & 0xFFFFF
      Return SP
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the value of the item's lParam field.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getitem
   GetItemParam(Row) {
      Static OffParam := 24 + (A_PtrSize * 2)
      This.Create_LVITEM(&LVITEM, 0x00000004, Row) ; LVIF_PARAM
      DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104B, "Ptr", 0, "Ptr", LVITEM, "UInt")
      Return NumGet(LVITEM, OffParam, "UPtr")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the bounding rectangle for all or part of an item in the current view.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getitemrect
   GetItemRect(Row := 1, LVIR := 0, &RECT := "") {
      RECT := Buffer(16, 0)
      NumPut("Int", LVIR, RECT)
      If !DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x100E, "Ptr", Row - 1, "Ptr", RECT, "UInt")
         Return False
      Result := {}
      Result.X := NumGet(RECT,  0, "Int"), Result.Y := NumGet(RECT,  4, "Int")
      Result.R := NumGet(RECT,  8, "Int"), Result.B := NumGet(RECT, 12, "Int")
      Result.W := Result.R - Result.X,     Result.H := Result.B - Result.Y
      Return Result
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the state of a list-view item.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getitemstate
   ; LVITEM state
   ; LVIS_FOCUSED            = 0x0001
   ; LVIS_SELECTED           = 0x0002
   ; LVIS_CUT                = 0x0004
   ; LVIS_DROPHILITED        = 0x0008
   ; LVIS_CHECKED            = 0x2000  ; not defined by MS
   GetItemState(Row, StateMask := 0x200F) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x102C, "Ptr", Row - 1, "Ptr", StateMask & 0x200F, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the height of the specified row.
   GetRowHeight(Row := 1) {
      Return This.GetItemRect(Row).H
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Calculates the number of items that can fit vertically in the visible area of a list-view
   ; control when in list or report view. Only fully visible items are counted.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getcountperpage
   GetRowsPerPage() {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1028, "Ptr", 0, "Ptr", 0, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves information about the bounding rectangle for a subitem in a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getsubitemrect
   GetSubItemRect(Column, Row := 1, LVIR := 0, &RECT := "") {
      RECT := Buffer(16, 0)
      NumPut("Int", LVIR, "Int", Column - 1, RECT)
      If !DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1038, "Ptr", Row - 1, "Ptr", RECT, "UInt")
         Return False
      If (Column = 1) && ((LVIR = 0) || (LVIR = 3))
         NumPut("Int", NumGet(RECT, 0, "Int") + This.GetColumnWidth(1), RECT, 8)
      Result := {}
      Result.X := NumGet(RECT,  0, "Int"), Result.Y := NumGet(RECT,  4, "Int")
      Result.R := NumGet(RECT,  8, "Int"), Result.B := NumGet(RECT, 12, "Int")
      Result.W := Result.R - Result.X,     Result.H := Result.B - Result.Y
      Return Result
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the maximum number of additional text lines in each tile, not counting the title.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-gettileviewinfo
   GetTileViewLines() {
      Static SizeOfLVTVI := 40, OffLines := 20
      LVTVI := Buffer(SizeOfLVTVI, 0) ; LVTILEVIEWINFO
      NumPut("UInt", SizeOfLVTVI, "UInt", 0x00000002, LVTVI)   ; cbSize, dwMask = LVTVIM_COLUMNS
      DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A3, "Ptr", 0, "Ptr", LVTVI, "Int")
      Lines := NumGet(LVTVI, OffLines, "Int")
      Return (Lines > 0 ? --Lines : 0)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the index of the topmost visible item when in list or report view.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-gettopindex
   GetTopIndex() {
      Return (DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1027, "Ptr", 0, "Ptr", 0, "Int") + 1)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Retrieves the current view of a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getview
   GetView() {
      Static Views := {0x00: "Icon", 0x01: "Report", 0x02: "IconSmall", 0x03: "List", 0x04: "Tile"}
      View := DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x108F, "Ptr", 0, "Ptr", 0, "UInt")
      Return Views.HasOwnProp(View) ? Views.%View% : ""
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets group information.  !!!Not supported as yet!!!
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getgroupinfo
   ; LVGROUP mask
   ; LVGF_ALIGN              = 0x00000008
   ; LVGF_DESCRIPTIONBOTTOM  = 0x00000800    ; >= Vista  pszDescriptionBottom is valid
   ; LVGF_DESCRIPTIONTOP     = 0x00000400    ; >= Vista  pszDescriptionTop is valid
   ; LVGF_EXTENDEDIMAGE      = 0x00002000    ; >= Vista  iExtendedImage is valid
   ; LVGF_FOOTER             = 0x00000002
   ; LVGF_GROUPID            = 0x00000010
   ; LVGF_HEADER             = 0x00000001
   ; LVGF_ITEMS              = 0x00004000    ; >= Vista  iFirstItem and cItems are valid
   ; LVGF_NONE               = 0x00000000
   ; LVGF_STATE              = 0x00000004
   ; LVGF_SUBSET             = 0x00008000    ; >= Vista  pszSubsetTitle is valid
   ; LVGF_SUBSETITEMS        = 0x00010000    ; >= Vista  readonly, cItems holds count of items in visible subset, iFirstItem is valid
   ; LVGF_SUBTITLE           = 0x00000100    ; >= Vista  pszSubtitle is valid
   ; LVGF_TASK               = 0x00000200    ; >= Vista  pszTask is valid
   ; LVGF_TITLEIMAGE         = 0x00001000    ; >= Vista  iTitleImage is valid
   GroupGetInfo(GroupID, Mask := 0xFFFFFF) {
      Static SizeOfLVGROUP := (4 * 10) + (A_PtrSize * 14)
      Return 0
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Gets the state for a specified group.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getgroupstate
   ; LVGROUP state:
   ; LVGS_COLLAPSED          = 0x00000001
   ; LVGS_COLLAPSIBLE        = 0x00000008    ; >= Vista ?
   ; LVGS_FOCUSED            = 0x00000010    ; >= Vista ?
   ; LVGS_HIDDEN             = 0x00000002
   ; LVGS_NOHEADER           = 0x00000004    ; >= Vista ?
   ; LVGS_NORMAL             = 0x00000000
   ; LVGS_SELECTED           = 0x00000020    ; >= Vista ?
   ; LVGS_SUBSETED           = 0x00000040    ; >= Vista ?
   ; LVGS_SUBSETLINKFOCUSED  = 0x00000080    ; >= Vista ?
   GroupGetState(GroupID, StateMask := 0xFF) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x105C, "Ptr", GroupID, "Ptr", StateMask & 0xFF, "UInt")
;       Static LVGS := Map("Collapsed", 0x01, "Collapsible", 0x08, "Focused", 0x10, "Hidden", 0x02, "NoHeader", 0x04,
;                          "Normal", 0x00, "Selected", 0x20, "SUBSETED",
;       Static LVGF := 0x04 ; LVGF_STATE
;       Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
;       Static OffStateMask := 8 + (A_PtrSize * 3) + 8
;       Static OffState := OffStateMask + 4
;       SetStates := 0
;       LVGS := OS > 5 ? LVGS6 : LVGS5
;       For Each, State In LVGS
;          SetStates |= State
;       VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
;       NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
;       NumPut(LVGF, LVGROUP, 4, "UInt")
;       NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
;       SendMessage, 0x1095, %GroupID%, &LVGROUP, , % "ahk_id " . HLV
;       States := NumGet(&LVGROUP, OffState, "UInt")
;       For Each, State in LVGS
;          %Each% := States & State ? True : False
;       Return ErrorLevel
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Inserts a group into a list-view control.
   ; ATM, only group attributes defined for Win XP are supported.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-insertgroup
   GroupInsert(GroupID, Header, Align := "", Index := -1) {
      ; LVM_INSERTGROUP = 0x1091 -> msdn.microsoft.com/en-us/library/bb761103(v=vs.85).aspx
      Static Alignment := {1: 1, 2: 2, 4: 4, C: 2, L: 1, R: 4}
      Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4) ; V5 (Win XP)
      Static OffHeader := 8
      Static OffGroupID := OffHeader + (A_PtrSize * 3) + 4
      Static OffAlign := OffGroupID + 12
      Static LVGF := 0x11 ; LVGF_GROUPID | LVGF_HEADER | LVGF_STATE
      Static LVGF_ALIGN := 0x00000008
      Align := SubStr(Align, 1, 1)
      Align := Alignment.HasOwnProp(Align) ? Alignment.%Align% : 0
      Mask := LVGF | (Align ? LVGF_ALIGN : 0)
      LVGROUP := Buffer(SizeOfLVGROUP, 0)
      NumPut("UInt", SizeOfLVGROUP, "UInt", Mask, LVGROUP)
      NumPut("Ptr", StrPtr(Header), LVGROUP, OffHeader)
      NumPut("Int", GroupID, LVGROUP, OffGroupID)
      NumPut("UInt", Align, LVGROUP, OffAlign)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1091, "Ptr", Index, "Ptr", LVGROUP, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Removes a group from a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-removegroup
   GroupRemove(GroupID) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1096, "Ptr", GroupID, "Ptr", 0, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Removes all groups from a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-removeallgroups
   GroupRemoveAll() {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A0, "Ptr", 0, "Ptr", 0, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the state for a specified group.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setgroupinfo
   ; LVGROUP state:
   ; LVGS_COLLAPSED          = 0x00000001
   ; LVGS_COLLAPSIBLE        = 0x00000008    ; >= Vista ?
   ; LVGS_FOCUSED            = 0x00000010    ; >= Vista ?
   ; LVGS_HIDDEN             = 0x00000002
   ; LVGS_NOHEADER           = 0x00000004    ; >= Vista ?
   ; LVGS_NORMAL             = 0x00000000
   ; LVGS_SELECTED           = 0x00000020    ; >= Vista ?
   ; LVGS_SUBSETED           = 0x00000040    ; >= Vista ?
   ; LVGS_SUBSETLINKFOCUSED  = 0x00000080    ; >= Vista ?
   GroupSetState(GroupID, StateMask, States) {
      ; LVM_SETGROUPINFO = 0x1093 -> msdn.microsoft.com/en-us/library/bb761167(v=vs.85).aspx
      Static LVGF := 0x04 ; LVGF_STATE
      Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4) ; V5 (Win XP)
      Static OffStateMask := 8 + (A_PtrSize * 3) + 8
      LVGROUP := Buffer(SizeOfLVGROUP, 0)
      NumPut("UInt", SizeOfLVGROUP, "UInt", LVGF, LVGROUP)
      NumPut("UInt", StateMask & 0xFF, "UInt", States & 0xFF, LVGROUP, OffStateMask)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1093, "Ptr", GroupID, "Ptr", LVGROUP, "Int")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Determines whether the list-view control has a specified group.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-hasgroup
   HasGroup(GroupID) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A1, "Ptr", 0, "Ptr", 0, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Checks whether the list-view control has group view enabled.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-isgroupviewenabled
   IsGroupViewEnabled() {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10AF, "Ptr", 0, "Ptr", 0, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Indicates if a row in the list-view control is checked.
   ; LVIS_CHECKED = 0x2000  ; not defined by MS
   IsRowChecked(Row) {
      Return This.GetItemState(Row, 0x2000)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Indicates if a row in the list-view control is focused.
   ; LVIS_FOCUSED = 0x0001
   IsRowFocused(Row) {
      Return This.GetItemState(Row, 0x0001)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Indicates if a row in the list-view control is selected.
   ; LVIS_SELECTED = 0x0002
   IsRowSelected(Row) {
      Return This.GetItemState(Row, 0x0002)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Indicates if a row in the list-view control is visible.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-isitemvisible
   IsRowVisible(Row) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10B6, "Ptr", Row - 1, "Ptr", 0, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; CommCtrl.h:
   ; // These next to methods make it easy to identify an item that can be repositioned
   ; // within listview. For example: Many developers use the lParam to store an identifier that is
   ; // unique. Unfortunatly, in order to find this item, they have to iterate through all of the items
   ; // in the listview. Listview will maintain a unique identifier.  The upper bound is the size of a DWORD.
   ; -------------------------------------------------------------------------------------------------------------------
   ; Maps the ID of an item to an index.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-mapidtoindex
   MapIDToIndex(ID) {
      Return (DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10B5, "Ptr", ID, "Ptr", 0, "Int") + 1)
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Maps the index of an item to an unique ID.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-mapindextoid
   MapIndexToID(Index) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10B4, "Ptr", Index - 1, "Ptr", 0, "Ptr")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Forces a list-view control to redraw a range of items.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-redrawitems
   RedrawRows(First := 0, Last := "") {
      If (First > 0) {
         If (Last = "")
            Last := First
      }
      Else {
         First := This.GetTopIndex()
         Last := First + This.GetRowsPerPage() - 1
      }
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1015, "Ptr", First - 1, "Ptr", Last - 1, "UInt") ?
             DllCall("UpdateWindow", "Ptr", This.HWND, "UInt") : False
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the background image in a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setbkimage
   ; LVBKIMAGE ulFlags
   ; LVBKIF_FLAG_ALPHABLEND  = 0x20000000
   ; LVBKIF_FLAG_TILEOFFSET  = 0x00000100
   ; LVBKIF_SOURCE_HBITMAP   = 0x00000001
   ; LVBKIF_SOURCE_NONE      = 0x00000000
   ; LVBKIF_SOURCE_URL       = 0x00000002
   ; LVBKIF_STYLE_NORMAL     = 0x00000000
   ; LVBKIF_STYLE_TILE       = 0x00000010
   ; LVBKIF_TYPE_WATERMARK   = 0x10000000
   SetBkImage(Image, Width := "", Height := "") {
      Static XAlign := {C: 50, L: 0, R: 100}, YAlign := {B: 100, C: 50, T: 0}
      HBITMAP := 0
      If IsInteger(Image)
         HBITMAP := Image
      Else If FileExist(Image) {
         If (Width = "") && (Height = "") {
            RECT := Buffer(16, 0)
            DllCall("GetClientRect", "Ptr", This.HWND, "Ptr", RECT)
            Width := NumGet(RECT, 8, "Int"), Height := NumGet(RECT, 12, "Int")
         }
         Else If (Width = "")
            Width := -1
         Else If (Height = "")
            Height := -1
         HBITMAP := LoadPicture(Image, "GDI+ w" . Width . " h" . Height)
      }
      If !(HBITMAP) && (Image != 0)
         Return False
      ; Set extended style LVS_EX_DOUBLEBUFFER to avoid drawing issues
      This.SetExtendedStyle(0x00010000, 0x00010000) ; LVS_EX_DOUBLEBUFFER = 0x00010000
      Flags := (Image = 0) ? 0x10000000 : 0x30000000 ; LVBKIF_TYPE_WATERMARK | LVBKIF_FLAG_ALPHABLEND
      SizeOfLVBKIMAGE :=  (4 * 2) + (A_PtrSize * 4)
      LVBKIMAGE := Buffer(SizeOfLVBKIMAGE, 0)
      NumPut("UInt", Flags, LVBKIMAGE), NumPut("UPtr", HBITMAP, LVBKIMAGE, A_PtrSize)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x108A, "Ptr", 0, "Ptr", LVBKIMAGE, "Ptr")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the left-to-right order of columns in a list-view control.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setcolumnorderarray
   SetColumnOrder(ColArray) {
      Cols := ColArray.Length
      COA := Buffer(Cols * 4, 0)
      Addr := COA.Ptr
      For I, C In ColArray
         Addr := NumPut("Int", C - 1, Addr)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x103A, "Ptr", Cols, "Ptr", COA, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets extended styles in list-view controls.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setextendedlistviewstyle
   SetExtendedStyle(StyleMask, Styles) {
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1036, "Ptr", StyleMask, "Ptr", Styles, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Assigns a list-view item to an existing group.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setitem
   ; ======================================================================================================================
   SetGroup(Row, GroupID) {
      Static OffGroupID := 28 + (A_PtrSize * 3)
      This.Create_LVITEM(&LVITEM, 0x00000100, Row) ; LVIF_GROUPID
      NumPut("Int", GroupID, LVITEM, OffGroupID)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104C, "Ptr", 0, "Ptr", LVITEM, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the spacing between icons in the icon view.
   SetIconSpacing(CX, CY) {
      If (CX < 4) && (CX != -1)
         CX := 4
      If (CY < 4) && (CY != -1)
         CY := 4
      XY := (CX & 0xFFFF) | ((CY & 0xFFFF) << 16)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1035, "Ptr", 0, "Ptr", XY, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the indent of the first column to the specified number of icon widths.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setitem
   SetItemIndent(Row, NumIcons) {
      Static OffIndent := 24 + (A_PtrSize * 3)
      This.Create_LVITEM(&LVITEM, 0x00000010, Row) ; LVIF_INDENT
      NumPut("Int", NumIcons, LVITEM, OffIndent)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104C, "Ptr", 0, "Ptr", LVITEM, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the lParam field of the item to the specified value.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setitem
   SetItemParam(Row, Value) {
      Static OffParam := 24 + (A_PtrSize * 2)
      This.Create_LVITEM(&LVITEM, 0x00000004, Row) ; LVIF_PARAM
      NumPut("Ptr", Value, LVITEM, OffParam)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104C, "Ptr", 0, "Ptr", LVITEM, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Assigns an image from the list-view's image list to this subitem.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setitem
   SetSubItemImage(Row, Column, Index) {
      Static OffImage := 20 + (A_PtrSize * 2)
      This.SetExtendedStyle(0x00000002, 0x00000002) ; LVS_EX_SUBITEMIMAGES = 0x00000002
      This.Create_LVITEM(&LVITEM, 0x00000002, Row, Column) ; LVIF_IMAGE
      NumPut("Int", Index - 1, LVITEM, OffImage)
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x104C, "Ptr", 0, "Ptr", LVITEM, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the additional columns displayed for this tile, and the order of those columns.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-settileinfo
   SetTileInfo(Row, Columns*) {
      ; Row      : The 1-based row number. If you specify a number less than 1, the tile info will be set for all rows.
      ; Colomns* : Array of column indices, specifying which columns are displayed for this item, and the order of those
      ;            columns. Indices should be greater than 1, because column 1, the item name, is already displayed.
      Static SizeOfLVTI := (4 * 2) + (A_PtrSize * 3)
      Static OffItem := 4
      Static OffCols := 8
      Static OffColArr := OffCols + A_PtrSize
      ColCount := Columns.Length
      Lines := This.GetTileViewLines()
      If ((Row = 0) && (ColCount != Lines)) || ((Row != 0) && (ColCount >= Lines))
         This.SetTileViewLines(ColCount)
      ColArr := Buffer(4 * (ColCount + 1), 0)
      Addr := ColArr.Ptr
      For I, Column In Columns
         Addr := NumPut("UInt", Column - 1, Addr)
      LVTI := Buffer(SizeOfLVTI, 0)                ; LVTILEINFO
      NumPut("UInt", SizeOfLVTI, LVTI)             ; cbSize
      NumPut("UInt", ColCount, LVTI, OffCols)      ; cColumns
      NumPut("Ptr", ColArr.Ptr, LVTI, OffColArr)   ; puColumns
      If (Row > 0) {
         NumPut("Int", Row - 1, LVTI, OffItem) ; iItem
         Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A4, "Ptr", 0, "Ptr", LVTI, "UInt") ; LVM_SETTILEINFO
      }
      Loop This.GetCount() {
         NumPut("Int", A_Index - 1, LVTI, OffItem) ; iItem
         If !DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A4, "Ptr", 0, "Ptr", LVTI, "UInt")
            Return False
      }
      Return True
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Sets the maximum number of additional text lines in each tile, not counting the title.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-settileviewinfo
   ; Lines : Maximum number of text lines in each item label, not counting the title.
   ; One line is added internally because the item might be wrapped to two lines!
   SetTileViewLines(Lines) {
      Static SizeOfLVTVI := 40
      Static OffLines := 20
      If (Lines > 0)
         Lines++
      LVTVI := Buffer(SizeOfLVTVI, 0)      ; LVTILEVIEWINFO
      NumPut("UInt", SizeOfLVTVI, "UInt", 0x00000003, LVTVI)     ; cbSize , dwMask = LVTVIM_TILESIZE | LVTVIM_COLUMNS
      NumPut("Int", Lines, LVTVI, OffLines) ; c_lines: max lines below first line
      Return DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x10A2, "Ptr", 0, "Ptr", LVTVI, "UInt")
   }
   ; -------------------------------------------------------------------------------------------------------------------
   ; Determines which list-view item or subitem is at a given position.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-subitemhittest
   SubItemHitTest(X := -1, Y := -1) {
      ; LVM_SUBITEMHITTEST = 0x1039 -> http://msdn.microsoft.com/en-us/library/bb761229(v=vs.85).aspx
      LVHTI := Buffer(24, 0) ; LVHITTESTINFO
      If (X = -1) || (Y = -1) {
         DllCall("GetCursorPos", "Ptr", LVHTI)
         DllCall("ScreenToClient", "Ptr", This.HWND, "Ptr", LVHTI)
      }
      Else
         NumPut("Int", X, "Int", Y, LVHTI)
      Return (DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1039, "Ptr", 0, "Ptr", LVHTI, "Int") < 0) ?
             0 : NumGet(LVHTI, 16, "Int") + 1
   }
   ; ===================================================================================================================
   ; Methods for internal use
   ; ===================================================================================================================
   Create_LVITEM(&LVITEM, Mask := 0, Row := 1, Col := 1) {
      Static LVITEMSize := 48 + (A_PtrSize * 3)
      LVITEM := Buffer(LVITEMSize, 0)
      NumPut("UInt", Mask, "Int", Row - 1, "Int", Col - 1, LVITEM)
   }
}
Enjoy! ;)
Last edited by just me on 13 Feb 2024, 06:20, edited 1 time in total.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

26 Sep 2021, 14:26

:bravo:

Cool, I tested the example, the effect is very nice.
ListViewExtensions.png
ListViewExtensions.png (137.03 KiB) Viewed 1686 times
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

27 Sep 2021, 07:17

Very nice @just me!

I can make use of this for sure.
CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

12 Feb 2024, 12:20

Hey JustMe

I started to convert a script to AHK v2. Thank you for the useful library that I already love in AHK v1.

Converting my script I stumble over this error.

After

Code: Select all

ListViewExtensions_Add(LV)
in the demo GUI, I added

Code: Select all

LV.OnEvent("Click",AnalyzeListViewClick)

...

AnalyseListViewClick(LV, RowNumber)
{
	ColumnNumber := LV.SubItemHitTest()
    MsgBox("You clicked on column number: " ColumnNumber)
}
But I get an error message that says

Error: This value of type "VarRef" does not have a property named "Ptr".
at 607: DllCall("GetCursorPos", "Ptr", &LVHTI)

Is this a bug or am I doing something wrong?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

13 Feb 2024, 05:42

@CyberKlabauter,

there's some AHK v1.1 syntax in the method. It must be changed to:

Code: Select all

   ; -------------------------------------------------------------------------------------------------------------------
   ; Determines which list-view item or subitem is at a given position.
   ; https://docs.microsoft.com/en-us/windows/win32/controls/lvm-subitemhittest
   SubItemHitTest(X := -1, Y := -1) {
      ; LVM_SUBITEMHITTEST = 0x1039 -> http://msdn.microsoft.com/en-us/library/bb761229(v=vs.85).aspx
      LVHTI := Buffer(24, 0) ; LVHITTESTINFO
      If (X = -1) || (Y = -1) {
         DllCall("GetCursorPos", "Ptr", LVHTI) ; <<<<< changed &LVHTI to LVHTI
         DllCall("ScreenToClient", "Ptr", This.HWND, "Ptr", LVHTI) ; <<<<< changed &LVHTI to LVHTI
      }
      Else
         NumPut("Int", X, "Int", Y, LVHTI)
      Return (DllCall("SendMessage", "Ptr", This.HWND, "UInt", 0x1039, "Ptr", 0, "Ptr", LVHTI, "Int") < 0) ?
             0 : NumGet(LVHTI, 16, "Int") + 1
   }
Would you please test it? I'll change the OP after your confirmation.
CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

13 Feb 2024, 06:11

Hi @just me,

Wonderful. Now it works as expected! Could not live without this feature.

LVHTI is global. So we didn't have to use "byRef" to refer to it. Right?

Thanks for the quick fix!
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

13 Feb 2024, 06:17

Thanks, LVHTI is a Buffer Object which is automatically passed as a pointer using its Ptr property.

I'll fix the OP.
CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: 2.0-beta.1 - ListViewExtensions (alpha.1)

13 Feb 2024, 06:18

Thanks for the clarification.
CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

19 Feb 2024, 16:08

@Just me
I think I run into a conflict with LV_Colors. If I use ListViewExtensions first and then LV_Colors, I get an error: "Error: LV_Colors requires a ListView control! - Specifically: ListViewX".

After changing line 42 from "Type => "ListViewX" to "Type => "ListView" it works.

I do not know which is the better approach. Maybe it is smarter to make LV_Colors work with type "ListViewX"?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

19 Feb 2024, 17:18

If it causes any trouble you can just remove the line

Code: Select all

   Type => "ListViewX"
from the class. It actually isn't needed.
CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

19 Feb 2024, 18:05

That's what I thought. Thank you for your quick reply!
Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

Yesterday, 03:04

Hi @just me.

Is it possible, with ListView, to show items that span multiple lines? What I mean is: if the value of a cell is a String with newline characters, can I have the LV expand the cell downwards to show the whole string?

Thanks Spitzi
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

Yesterday, 03:14

Hi @Spitzi,
the only way I know is to add (invisible) icons with a height of multiple rows.
Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

Yesterday, 03:46

@just me Thanks for your quick reply. Good idea, i'll try that
Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Re: AHK v2 - ListViewExtensions (alpha.1) - 2024-02-13

Yesterday, 03:56

@just me Hmm, not so easy (for me)... I see your SetSubItemImage function, but how would I be able to load a picture in it? and set it's height?

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: kunkel321, mcd and 20 guests