I'm really surprised that "LV_GetText()" function is limited to 8191 characters only! (Really?)
Why does such unnecessary limit exist in the first place?
Anyway, Is there any work around to force the "LV_GetText()" function to get text longer than 8191 characters?
Thanks!
Solutions:
LV_GetAllText() v1.2 (uses fail loop method)
LVM_GetItemText() v1.1 (AHK 64bit supported now!) modified from jballi's function!
LVM_GetItemText() v1.0 (AHK 64bit not supported!) modified from jballi's function (old version)!
[ListView] How to force "LV_GetText()" function to get text longer than 8191 characters? Topic is solved
[ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Last edited by User on 28 Nov 2018, 00:33, edited 5 times in total.
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Did you try AccViewer?
Or: ControlGet, vText, List,, SysListView321, A
There are also these functions:
GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
Or: ControlGet, vText, List,, SysListView321, A
There are also these functions:
GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Hehe, "ControlGet" seems to be limited to 1022 characters only! Great!
D: Lets set a limit here!
U: Why?
D: Because it's cool to set limits!
Code: Select all
gui, add, listview, w600 h300 Grid +HwndLVCtrlId, Id|A|B|C
gui, add, button, gGet, Get
gui, add, text, x+5, Select a row and press "Get"
loop, 3
LV_ModifyCol(a_index, 100)
loop, 3
LV_ADD(,a_index, "A" a_index " ", "B" a_index " ", "C" a_index " ")
loop, 12000
text .= "x"
text .= "End"
LV_Modify(3, "col2", text)
gui, show
return
Get: ;_____________ Get _________________
gui, Get:Default
gui, destroy
gui, add, edit, w400 h300 +HScroll +HwndEditCtrlId,
gui, add, text, w200 vStrLen +border,
Options := "Focused Col2"
ControlGet, StringFound, List , % Options, , % "ahk_id" LVCtrlId
guicontrol, , % EditCtrlId, % StringFound
;ControlSetText , , % StringFound, % "ahk_id" EditCtrlId
guicontrol, , StrLen, % "String Length = " StrLen(StringFound)
gui, show
return
guiclose: ;_______________ gui close _________________
exitapp
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Why do you want to store that much text in one ListView's subitem only able to show up to 260 characters?
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
You shouldn't be asking such a question!
For God's sake, why in tha world if I can store 12000 or more characters in ListView's subitems and then I am limited to get only 1022 or 8191 characters from them?
Really, I see no sense in that!
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Really, I see no sense in storing 12000 characters or more in one subitem and trying to get the same 12000 or more characters back again.
-
- Posts: 440
- Joined: 28 Apr 2018, 21:59
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
As a work around you could store the larger text into a variable under the specific row number. But as for the limit its most likely there since they expect a listview to be extremely large in some cases, and more data will slow the whole listview down, which they probably tested with a large amount of fake data. You can think of it like a file, the more and more data you put into that file the longer it will take to read it and find the data you want.
Edit: Personally I only use listviews for simple searching, for example csv files and such. Even if the data value is large I can always still go back and get all the data from the file.
Edit: Personally I only use listviews for simple searching, for example csv files and such. Even if the data value is large I can always still go back and get all the data from the file.
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
It's clear that the programmer was really undecided about 8191 limit, see source code below:MannyKSoSo wrote: ↑23 Oct 2018, 11:32As a work around you could store the larger text into a variable under the specific row number. But as for the limit its most likely there since they expect a listview to be extremely large in some cases, and more data will slow the whole listview down, which they probably tested with a large amount of fake data. You can think of it like a file, the more and more data you put into that file the longer it will take to read it and find the data you want.
Edit: Personally I only use listviews for simple searching, for example csv files and such. Even if the data value is large I can always still go back and get all the data from the file.
8191 programmer comments: https://github.com/Lexikos/AutoHotkey_L ... t.h#LC2548
git file: https://github.com/Lexikos/AutoHotkey_L ... e/script.h
So, the programmer badly decided to impose the 8191 limit!
This is sad!
Code: Select all
#define LV_REMOTE_BUF_SIZE 1024 // 8192 (below) seems too large in hindsight, given that an LV can only display the first 260 chars in a field.
#define LV_TEXT_BUF_SIZE 8192 // Max amount of text in a ListView sub-item. Somewhat arbitrary: not sure what the real limit is, if any.
enum LVColTypes {LV_COL_TEXT, LV_COL_INTEGER, LV_COL_FLOAT}; // LV_COL_TEXT must be zero so that it's the default with ZeroMemory.
struct lv_col_type
{
UCHAR type; // UCHAR vs. enum LVColTypes to save memory.
bool sort_disabled; // If true, clicking the column will have no automatic sorting effect.
UCHAR case_sensitive; // Ignored if type isn't LV_COL_TEXT. SCS_INSENSITIVE is the default.
bool unidirectional; // Sorting cannot be reversed/toggled.
bool prefer_descending; // Whether this column defaults to descending order (on first click or for unidirectional).
};
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
It would be nice if you would explain the sense you believe to see.
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
The code below uses a nice function from "jballi" Autohotkey forum user!
The "LVM_GetItemText()" function can get more than 8191 chars from ListView's subitem!
The only problem is that, you have to set the Max characters allowed! The question is, how to set the Max characters to unlimited?
The "LVM_GetItemText()" function can get more than 8191 chars from ListView's subitem!
The only problem is that, you have to set the Max characters allowed! The question is, how to set the Max characters to unlimited?
Code: Select all
gui, add, listview, w600 h300 Grid +HwndLVCtrlId, Id|A|B|C
gui, add, button, gGet, Get - row3 / col2 - data
loop, 3
LV_ModifyCol(a_index, 100)
loop, 3
LV_ADD(,a_index, "A" a_index " ", "B" a_index " ", "C" a_index " ")
loop, 12000
text .= "x"
text .= "End"
LV_Modify(3, "col2", text)
gui, show
return
Get: ;_____________ Get _________________
gui, Get:Default
gui, destroy
gui, add, edit, w400 h300 +HScroll +HwndEditCtrlId,
gui, add, text, w200 vStrLen +border,
StringFound := LVM_GetItemText(LVCtrlId, 3, 2) ;3=row, 2=col
guicontrol, , % EditCtrlId, % StringFound
;ControlSetText , , % StringFound, % "ahk_id" EditCtrlId
guicontrol, , StrLen, % "String Length = " StrLen(StringFound)
gui, show
return
guiclose: ;_______________ gui close _________________
exitapp
LVM_GetItemText(hLV,p_Item,p_Column=1,p_MaxTCHARs=32768) ;_______________ LVM_GetItemText(Function) - v1.0 "User" - by "jballi" Autohotkey forum user ____________________
{
;by "jballi" Autohotkey forum user:
;https://autohotkey.com/board/topic/99547-longer-text-in-listview/
Static Dummy5384
p_Item--
p_Column--
;-- LVITEM flags
,LVIF_TEXT :=0x1
;-- Messages
,LVM_GETITEMTEXTA:=0x102D ;-- LVM_FIRST + 45
,LVM_GETITEMTEXTW:=0x1073 ;-- LVM_FIRST + 115
;;;;; ;-- Parameters
;;;;; if p_MaxTCHARs is not Integer
;;;;; p_MaxTCHARs:=32768
;-- Workarounds for AutoHotkey Basic
PtrSize:=A_PtrSize ? A_PtrSize:4
PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"
;-- Define/Populate LVITEM Structure
VarSetCapacity(l_Text,A_IsUnicode ? p_MaxTCHARs*2:p_MaxTCHARs,0)
VarSetCapacity(LVITEM,20+PtrSize+4,0)
NumPut(LVIF_TEXT, LVITEM,0,"UInt") ;-- mask
NumPut(p_Item, LVITEM,4,"Int") ;-- iItem
NumPut(p_Column, LVITEM,8,"Int") ;-- iSubItem
NumPut(&l_Text, LVITEM,20,PtrType) ;-- pszText
NumPut(p_MaxTCHARs,LVITEM,20+PtrSize,"Int") ;-- cchTextMax
;-- Note: cchTextMax contains the number of TCHARs in the buffer pointed
; to by pszText.
;-- Collect text
SendMessage
,% A_IsUnicode ? LVM_GETITEMTEXTW:LVM_GETITEMTEXTA
,p_Item
,&LVITEM
,,ahk_id %hLV%
;;;;; outputdebug End Function: %A_ThisFunc% - ErrorLevel=%ErrorLevel%
;;;;; Return % StrGet(&Text)
VarSetCapacity(l_Text,-1)
Return l_Text
}
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
@User, thanks to you for finding and resurrecting that code, and of course thanks to @jballi for writing it.
I believe that will be very useful for me. (I've been lurking in this thread, as the issue is important to me.)
BTW, I don't have it running with 64-bit AHK 1.1.30.00 yet (will post if I have success), but with 32-bit so far it runs fine changing pMax_TCHARS value to 131072.
Regards,
burque505
I believe that will be very useful for me. (I've been lurking in this thread, as the issue is important to me.)
BTW, I don't have it running with 64-bit AHK 1.1.30.00 yet (will post if I have success), but with 32-bit so far it runs fine changing pMax_TCHARS value to 131072.
Regards,
burque505
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
@User, I don't know this for sure, but I think for 32-bit the max number is going to be 4,294,967,295 (unsigned int). I set it to that:
tried a loop of 1,500,000, and it did not choke, and actually only took a couple of seconds.
Granted, this is a bit of a smoke test I don't think I'd ever really want to set it that high.
But I certainly would like to use this with 64-bit AHK!
Regards,
burque505
Code: Select all
VarSetCapacity(l_Text,A_IsUnicode ? p_MaxTCHARs*2:p_MaxTCHARs,4294967295)
Granted, this is a bit of a smoke test I don't think I'd ever really want to set it that high.
But I certainly would like to use this with 64-bit AHK!
Regards,
burque505
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
- @User: Did you try AccViewer or my functions library (specifically JEE_LVGetText)? In the link (see post 2 of this thread) I even mention a thread where I tested controls to see what the string length limits were.
- I would genuinely be interested as to why you need to store so many characters.
- I would genuinely be interested as to why you need to store so many characters.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Just adding my 2 cents...
If the LVM_GETITEMTEXT message is used to get the text of a ListView item, a predefined buffer must be defined. There is no way to get around it that I know of. AutoHotkey sets 8K character limit. The LVM_GetItemText function that I wrote uses a 32K character limit default but the developer can change it to any value.
For this message, setting a limit that would create a gargantuan buffer can be very detrimental. Every call to the function requires that the buffer be created, loaded, and released. If the maximum size was set to 4GB, 4GB of memory would be allocated and released for every call. This "requirement" could slow down your script substantially.
The best course of action is to set a reasonable size limit based on your application. If needed, increase the default or set/change the size as needed.
Them be my thoughts.
If the LVM_GETITEMTEXT message is used to get the text of a ListView item, a predefined buffer must be defined. There is no way to get around it that I know of. AutoHotkey sets 8K character limit. The LVM_GetItemText function that I wrote uses a 32K character limit default but the developer can change it to any value.
For this message, setting a limit that would create a gargantuan buffer can be very detrimental. Every call to the function requires that the buffer be created, loaded, and released. If the maximum size was set to 4GB, 4GB of memory would be allocated and released for every call. This "requirement" could slow down your script substantially.
The best course of action is to set a reasonable size limit based on your application. If needed, increase the default or set/change the size as needed.
Them be my thoughts.
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
@jballi, thanks for your words of wisdom.
Might I ask what would need to be changed in the script for it to work with 64-bit AHK?
Regards,
burque505
Might I ask what would need to be changed in the script for it to work with 64-bit AHK?
Regards,
burque505
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
Using VarSetCapacity for "LVITEM" variable only once and making it a "static" variable would not help?
I didn't notice that function of yours, I will test it and report here the results!
"I would genuinely be interested as to why you need to store so many characters."
I just want to get exactly what I stored in a listview item! That's it!
I tried all the Unicode characters from 1 to 1114111 , on win7 x32, p_MaxTCHARs=4.000.000, no problems found!
Code: Select all
;The Max Chars the function can Get must be Specified!
gui, wait: add, text, w300 h200, Please Wait!!!
gui, wait: show
gui, add, listview, w600 h300 Grid +HwndLVCtrlId, Id|A|B|C
gui, add, button, gGet, Get - row3 / col2 - data
loop, 3
LV_ModifyCol(a_index, 100)
loop, 3
LV_ADD(,a_index, "A" a_index " ", "B" a_index " ", "C" a_index " ")
loop, 1114111
text .= chr(a_index)
text .= "`r`nEnd"
LV_Modify(3, "col2", text)
gui, wait: destroy
gui, show
return
Get: ;_____________ Get _________________
gui, wait: add, text, w300 h200, Please Wait!!!
gui, wait: show
gui, Get:Default
gui, destroy
gui, add, edit, w400 h300 +HScroll +HwndEditCtrlId,
gui, add, text, w400 vStrLen +border,
StringFound := LVM_GetItemText(LVCtrlId, 3, 2) ;3=row, 2=col
if (text == StringFound) ;"==" is case sensitive
Result := "Matched"
else
Result := "Un-Matched"
;guicontrol, , % EditCtrlId, % StringFound
ControlSetText , , % StringFound, % "ahk_id" EditCtrlId
guicontrol, , StrLen, % "String Length = " StrLen(StringFound) " / 'Text' and 'StringFound' vars " Result "!"
gui, wait: destroy
gui, show
return
guiclose: ;_______________ gui close _________________
WaitGuiClose:
exitapp
LVM_GetItemText(hLV,p_Item,p_Column=1,p_MaxTCHARs=4000000) ;_______________ LVM_GetItemText(Function) - v1.0 "User" - by "jballi" Autohotkey forum user ____________________
{
;by "jballi" Autohotkey forum user:
;https://autohotkey.com/board/topic/99547-longer-text-in-listview/
Static Dummy5384
p_Item--
p_Column--
;-- LVITEM flags
,LVIF_TEXT :=0x1
;-- Messages
,LVM_GETITEMTEXTA:=0x102D ;-- LVM_FIRST + 45
,LVM_GETITEMTEXTW:=0x1073 ;-- LVM_FIRST + 115
;;;;; ;-- Parameters
;;;;; if p_MaxTCHARs is not Integer
;;;;; p_MaxTCHARs:=32768
;-- Workarounds for AutoHotkey Basic
PtrSize:=A_PtrSize ? A_PtrSize:4
PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"
;-- Define/Populate LVITEM Structure
VarSetCapacity(l_Text,A_IsUnicode ? p_MaxTCHARs*2:p_MaxTCHARs,0)
VarSetCapacity(LVITEM,20+PtrSize+4,0)
NumPut(LVIF_TEXT, LVITEM,0,"UInt") ;-- mask
NumPut(p_Item, LVITEM,4,"Int") ;-- iItem
NumPut(p_Column, LVITEM,8,"Int") ;-- iSubItem
NumPut(&l_Text, LVITEM,20,PtrType) ;-- pszText
NumPut(p_MaxTCHARs,LVITEM,20+PtrSize,"Int") ;-- cchTextMax
;-- Note: cchTextMax contains the number of TCHARs in the buffer pointed
; to by pszText.
;-- Collect text
SendMessage
,% A_IsUnicode ? LVM_GETITEMTEXTW:LVM_GETITEMTEXTA
,p_Item
,&LVITEM
,,ahk_id %hLV%
;;;;; outputdebug End Function: %A_ThisFunc% - ErrorLevel=%ErrorLevel%
;;;;; Return % StrGet(&Text)
VarSetCapacity(l_Text,-1)
Return l_Text
}
Re: [ListView] How to force "LV_GetText()" function to get text longer than 8191 characters?
@jeeswg, I tried your function, but it does not work, gives an error!
Code: Select all
gui, wait: add, text, w300 h200, Please Wait!!!
gui, wait: show
gui, add, listview, w600 h300 Grid +HwndLVCtrlId, Id|A|B|C
gui, add, button, gGet, Get - row3 / col2 - data
loop, 3
LV_ModifyCol(a_index, 100)
loop, 3
LV_ADD(,a_index, "A" a_index " ", "B" a_index " ", "C" a_index " ")
loop, 1114111
text .= chr(a_index)
text .= "`r`nEnd"
LV_Modify(3, "col2", text)
gui, wait: destroy
gui, show
return
Get: ;_____________ Get _________________
gui, wait: add, text, w300 h200, Please Wait!!!
gui, wait: show
gui, Get:Default
gui, destroy
gui, add, edit, w400 h300 +HScroll +HwndEditCtrlId,
gui, add, text, w400 vStrLen +border,
StringFound := JEE_LVGetText(hCtl, "f", 2) ;f-focusedrow 2col
if (text == StringFound) ;"==" is case sensitive
Result := "Matched"
else
Result := "Un-Matched"
;guicontrol, , % EditCtrlId, % StringFound
ControlSetText , , % StringFound, % "ahk_id" EditCtrlId
guicontrol, , StrLen, % "String Length = " StrLen(StringFound) " / 'Text' and 'StringFound' vars " Result "!"
gui, wait: destroy
gui, show
return
guiclose: ;_______________ gui close _________________
WaitGuiClose:
exitapp
JEE_LVGetText(hCtl, vList:=-1, vCol:=-1, vSep:="`n", vSepTab:="`t", vOpt:="")
{
vErr := A_PtrSize=8 && JEE_WinIs64Bit(hCtl) ? -1 : 0xFFFFFFFF
(vList = "") && (vList := -1)
vScriptPID := DllCall("kernel32\GetCurrentProcessId", UInt)
vPID := WinGetPID("ahk_id " hCtl)
if (vPID = vScriptPID)
vIsLocal := 1, vPIs64 := (A_PtrSize=8)
;count items (rows) and columns
if !vCount := SendMessage(0x1004, 0, 0,, "ahk_id " hCtl) ;LVM_GETITEMCOUNT := 0x1004
return
if !hLVH := SendMessage(0x101F,,,, "ahk_id " hCtl) ;LVM_GETHEADER := 0x101F
return
if !vCountCol := SendMessage(0x1200,,,, "ahk_id " hLVH) ;HDM_GETITEMCOUNT := 0x1200
return
if (vCountCol = vErr) ;-1
return
if (vCol = -1)
{
vCol := "1"
Loop, % vCountCol - 1
vCol .= "," (A_Index+1)
}
if IsObject(vList)
oArray := vList
else if InStr(vList, ",")
oArray := StrSplit(vList, ",")
else if (SubStr(vList, 1, 1) = "f")
{
;LVNI_FOCUSED := 0x1
vIndex := SendMessage(0x100C, -1, 0x1,, "ahk_id " hCtl) ;LVM_GETNEXTITEM := 0x100C
if (vIndex = vErr) ;-1
return
oArray := [vIndex+1]
}
else if (SubStr(vList, 1, 1) = "s")
{
oArray := {}
;LVNI_SELECTED := 0x2
vItem := -1
Loop
{
vItem := SendMessage(0x100C, vItem, 0x2,, "ahk_id " hCtl) ;LVM_GETNEXTITEM := 0x100C
if (vItem = vErr) ;-1
break
oArray.Push(vItem+1)
}
}
else if !(vList = -1)
oArray := [vList]
if !vIsLocal
{
if !hProc := JEE_DCOpenProcess(0x438, 0, vPID)
return
if A_Is64bitOS && !DllCall("kernel32\IsWow64Process", Ptr,hProc, PtrP,vIsWow64Process)
return
vPIs64 := !vIsWow64Process
}
vPtrType := vPIs64?"Int64":"Int"
vMaxChars := RegExReplace(vOpt "m260", ".*?m(\d+).*", "$1")
vSize1 := vPIs64?40:28
vSize2 := vMaxChars << !!A_IsUnicode
VarSetCapacity(LVITEM, vSize1, 0)
VarSetCapacity(vTemp, vSize2, 0)
if !vIsLocal
{
if !pBuf := JEE_DCVirtualAllocEx(hProc, 0, vSize1+vSize2, 0x3000, 0x4)
return
pBuf2 := pBuf + vSize1
}
else
pBuf := &LVITEM, pBuf2 := &vTemp
NumPut(0x1, &LVITEM, 0, "UInt") ;mask ;LVIF_TEXT := 0x1
NumPut(pBuf2, &LVITEM, vPIs64?24:20, vPtrType) ;pszText
NumPut(vMaxChars, &LVITEM, vPIs64?32:24, "Int") ;cchTextMax
if !vIsLocal
JEE_DCWriteProcessMemory(hProc, pBuf, &LVITEM, vSize1, 0)
vMsg := A_IsUnicode?0x1073:0x102D
if vGetObj := !!InStr(vOpt, "o")
(oOutput := {}).SetCapacity(vCount)
else
VarSetCapacity(vOutput, 100*vCount << !!A_IsUnicode)
Loop, % oArray.Length() ? oArray.Length() : vCount
{
vIndex := (vList = -1) ? A_Index-1 : oArray[A_Index]-1
if vGetObj
oOutput[vIndex+1] := {}
else
vOutput .= (A_Index=1?"":vSep)
Loop, Parse, vCol, % ","
{
StrPut("", &vTemp)
NumPut(vIndex, &LVITEM, 4, "Int") ;iItem
NumPut(A_LoopField-1, &LVITEM, 8, "Int") ;iSubItem
if !vIsLocal
JEE_DCWriteProcessMemory(hProc, pBuf+4, &LVITEM+4, 8, 0)
vChars := SendMessage(vMsg, vIndex, pBuf,, "ahk_id " hCtl) ;LVM_GETITEMTEXTW := 0x1073 ;LVM_GETITEMTEXTA := 0x102D
vSize2X := (vChars+1) << !!A_IsUnicode
if vChars && !vIsLocal
JEE_DCReadProcessMemory(hProc, pBuf2, &vTemp, vSize2X, 0)
VarSetCapacity(vTemp, -1)
if vGetObj
oOutput[vIndex+1].Push(vTemp)
else
vOutput .= (A_Index=1?"":vSepTab) vTemp
}
}
if !vIsLocal
{
JEE_DCVirtualFreeEx(hProc, pBuf, 0, 0x8000)
JEE_DCCloseHandle(hProc)
}
if vGetObj
return oOutput
else
return vOutput
}
Who is online
Users browsing this forum: yabab33299 and 137 guests