Page 2 of 3

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 13 May 2016, 21:50
by Guest888
Hi just me,

It will be wonderful if you can combine LV_EX, LV_InCellEdit, LV_Colors to one. Have you ever think about it?

Thank you so much for your brilliant work! :thumbup: :thumbup: :thumbup:

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 16 May 2016, 01:35
by just me
Hi Guest888,

I think it wouldn't make much sense. LV_EX is primarily a wrapper for list-view control messages. LV_Colors() and LV_InCellEdit() depend on the monitoring and processing of list-view notifications. Both need to run with high performance to avoid issues, so the overhead caused by calling LV_EX functions might be problematic. Also, I didn't believe that LV_Colors() and LV_InCellEdit() will work concurrently without issues, but actually some users seem to do it successfully.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 17 May 2016, 04:15
by Guest888
Thank you for your explanation. You are the best :thumbup:

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 01 Aug 2016, 22:06
by canisdibellum
@just me: sorry for my ignorance....it looks like LV_EX_FindString only searches 1st Column....is there anyway to search other columns?

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 02 Aug 2016, 02:45
by just me
LV_EX_FindStringEx() ?

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 02 Aug 2016, 08:10
by canisdibellum
ah yes....missed that one...thanks!

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 13 Aug 2016, 23:58
by Guest078
Great lib, thanks for creating it!

I was looking for a function that replaces LV_Add() / LV_Insert() but I guess it's out of this scope of this library to add something like that, right?

The reason: My GUI windows consists of several functions with more than one listview (the GUI itself and it's helper functions) and LV_Add() / LV_Insert() operate on what
is last set as the default GUI respect. Gui, ListView, <variable name of the listview>.

All that switching (+ designing of functions) is a bit cumbersome and would be so much easier if we could just use the LV_ commands with a HWND as it's target...

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 14 Aug 2016, 01:36
by just me
I didn't add replacements for the built-in LV_... functions as yet, but I already thought about.

You might want to try this:

Code: Select all

; ==================================================================================================================================
LVH_Add(HLV, Options := "", Item := "", Subitems*) {
   Static GETITEMCOUNT := 0x1004
   Row := DllCall("SendMessage", "Ptr", HLV, "UInt", GETITEMCOUNT, "Ptr", 0, "Ptr", 0, "Int") + 1
   Return LVH_Insert(HLV, Row, Options, Item, Subitems*)
}
; ==================================================================================================================================
LVH_Insert(HLV, RowNumber, Options := "", Item := "", Subitems*) {
   Static INSERTITEM := A_IsUnicode ? 0x104D : 0x1007
        , SETITEMSTATE := 0x102B
        , SETITEMTEXT := A_IsUnicode ? 0x1074 : 0x102E
        , OffText := 16 + A_PtrSize
        , OffImage := OffText + A_PtrSize + 4
   If Rownumber Is Not Integer
      Return 0
   If (RowNumber < 1)
      Return 0
   Icon := States := 0
   If (Options <> "")
      Options := " " . RegExReplace(Options, "\s+", " ") . " "
      , Icon := RegExMatch(Options, "i) Icon\K\d+", N) ? N - 1 : 0
      , States := (InStr(Options, " Check ") ? 0x2000 : 0)
                | (InStr(Options, " Focus ") ? 0x0001 : 0)
                | (InStr(Options, " Select ") ? 0x0002 : 0)
      , StMask := States | (States & 0x2000 ? 0x1000 : 0)
   VarSetCapacity(LVITEM, 40 + (A_PtrSize * 5), 0)   ; LVITEM structure
   , NumPut(0x03, LVITEM, "UInt")                    ; mask
   , NumPut(RowNumber - 1, LVITEM, 4, "Int")         ; iItem
   , NumPut(0, LVITEM, 8, "Int")                     ; iSubItem
   , NumPut(&Item, LVITEM, OffText, "Ptr")           ; pszText
   , NumPut(Icon, LVITEM, OffImage, "Int")           ; iImage
   , Row := DllCall("SendMessage", "Ptr", HLV, "UInt", INSERTITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   If (Row > -1) {
      For Index, Text In Subitems
         NumPut(Row, LVITEM, 4, "Int")
         , NumPut(A_Index, LVITEM, 8, "Int")
         , NumPut(&Text, LVITEM, OffText, "Ptr")
         , DllCall("SendMessage", "Ptr", HLV, "UInt", SETITEMTEXT, "Ptr", Row, "Ptr", &LVITEM)
      If (States)
         NumPut(States, LVITEM, 12, "UInt")     ; state
         , NumPut(StMask, LVITEM, 16, "UInt")   ; stateMask
         , DllCall("SendMessage", "Ptr", HLV, "UInt", SETITEMSTATE, "Ptr", Row, "Ptr", &LVITEM)
   }
   Return (Row + 1)
}
; ==================================================================================================================================
For now only options Icon., Check, Focus, and Select are supported.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 14 Aug 2016, 02:19
by Guest078
Wow!

I didn't test the icon options (yet) but all other work fine in a gui with multiple listviews.

Absolutely outstanding!

Thanks so much, just me :!:

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 14 Aug 2016, 08:05
by Guest078
Btw, there is a small issue with AutoHotkey_H (v2):

I've changed in LVH_Insert:

Code: Select all

If Rownumber Is Not Integer
with

Code: Select all

If (type(RowNumber) != "integer")
to not get an error and I use this small example (and both functions at the end of it):

Code: Select all

Gui, Add, ListView, HwndHwnd_LV, Index|Name
a := "a,b,c,d,e"
Loop, Parse, % a, `,
	LVH_Add(Hwnd_LV, , A_Index, A_LoopField)

Gui, Show
return

GuiClose:
	ExitApp
return

LVH_Add(...)
LVH_Insert(...)
https://s4.postimg.org/i9mgca599/testscript.png

When compiled with AutoHotkey_L (and no change), the output in the Index column shows 1, 2, ..., 5

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 15 Aug 2016, 01:30
by just me
Interesting! I don't use v2, but your issue might be caused by
v2-changes wrote:Expressions
...
Address-of: Since pure numbers and strings are now distinct types, &(var := 123) now returns the address of an int64 instead of the address of a string. ...
...

Source
Seemingly you need some extra work if you have to store a string pointer in a structure and the variable contains a pure number.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 16 Aug 2016, 22:30
by lexikos
You just need to convert the value to a string, i.e. Item := Item "".

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 18 Aug 2016, 06:22
by Guest078
Thanks again @just me & @lexikos!

Converting the integer to a string works flawlessly even in AHK v2 / _L :)

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 12 Nov 2016, 02:56
by qqap
LV_EX_SetColumnOrder is didn't work. plz fix it

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 12 Nov 2016, 05:17
by just me
Hi qqap, would you please post what you have tried?

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 28 Feb 2017, 21:02
by kczx3
Is there a way to get an array of the rows that are within a group by group ID? I am thinking it'd be sending LVM_GETGROUPINFO with the proper mask for cItems. Currently, I loop over all the rows in the listview and check if they are a part of the specific group. I'd prefer not to loop if possible.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 01 Mar 2017, 04:59
by just me
You have to assign the group to each item manually. So why don't you store the items in an array?

Code: Select all

; ======================================================================================================================
; LV_GroupGetCount - Get group item count (requires Win Vista+).
; ======================================================================================================================
LV_GroupGetCount(HLV, GroupID, ByRef FirstItem := "") {
   ; LVM_GETGROUPINFO = 0x1095 -> msdn.microsoft.com/en-us/library/bb774932(v=vs.85).aspx
   Static LVGF := 0x4000 ; LVGF_ITEMS
   Static SizeOfLVGROUP := (4 * 10) + (A_PtrSize * 14)
   Static OffFirstItem := (4 * 9) + (A_PtrSize * 11)
   FirstItem := 0
   VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
   NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
   NumPut(LVGF, LVGROUP, 4, "UInt")
   If (DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1095, "Ptr", GroupID, "Ptr", &LVGROUP, "Ptr") = GroupID) {
      FirstItem := NumGet(LVGroup, OffFirstItem, "Int") + 1
      Return NumGet(LVGroup, OffFirstItem + 4, "UInt")
   }
   Return False
}
might be of limited use, because items seem to keep their original index when added to a group.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 01 Mar 2017, 09:00
by kczx3
Thanks just me. I definitely can store them in an array. I just figured that the control was maintaining that information so I'd rather pull it from there than keep a second instance of tracking which rows are in which groups. Because of how I have my data structured, I am able to do this:

Code: Select all

groupLength := LV_GroupGetCount(hwnd, gID, firstItem)
Loop, % groupLength
	LV_GetText(ticketSessionID, firstItem + (A_Index - 1), 3)
Thanks again!

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 02 Mar 2017, 19:05
by kczx3
I am having issues with Tile view and the tiles displaying correctly. The only way I can find that they are getting spaced correctly is when Group View is enabled or toggled at least once. Seems that it causes the control to redraw and it then correctly spaces the tiles (size of the tile doesn't appear to change). I tried using LV_EX_RedrawRows() but it doesn't appear to help.

Simple code where I am seeing the issue:

Code: Select all

#Include LV_EX.ahk

Gui, +hwndhGui
Gui, Add, ListView, w200 h400 -Multi -E0x200 +Tile -Hdr AltSubmit BackgroundSilver hwndhlistview, A|B|C|D
Loop 10
	LV_Add("", "Row " A_Index " Col A", "Row " A_Index " Col B", "Row " A_Index " Col C", "Row " A_Index " Col D")
LV_EX_SetTileViewLines(hlistview, 1)
LV_EX_SetTileInfo(hlistview, 0, 2)
Gui, Show
LV_EX_RedrawRows(hlistview)
return

GuiClose:
Exit
EDIT:

Another example which is a slightly modified sample from you, just me:

Code: Select all

#NoEnv
#Include LV_EX.ahk
Gui, Add, Listview, xm w500 r10 Grid hwndHLV vVLV, Col 1|Col 2|Col 3
Loop, 10 {
   Zeroes := SubStr("000", 1, 3 - StrLen(A_Index))
   LV_Add("", "A" . Zeroes . A_Index, "B" . Zeroes . A_Index, "C" . Zeroes . A_Index)
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
LV_EX_GroupInsert(HLV, 10, "Group 1")
; MsgBox, 0, LV_EX_GroupInsert, % LV_EX_GroupInsert(HLV, 40, "Group 1") ; , , 12)
LV_EX_GroupInsert(HLV, 20, "Group 2", 2, 9999)
; MsgBox, 0, LV_EX_GroupInsert, % LV_EX_GroupInsert(HLV, 10, "Group 2", 2, 9999)
Loop, 5
   LV_EX_SetGroup(HLV, A_Index, 10)
Loop, 5
   LV_EX_SetGroup(HLV, A_Index + 5, 20)
LV_EX_GroupSetState(HLV, 10, "Collapsible")
LV_EX_GroupSetState(HLV, 20, "Collapsible")
; LV_EX_EnableGroupView(HLV)
; MsgBox, 0, LV_EX_EnableGroupView, % LV_EX_EnableGroupView(HLV)
Gui, Add, CheckBox, vCBGV gGroupView, GroupView
Gui, Add, CheckBox, vCBTV gTileView, TileView
Gui, Show, , LV_EX Groups Sample
MsgBox, 0, HasGroup, % "GoupID 10 = " . LV_EX_HasGroup(HLV, 10)
; MsgBox, 0, GetGroup, % "Row 2 = " . LV_EX_GetGroup(HLV, 2)
Return
; ----------------------------------------------------------------------------------------------------------------------
GuiClose:
ExitApp
; ----------------------------------------------------------------------------------------------------------------------
GroupView:
GuiControlGet, CBGV
LV_EX_EnableGroupView(HLV, CBGV)
Return

TileView:
	GuiControlGet, CBTV
	IF (CBTV)
		GuiControl, +Tile, %HLV%
	Else
		GuiControl, +Report, %HLV%
	LV_EX_SetTileViewLines(HLV, 2)
	LV_EX_SetTileInfo(HLV, 0, 2, 3, 4)
return
Notice how when you first check the Tile View checkbox, the tiles are overlapping. But if you uncheck, and then check the Tile View box again, the tiles are properly oriented.

Re: [LIB] LV_EX - update on 2016-04-28

Posted: 03 Mar 2017, 04:24
by just me
Seemingly the auto-sizing of the tiles is done only once when the tile view is activated. So you have to change the tile view settings before you activate the view.

Code: Select all

#NoEnv
#Include LV_EX.ahk
Gui, +hwndhGui
Gui, Add, ListView, w200 h400 -Multi -E0x200 -Hdr AltSubmit BackgroundSilver hwndhlistview, A|B|C|D ; <<<<< removed +Tile
Loop 10
	LV_Add("", "Row " A_Index " Col A", "Row " A_Index " Col B", "Row " A_Index " Col C", "Row " A_Index " Col D")
LV_EX_SetTileViewLines(hlistview, 1)
LV_EX_SetTileInfo(hlistview, 0, 2)
GuiControl, +Tile, %hlistview% ; <<<<< added
Gui, Show
Return

GuiClose:
ExitApp