|
-
Jun 1st, 2010, 02:00 AM
#1
Thread Starter
Addicted Member
Get text of the item out of listview with LVS_OWNERDRAWFIXED
how to Get itemtext of the list item out of listview with LVS_OWNERDRAWFIXED
-
Jun 1st, 2010, 03:01 AM
#2
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
What do you mean by "Out of listview"? If you can explain exactly what do you want to do then probably it will be easier to answer your query appropriately.
A good exercise for the Heart is to bend down and help another up...
Please Mark your Thread " Resolved", if the query is solved
MyGear:
★ CPU ★ Ryzen 5 5800X
★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
★ Keyboard ★ TVS Electronics Gold Keyboard
★ Mouse ★ Logitech G502 Hero
-
Jun 1st, 2010, 03:56 AM
#3
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by koolsid
What do you mean by "Out of listview"? If you can explain exactly what do you want to do then probably it will be easier to answer your query appropriately.
i mean to say is i want to get the item text from the listview(LVS_OWNERDRAWFIXED) and store in a file
-
Jun 1st, 2010, 04:44 AM
#4
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Rohit:
Constant
LVS_OWNERDRAWFIXED
Description
The owner window can paint items in report view. The list-view control sends a WM_DRAWITEM message to paint each item; it does not send separate messages for each subitem. The iItemData member of the DRAWITEMSTRUCT structure contains the item data for the specified list-view item.
If you just want the item text then why not use the following?
Code:
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const LVM_GETNEXTITEM = (LVM_FIRST + 12)
Private Const LVNI_SELECTED = &H2
A good exercise for the Heart is to bend down and help another up...
Please Mark your Thread " Resolved", if the query is solved
MyGear:
★ CPU ★ Ryzen 5 5800X
★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
★ Keyboard ★ TVS Electronics Gold Keyboard
★ Mouse ★ Logitech G502 Hero
-
Jun 1st, 2010, 11:25 AM
#5
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
LVM_GETITEMTEXT may not work with ownerdrawn controls? May want to try LVM_GETITEM and use the LVIF_TEXT flag in the LVITEM structure. Please read the remarks of that message. If you get anything other than all zeros when you call ReadProcessMemory, then things are looking up.
-
Jun 1st, 2010, 01:56 PM
#6
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Code:
Option Explicit
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As Long, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As Long, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PAGE_READWRITE As Long = &H4
Private Const MEM_RESERVE As Long = &H2000&
Private Const MEM_RELEASE As Long = &H8000&
Private Const MEM_COMMIT As Long = &H1000&
Private Const PROCESS_VM_OPERATION As Long = &H8
Private Const PROCESS_VM_READ As Long = &H10
Private Const PROCESS_VM_WRITE As Long = &H20
Private Const LVIF_TEXT As Long = &H1
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_GETITEMCOUNT As Long = (LVM_FIRST + 4)
Private Const LVM_GETHEADER As Long = (LVM_FIRST + 31)
Private Const LVM_GETITEMTEXTA As Long = (LVM_FIRST + 45)
Private Const HDI_TEXT As Long = &H2
Private Const HDM_FIRST As Long = &H1200
Private Const HDM_GETITEMCOUNT As Long = (HDM_FIRST + 0)
Private Const HDM_GETITEMA As Long = (HDM_FIRST + 3)
Private Const LVN_FIRST As Long = -100
Private Const LVN_GETDISPINFOA As Long = (LVN_FIRST - 50)
Private Type LVITEM ' 40 bytes
mask As Long
iItem As Long
iSubItem As Long
state As Long
stateMask As Long
pszText As Long ' String pointer
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
Private Type HDITEM ' 36 bytes
mask As Long
cxy As Long
pszText As Long ' String pointer
hbm As Long
cchTextMax As Long
fmt As Long
lParam As Long
iImage As Long
iOrder As Long
End Type
Private Type NMHDR
hWnd As Long
idFrom As Long
code As Long
End Type
Private Type NMLVDISPINFO
hdr As NMHDR
item As LVITEM
End Type
Private Sub Form_Load()
EnumChildWindows GetDesktopWindow, AddressOf EnumDesktopWindow, ByVal 0&
If hSysListView <> 0 Then
SysListView32ToCSV hSysListView, "C:\MyFile.txt", ","
MsgBox "DONE"
Else
MsgBox "ERROR"
End If
End Sub
'----------------------
'// IF YOU LIKE LIST ALL SysListView32 THEN
Private Sub List1_DblClick()
SysListView32ToCSV List1.ItemData(List1.ListIndex), "C:\MyFileq.txt", ","
End Sub
'-------------------------------
Public Function SysListView32ToCSV(ByVal hListView As Long, ByVal DestPath As String, ByVal Delimiter As String) As Boolean
On Error GoTo ErrHandler
Dim ListCount As Long, ColumnCount As Long, HeaderhWnd As Long
Dim ProcessID As Long, ProcessHandle As Long
Dim MemAddr1 As Long, MemAddr2 As Long
Dim i As Long, j As Long, lRtn As Long
Dim sLine As String, sText As String, ItemText As String
Dim ListViewItem As LVITEM
Dim HeaderItem As HDITEM
Dim aText(260) As Byte
Dim FF As Integer
Dim DI As NMLVDISPINFO 'trying for DISPINFO
ListCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0, ByVal 0&)
HeaderhWnd = SendMessage(hListView, LVM_GETHEADER, 0, ByVal 0&)
ColumnCount = SendMessage(HeaderhWnd, HDM_GETITEMCOUNT, 0, ByVal 0&)
If Dir(DestPath) <> "" Then Kill DestPath
GetWindowThreadProcessId hListView, ProcessID
If ProcessID = 0 Then Exit Function
ProcessHandle = OpenIPCProcess(ProcessID)
If ProcessHandle Then
FF = FreeFile
Open DestPath For Append As #FF
MemAddr1 = CreateIPCMemory(36, ProcessHandle)
MemAddr2 = CreateIPCMemory(261, ProcessHandle)
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
With HeaderItem
.cchTextMax = 260&
.mask = HDI_TEXT
.pszText = MemAddr2
End With
For i = 0 To ColumnCount - 1
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(HeaderItem), 36&
lRtn = SendMessage(HeaderhWnd, HDM_GETITEMA, i, ByVal MemAddr1)
If lRtn Then
ReadIPCMemory ProcessHandle, MemAddr2, VarPtr(aText(0)), 260&
ItemText = StrConv(aText, vbUnicode)
ItemText = Left$(ItemText, InStr(ItemText, vbNullChar) - 1)
sLine = sLine & ItemText & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Next
Print #FF, sLine
' Release virtual memory
DestroyIPCMemory ProcessHandle, MemAddr1
End If
' Create virtual memory
'MemAddr1 = CreateIPCMemory(40, ProcessHandle)
MemAddr1 = CreateIPCMemory(Len(DI), ProcessHandle)
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
End With
'doing the same to NMLVDISPINFO
With DI.item
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
End With
DI.hdr.hWnd = Me.hWnd
DI.hdr.idFrom = 0 'not sure what ID I should put here
DI.hdr.code = 0 'also not sure what code should go here
For i = 0 To ListCount - 1
sLine = vbNullString
For j = 0 To ColumnCount - 1
ListViewItem.iSubItem = j
DI.item.iSubItem = j
'DI.hdr.code = j
'WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(DI), Len(DI)
'lRtn = SendMessage(hListView, LVM_GETITEMTEXTA, i, ByVal MemAddr1)
lRtn = SendMessage(hListView, LVN_GETDISPINFOA, i, ByVal MemAddr1)
If lRtn > 0& Then
ReadIPCMemory ProcessHandle, MemAddr2, VarPtr(aText(0)), 260&
sLine = sLine & Left$(StrConv(aText, vbUnicode), lRtn) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Next
Print #FF, sLine
Next
' Release virtual memory
DestroyIPCMemory ProcessHandle, MemAddr1
End If
Close #FF
' Release virtual memory
If MemAddr2 <> 0& Then DestroyIPCMemory ProcessHandle, MemAddr2
CLoseIPCProcess ProcessHandle
SysListView32ToCSV = True
End If
Exit Function
ErrHandler:
End Function
'----------By LaVolpe ---------------------
Private Function OpenIPCProcess(ByVal ProcessID As Long) As Long
OpenIPCProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)
End Function
Private Function CreateIPCMemory(ByVal nrBytes As Long, ByRef ProcessHandle As Long) As Long
If ProcessHandle Then CreateIPCMemory = VirtualAllocEx(ProcessHandle, ByVal 0&, ByVal nrBytes, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
End Function
Private Sub WriteIPCMemory(ByVal ProcessHandle As Long, ByVal MemoryAddress As Long, ByVal srcMemory As Long, ByVal srcLength As Long)
WriteProcessMemory ProcessHandle, MemoryAddress, srcMemory, srcLength, 0
End Sub
Private Sub ReadIPCMemory(ByVal ProcessHandle As Long, ByVal MemoryAddress As Long, ByVal dstMemory As Long, ByVal dstLength As Long)
ReadProcessMemory ProcessHandle, MemoryAddress, dstMemory, dstLength, 0
End Sub
Private Sub DestroyIPCMemory(ByVal ProcessHandle As Long, ByVal MemoryAddress As Long)
VirtualFreeEx ProcessHandle, ByVal MemoryAddress, 0&, MEM_RELEASE
End Sub
Private Sub CLoseIPCProcess(ByVal ProcessHandle As Long)
CloseHandle ProcessHandle
End Sub
is this right ???
-
Jun 1st, 2010, 03:09 PM
#7
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by rohitb
is this right ???
Doesn't look right. For this test, I'd recommend rem'ing out your DI related lines and just use ListViewItem.
Per MSDN documentation I linked to, if it works, one of two things could happen:
1) The text is copied to MemAddr2
2) .pszText is changed to where the text can be found and .cchTextMax should be the text length. I am making an assumption on that last part, the documentation does not say if .cchTextMax will be changed.
Here is a modified loop for your listitems. Worth a try; worse cases: 1) crash, 2) still get no text. Changed loop to just do 1 item for the test
Code:
For i = 0 To 0 ' ListCount - 1
sLine = vbNullString
For j = 0 To 0 ' ColumnCount - 1
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
.iItem = i
.iSubItem = j
End With
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
lRtn = SendMessage(hListView, LVM_GETITEMA, 0&, ByVal MemAddr1)
If lRtn <> 0& Then
ReadIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
' To be safe, I'd resize aText() to .cchTextMax
ReDim aText(0 To ListViewItem.cchTextMax)
ReadIPCMemory ProcessHandle, ListViewItem.pszText, VarPtr(aText(0)), ListViewItem.cchTextMax
sLine = sLine & Left$(StrConv(aText, vbUnicode), lRtn) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Next
Next
Edited: You'll have to change the aText(260) declaration to just aText(). Also include constant for LVM_GETITEMA As Long = (LVM_FIRST + 5)
Last edited by LaVolpe; Jun 1st, 2010 at 03:36 PM.
-
Jun 1st, 2010, 10:40 PM
#8
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
Doesn't look right. For this test, I'd recommend rem'ing out your DI related lines and just use ListViewItem.
Per MSDN documentation I linked to, if it works, one of two things could happen:
1) The text is copied to MemAddr2
2) .pszText is changed to where the text can be found and .cchTextMax should be the text length. I am making an assumption on that last part, the documentation does not say if .cchTextMax will be changed.
Here is a modified loop for your listitems. Worth a try; worse cases: 1) crash, 2) still get no text. Changed loop to just do 1 item for the test
Code:
For i = 0 To 0 ' ListCount - 1
sLine = vbNullString
For j = 0 To 0 ' ColumnCount - 1
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
.iItem = i
.iSubItem = j
End With
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
lRtn = SendMessage(hListView, LVM_GETITEMA, 0&, ByVal MemAddr1)
If lRtn <> 0& Then
ReadIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
' To be safe, I'd resize aText() to .cchTextMax
ReDim aText(0 To ListViewItem.cchTextMax)
ReadIPCMemory ProcessHandle, ListViewItem.pszText, VarPtr(aText(0)), ListViewItem.cchTextMax
sLine = sLine & Left$(StrConv(aText, vbUnicode), lRtn) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Next
Next
Edited: You'll have to change the aText(260) declaration to just aText(). Also include constant for LVM_GETITEMA As Long = (LVM_FIRST + 5)
i tried the code u gave first with aText(260) and commenting ReDim aText(0 To ListViewItem.cchTextMax) i managed to get the column header which i was getting earlier and 1 blank line
then i tried the code with aText() and un-commenting ReDim aText(0 To ListViewItem.cchTextMax) i got a blank text file this time no column headers
-
Jun 1st, 2010, 10:50 PM
#9
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
The test was for the list items. You can get the column headers so I'd ignore that for now. BTW: If aText() is dynamic, just add this before your column headers loop: ReDim aText(0 to 260).
As for the blank line, what is the value of lRtn? Is it returning non-zero?
-
Jun 1st, 2010, 11:30 PM
#10
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
The test was for the list items. You can get the column headers so I'd ignore that for now. BTW: If aText() is dynamic, just add this before your column headers loop: ReDim aText(0 to 260).
As for the blank line, what is the value of lRtn? Is it returning non-zero?
i didnt get where exatly u want me to put ReDim aText(0 to 260)
but if i put atext(260) and then i get lrtn value as 1
-
Jun 2nd, 2010, 09:00 AM
#11
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
In post #9 above, what does lRtn have when this line is executed: If lRtn <> 0& Then
Again, not interested in the column headers, you know you can get those ok. It's the list items you can't get, correct? Please ensure your loop is identical to the one in post #9, especially the SendMessage call.
-
Jun 2nd, 2010, 12:57 PM
#12
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Code:
Public Function SysListView32ToCSV(ByVal hListView As Long, ByVal DestPath As String, ByVal Delimiter As String) As Boolean
On Error GoTo ErrHandler
Dim ListCount As Long, ColumnCount As Long, HeaderhWnd As Long
Dim ProcessID As Long, ProcessHandle As Long
Dim MemAddr1 As Long, MemAddr2 As Long
Dim i As Long, j As Long, lRtn As Long
Dim sLine As String, sText As String, ItemText As String
Dim ListViewItem As LVITEM
Dim HeaderItem As HDITEM
Dim aText() As Byte
Dim FF As Integer
Dim DI As NMLVDISPINFO 'trying for DISPINFO
ListCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0, ByVal 0&)
HeaderhWnd = SendMessage(hListView, LVM_GETHEADER, 0, ByVal 0&)
ColumnCount = SendMessage(HeaderhWnd, HDM_GETITEMCOUNT, 0, ByVal 0&)
If Dir(DestPath) <> "" Then Kill DestPath
GetWindowThreadProcessId hListView, ProcessID
If ProcessID = 0 Then Exit Function
ProcessHandle = OpenIPCProcess(ProcessID)
If ProcessHandle Then
FF = FreeFile
Open DestPath For Append As #FF
MemAddr1 = CreateIPCMemory(36, ProcessHandle)
MemAddr2 = CreateIPCMemory(261, ProcessHandle)
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
With HeaderItem
.cchTextMax = 260&
.mask = HDI_TEXT
.pszText = MemAddr2
End With
For i = 0 To ColumnCount - 1
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(HeaderItem), 36&
lRtn = SendMessage(HeaderhWnd, HDM_GETITEMA, i, ByVal MemAddr1)
Debug.Print lRtn
If lRtn Then
ReadIPCMemory ProcessHandle, MemAddr2, VarPtr(aText(0)), 260&
ItemText = StrConv(aText, vbUnicode)
ItemText = Left$(ItemText, InStr(ItemText, vbNullChar) - 1)
sLine = sLine & ItemText & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
ReDim aText(0 To 260)
End If
Next
Print #FF, sLine
' Release virtual memory
DestroyIPCMemory ProcessHandle, MemAddr1
End If
' Create virtual memory
'MemAddr1 = CreateIPCMemory(40, ProcessHandle)
MemAddr1 = CreateIPCMemory(Len(DI), ProcessHandle)
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
End With
For i = 0 To 0 ' ListCount - 1
sLine = vbNullString
For j = 0 To 0 ' ColumnCount - 1
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
.iItem = i
.iSubItem = j
End With
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
lRtn = SendMessage(hListView, LVM_GETITEMA, 0&, ByVal MemAddr1)
Debug.Print lRtn
If lRtn <> 0& Then
ReadIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
' To be safe, I'd resize aText() to .cchTextMax
ReDim aText(0 To ListViewItem.cchTextMax)
ReadIPCMemory ProcessHandle, ListViewItem.pszText, VarPtr(aText(0)), ListViewItem.cchTextMax
sLine = sLine & Left$(StrConv(aText, vbUnicode), lRtn) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Next
Next
' Release virtual memory
DestroyIPCMemory ProcessHandle, MemAddr1
End If
Close #FF
' Release virtual memory
If MemAddr2 <> 0& Then DestroyIPCMemory ProcessHandle, MemAddr2
CLoseIPCProcess ProcessHandle
SysListView32ToCSV = True
End If
Exit Function
ErrHandler:
End Function
is this right what im doing as per ur instructions and if it is right then im getting 1 as the value for lrtn
Last edited by rohitb; Jun 2nd, 2010 at 01:02 PM.
-
Jun 2nd, 2010, 01:09 PM
#13
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Just for the testing, I rem'd out stuff related to the headers. I also moved the ReDim statement up in the list. Try this version just to see if you are getting anything from the listivew items.
Code:
Public Function SysListView32ToCSV(ByVal hListView As Long, ByVal DestPath As String, ByVal Delimiter As String) As Boolean
On Error GoTo ErrHandler
Dim ListCount As Long, ColumnCount As Long, HeaderhWnd As Long
Dim ProcessID As Long, ProcessHandle As Long
Dim MemAddr1 As Long, MemAddr2 As Long
Dim i As Long, j As Long, lRtn As Long
Dim sLine As String, sText As String, ItemText As String
Dim ListViewItem As LVITEM
Dim HeaderItem As HDITEM
Dim aText() As Byte
Dim FF As Integer
Dim DI As NMLVDISPINFO 'trying for DISPINFO
ListCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0, ByVal 0&)
HeaderhWnd = SendMessage(hListView, LVM_GETHEADER, 0, ByVal 0&)
ColumnCount = SendMessage(HeaderhWnd, HDM_GETITEMCOUNT, 0, ByVal 0&)
If Dir(DestPath) <> "" Then Kill DestPath
GetWindowThreadProcessId hListView, ProcessID
If ProcessID = 0 Then Exit Function
ProcessHandle = OpenIPCProcess(ProcessID)
If ProcessHandle Then
FF = FreeFile
Open DestPath For Append As #FF
' MemAddr1 = CreateIPCMemory(36, ProcessHandle)
MemAddr2 = CreateIPCMemory(261, ProcessHandle)
' If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
'
' With HeaderItem
' .cchTextMax = 260&
' .mask = HDI_TEXT
' .pszText = MemAddr2
'
' End With
'
' ReDim aText(0 To 260) ' << Moved here
' For i = 0 To ColumnCount - 1
' WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(HeaderItem), 36&
' lRtn = SendMessage(HeaderhWnd, HDM_GETITEMA, i, ByVal MemAddr1)
' Debug.Print lRtn
' If lRtn Then
' ReadIPCMemory ProcessHandle, MemAddr2, VarPtr(aText(0)), 260&
' ItemText = StrConv(aText, vbUnicode)
' ItemText = Left$(ItemText, InStr(ItemText, vbNullChar) - 1)
' sLine = sLine & ItemText & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
' End If
' Next
'
' Print #FF, sLine
'
' ' Release virtual memory
' DestroyIPCMemory ProcessHandle, MemAddr1
'
' End If
' Create virtual memory
MemAddr1 = CreateIPCMemory(40, ProcessHandle)
' MemAddr1 = CreateIPCMemory(Len(DI), ProcessHandle)
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
For i = 0 To 0 ' ListCount - 1
sLine = vbNullString
For j = 0 To 0 ' ColumnCount - 1
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
.iItem = i
.iSubItem = j
End With
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
lRtn = SendMessage(hListView, LVM_GETITEMA, 0&, ByVal MemAddr1)
Debug.Print lRtn
If lRtn <> 0& Then
ReadIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
Debug.Print vbTab; ListViewItem.pszText; MemAddr2; ListViewItem.cchTextMax
' To be safe, I'd resize aText() to .cchTextMax
ReDim aText(0 To ListViewItem.cchTextMax)
ReadIPCMemory ProcessHandle, ListViewItem.pszText, VarPtr(aText(0)), ListViewItem.cchTextMax
sLine = sLine & Left$(StrConv(aText, vbUnicode), lRtn) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
End If
Print #FF, i, j, sLine
Next
Next
' Release virtual memory
DestroyIPCMemory ProcessHandle, MemAddr1
End If
Close #FF
' Release virtual memory
If MemAddr2 <> 0& Then DestroyIPCMemory ProcessHandle, MemAddr2
CLoseIPCProcess ProcessHandle
SysListView32ToCSV = True
End If
Exit Function
ErrHandler:
End Function
You may want to rename your original SysListView32ToCSV to SysListView32ToCSV_ORIGINAL and then paste the above as a new routine.
Last edited by LaVolpe; Jun 2nd, 2010 at 01:20 PM.
-
Jun 2nd, 2010, 01:15 PM
#14
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Oh, here's something that needs to be changed too. With LV_GETITEMA, lRtn is no longer the length of the string as it was with LV_GETITEMTEXTA. So your sLine line needs to be tweaked:
Code:
sLine = sLine & Left$(StrConv(aText, vbUnicode), _
ListViewItem.cchTextMax) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
Assuming sLine is returning something, the listitem may not be correct and have extra characters on it. If that is the case, it is easy to fix. But the big question is, do you get anything from the listview?
Last edited by LaVolpe; Jun 2nd, 2010 at 01:18 PM.
-
Jun 2nd, 2010, 09:27 PM
#15
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
Oh, here's something that needs to be changed too. With LV_GETITEMA, lRtn is no longer the length of the string as it was with LV_GETITEMTEXTA. So your sLine line needs to be tweaked:
Code:
sLine = sLine & Left$(StrConv(aText, vbUnicode), _
ListViewItem.cchTextMax) & IIf(j < ColumnCount - 1, Delimiter, vbNullString)
Assuming sLine is returning something, the listitem may not be correct and have extra characters on it. If that is the case, it is easy to fix. But the big question is, do you get anything from the listview?
with the code u gave me it created a file but no text in it
0 0 ,
this was the output of it
i also hav added a normal listview to the code is fetching the items from it but not from my application
im attaching the entire code and the output file it created
-
Jun 3rd, 2010, 07:39 AM
#16
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
What was the result of the 2 Debug lines?
Debug.Print lRtn
Debug.Print vbTab; ListViewItem.pszText; MemAddr2; ListViewItem.cchTextMax
-
Jun 3rd, 2010, 09:15 PM
#17
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
debug.print lrtn=1
Debug.Print vbTab; ListViewItem.pszText; MemAddr2; ListViewItem.cchTextMax = 46465024 46465024 260
there is a tab added in the output of Debug.Print vbTab; ListViewItem.pszText; MemAddr2; ListViewItem.cchTextMax
-
Jun 4th, 2010, 10:07 AM
#18
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Well, looking at the debug.print results, it is telling me that the pzsText member of the UDT is not being changed, nor is the text length. The lRtn=1 tells me the listview responded to the SendMessage call.
In a previous thread, I asked if the listview had the LVS_OWNERDATA style set? Does it?
If not, I would think you should get something. Here's another test you can try
1. Try to locate a owner drawn listview project
2. Run it and then try your code against that one.
If you get text back from that one, then your code works.
Otherwise you may have no option but to believe the strings are maintained by the application and not the listview.
-
Jun 4th, 2010, 10:37 PM
#19
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
Well, looking at the debug.print results, it is telling me that the pzsText member of the UDT is not being changed, nor is the text length. The lRtn=1 tells me the listview responded to the SendMessage call.
In a previous thread, I asked if the listview had the LVS_OWNERDATA style set? Does it?
If not, I would think you should get something. Here's another test you can try
1. Try to locate a owner drawn listview project
2. Run it and then try your code against that one.
If you get text back from that one, then your code works.
Otherwise you may have no option but to believe the strings are maintained by the application and not the listview.
Code:
If Not (MemAddr1 = 0& Or MemAddr2 = 0&) Then
Debug.Print "Ownerdrawn Listview? "; CBool(GetWindowLong(hListView, GWL_STYLE) And LVS_OWNERDATA)
For i = 0 To 0 ' ListCount - 1
sLine = vbNullString
For j = 0 To 0 ' ColumnCount - 1
With ListViewItem
.cchTextMax = 260&
.mask = LVIF_TEXT
.pszText = MemAddr2
.iItem = i
.iSubItem = j
End With
WriteIPCMemory ProcessHandle, MemAddr1, VarPtr(ListViewItem), 40&
lRtn = SendMessage(hListView, LVM_GETITEMA, 0&, ByVal MemAddr1)
this gave me Ownerdrawn Listview? False
also there is one application in vb which dose the same thing with the syslistview i want to get data from
Last edited by rohitb; Jun 4th, 2010 at 10:50 PM.
-
Jun 4th, 2010, 10:46 PM
#20
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Ok, I'm running out of ideas. And if the app is keeping the listitems and subitems separately, there is probably nothing you can do.
Example: I create a listivew I don't want people to take data out of. Hmmm, what could I do? Here's an idea. I make it owner drawn, pass null strings as list items and subitems. I then keep the real listitems and subitems in a custom class of mine. Now when the listview asks to paint a listitem, I get the text from my custom class and paint it myself. Sneaky but effective and a lot of work I would think.
Now it is possible that the code doesn't work. I'd definitely try with another owner-drawn listview if you can find one easily enough; or try to create your own owner-drawn listview for a test.
-
Jun 4th, 2010, 11:06 PM
#21
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
Ok, I'm running out of ideas. And if the app is keeping the listitems and subitems separately, there is probably nothing you can do.
Example: I create a listivew I don't want people to take data out of. Hmmm, what could I do? Here's an idea. I make it owner drawn, pass null strings as list items and subitems. I then keep the real listitems and subitems in a custom class of mine. Now when the listview asks to paint a listitem, I get the text from my custom class and paint it myself. Sneaky but effective and a lot of work I would think.
Now it is possible that the code doesn't work. I'd definitely try with another owner-drawn listview if you can find one easily enough; or try to create your own owner-drawn listview for a test.
there is one vb application which is fetching data from the same application's listveiw which im trying to fetch
can that application help us
-
Jun 4th, 2010, 11:30 PM
#22
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
If you have the source code, sure. If its fetching data, then a listview must be providing it. So, in that case either the fetching code is wrong above or maybe you are not looking at the correct listview?
What is the return value of GetWindowLong, passing GWL_STYLE? Curious.
Edited: And this could be a player, however unlikely. Let's say everything is custom drawn and that's why you don't get the text (assuming aText() array are all zeros). It is possible with other custom C++ like dlls that one can hook common drawing APIs like TextOut, DrawText, etc. Once those are hooked in the listview's process, any strings sent to them can be interecepted and read/modified. This is truly complicated and may be out in left field.
Using Spy++ on that other VB app might show what messages it is sending to that listview. I don't know how helpful it will be.
Last edited by LaVolpe; Jun 5th, 2010 at 12:28 AM.
-
Jun 6th, 2010, 11:27 PM
#23
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by lavolpe
if you have the source code, sure. If its fetching data, then a listview must be providing it. So, in that case either the fetching code is wrong above or maybe you are not looking at the correct listview?
What is the return value of getwindowlong, passing gwl_style? Curious.
im getting ownerdrawn listview = false
edited: And this could be a player, however unlikely. Let's say everything is custom drawn and that's why you don't get the text (assuming atext() array are all zeros). It is possible with other custom c++ like dlls that one can hook common drawing apis like textout, drawtext, etc. Once those are hooked in the listview's process, any strings sent to them can be interecepted and read/modified. This is truly complicated and may be out in left field.
Using spy++ on that other vb app might show what messages it is sending to that listview. I don't know how helpful it will be.
RETURN VALUE FOR GETWINDOWLONG PASSING GWL_STYLE IS OWNERDRAWN LISTVIEW=FALSE
im attaching the log which i got from spy++
Last edited by rohitb; Jun 6th, 2010 at 11:31 PM.
-
Jun 7th, 2010, 09:14 PM
#24
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
-
Jun 8th, 2010, 08:07 AM
#25
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by rohitb
are you there LaVolpe
Somedays, I'm not sure myself.
I don't use WinRar. Also, I was asking for the value of the GetWindowLong() call so I can see the actual style bits.
Last but not least, I'm near the end of my ability to assist. A while back I did try to download and use the app you are having issues with, but without success. So, unless someone else can help or identify anything improper with your code or a different solution, it may be up to you to do a lot of research and trial and error.
-
Jun 8th, 2010, 12:26 PM
#26
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
I was asking for the value of the GetWindowLong() call so I can see the actual style bits.
how do i get these
-
Jun 8th, 2010, 01:06 PM
#27
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Debug.Print GetWindowLong(hListView, GWL_STYLE)
-
Jun 9th, 2010, 05:39 AM
#28
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by LaVolpe
Debug.Print GetWindowLong(hListView, GWL_STYLE)
Debug.Print GetWindowLong(hListView, GWL_STYLE)=1342178317
-
Jun 9th, 2010, 09:55 AM
#29
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
I was hoping that one of the style bits would give me another clue, but it doesn't. I have to bow out and hope someone else can assist. Maybe that log (again I don't use WinRar) might be useful as a place to start looking. You said you had another app that does get the info from that listview, maybe using Spy++ on that other app might help; maybe not.
From that GWL_STYLE value, your listview has these styles: WS_CHILD, WS_VISIBLE, LVS_OWNERDRAWFIXED, LVS_REPORT, LVS_SHOWSELALWAYS, LVS_SINGLESEL
-
Jun 9th, 2010, 12:01 PM
#30
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
If its possible, you'd probably invoke the items to be drawn, or redrawn, and send/or/catch the WM_DRAWITEM message, and DRAWITEMSTRUCT.
I don't think looking anywhere else will yield item text, as quoted in post #4.
I also want to find a solution if its possible, so I'll need a test app.
What application has a listview with the LVS_OWNERDRAWFIXED style?
-
Jun 9th, 2010, 12:34 PM
#31
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
 Originally Posted by TTn
If its possible, you'd probably invoke the items to be drawn, or redrawn, and send/or/catch the WM_DRAWITEM message, and DRAWITEMSTRUCT.
I don't think looking anywhere else will yield item text, as quoted in post #4....
What application has a listview with the LVS_OWNERDRAWFIXED style?
I can't see how WM_DRAWITEM would be useful in this case. The DRAWITEMSTRUCTURE associated with that message cannot contain strings or string pointers, based on: WM_DRAWITEM is only sent with ListViews in Report style and is only sent once per list item, not for sub items. So, when received the control must draw the entire row and logic dictates that the .itemData member of the DrawItemStructure will not contain a string pointer since a single listview row can contain multiple strings.
EDITED: Using SPY++, is the listview subclassed? When looking at the window procedure for the window it will have (Subclassed) after the procedure address. I would expect the listview's parent to be subclassed so it can process WM_DrawItem messages. Just curious.
Last edited by LaVolpe; Jun 9th, 2010 at 01:14 PM.
-
Jun 9th, 2010, 04:36 PM
#32
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
I think you would have to subclass the window, or catch the message with hook. vbaccelerator has a working example for buttons, but no luck yet.
Otherwise it may not be directly possible.
-
Jun 9th, 2010, 11:27 PM
#33
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
EDITED: Using SPY++, is the listview subclassed? When looking at the window procedure for the window it will have (Subclassed) after the procedure address. I would expect the listview's parent to be subclassed so it can process WM_DrawItem messages. Just curious.
attaching the spy++ output for the thirdparty's syslistview32. the application from which i want to get data
Last edited by rohitb; Jun 9th, 2010 at 11:45 PM.
-
Jun 10th, 2010, 08:32 AM
#34
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Was that list a result of your app trying to get the data or the other app that works? Attach similar results for the other scenario: your app or the other one that works so we can see if there is any major difference.
Also, what about the subclassing (post #31)?
-
Jun 21st, 2010, 02:02 PM
#35
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
sorry for no replies but i was down on bad health
there is one software called screenscraper studio which does this
-
Jun 23rd, 2010, 11:45 AM
#36
Thread Starter
Addicted Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
-
Jun 23rd, 2010, 02:36 PM
#37
Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
It's quite a while sins I wrote somethin in VB6 but I have answered a similar question a couple of years ago.
If you have retrieved a correct process id this is how I answered the question.
Code:
Dim n As Long
Dim txt As String
Dim lvi As LVITEM
Dim pMem As Long
Dim pBuffer As Long
Dim lpNumberOfBytesWritten As Long
txt = Space(128)
pMem = VirtualAllocEx(hProcess, 0, Len(lvi), MEM_COMMIT, PAGE_READWRITE)
pBuffer = VirtualAllocEx(hProcess, 0, Len(txt), MEM_COMMIT, PAGE_READWRITE)
lvi.pszText = pBuffer
lvi.cchTextMax = Len(txt)
lvi.mask = LVIF_TEXT + LVIS_SELECTED
n = SendMessage(hwnd, LVM_GETNEXTITEM, -1, LVNI_SELECTED)
lvi.iItem = n
n = WriteProcessMemory(hProcess, ByVal pMem, lvi, Len(lvi), lpNumberOfBytesWritten)
n = SendMessage(hwnd, LVM_GETITEM, 0&, ByVal pMem)
n = ReadProcessMemory(hProcess, ByVal pMem, ByVal lvi, Len(lvi), lpNumberOfBytesWritten)
n = ReadProcessMemory(hProcess, ByVal pBuffer, ByVal txt, Len(txt), lpNumberOfBytesWritten)
Form1.List1.AddItem "Item " & lvi.iItem & ": " & txt
VirtualFreeEx hProcess, pMem, len(lvi), MEM_RELEASE
VirtualFreeEx hProcess, pBuffer, len(txt), MEM_RELEASE
CloseHandle hProcess
I hope it can help you.
-
Jun 23rd, 2010, 03:33 PM
#38
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Here are several situations for owner-draw ListView where content in not stored in ListViewItem structure:
Final - vhGrid! - 1.7 (Update July 07)
http://www.planet-source-code.com/vb...67906&lngWId=1
Situation 1. Headers are stored normally but ListItems are stored in class array vs ListViewItem structure.
Situation 2. Headers are stored normally but ListView is in virutal mode where the items are requested via event.
Private Sub ucVHGrid1_eVHVirtualAccess(ByVal lRow As Long, _
ByVal lCell As Long, _
sText As String, _
lIcon As Long)
Final 2.4.6- HyperList NGEN! The last Listview control you will ever need..
http://www.planet-source-code.com/vb...66732&lngWId=1
frmDataBaseMode.frm supplies the items via callback:
Private Sub ucHyperListNG1_eHIndirect(ByVal iItem As Long, _
ByVal iSubItem As Long, _
ByVal fMask As Long, _
sText As String, _
iImage As Long)
'/* Indirect callback method:
'/* if using an external database, this
'/* is where reecords would be passed
'/* by index into the list
'/* iItem would map to the record number
'/* iSubItem 0 is the list item, and subsequent
'/* would map to record fields intended for subitems
'/* the sText is byref, pass the item text with this var
'/* iImage could correspond to a field maintaining icon indece
'* Note to all the 'database gurus' who can't figure out a callback..
'* example of usage would be something like this:
'Dim i As Long
' rs.Move iItem, 1
' i = 0
' Dim f As Variant
' For Each f In rs.Fields
' If i = iSubItem Then
' sText = f.Value
' Exit For
' End If
' i = i + 1
' Next
-
Oct 8th, 2015, 12:59 AM
#39
Hyperactive Member
Re: Get text of the item out of listview with LVS_OWNERDRAWFIXED
Has anyone attempted to implement LVS_OWNERDRAWVARIABLE in Listview? (I know it has been done in ListBox), I searched and found: [There is no LVS_OWNERDRAWVARIABLE style (does not exist) for ListView only LVS_OWNERDRAWFIXED style].
in post #24
rohitb: are you there LaVolpe
in post #25
LaVolpe: Somedays, I'm not sure myself.
:: You gotta love the fox "LaVolpe" ::
LucasMKG
paging through vbForums archives
hoping all is well with 'rohitb' ..(based on post #35...even though its an old thread)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|