Link to home
Start Free TrialLog in
Avatar of jlbryant
jlbryant

asked on

syslistview32

I have two applications one i made the other i did not. I made a project that will tell me how many lines there are in a listview box, this works great on my projects that i have tested with, But the application that i need it to retrieve the info from CRASHES. It will give me the number of lines, BUT when it goes to get the text from the listview the app that contains the listview crashes..
Avatar of Erick37
Erick37
Flag of United States of America image

How are you trying to retrieve the text?

1: is your code inside a ActiveX control? if yes you need to clear
registry on second computer.

2: do you use API functions in your code?
 If yes see if the other computer OS is compatible with the API function.


Avatar of Ark
Hi
Retrieving data from another listview using SendMessage and pointers need interprocess memory communication, otherwise it crashes because you send pointers from YOUR process and another process don't know anything about your process address space. Pseudocode to get strings:
1. Get items count:
nCount = SendMessage(hLV, LVM_GETITEMCOUNT, 0, ByVal 0&)

2. Get ProcessID from SysListView32 handle -
tid = GetWindowThreadProcessId(hLV, pid)

3. Open process:
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, pid)

4. Allocate memory in remote process. In your case you need two memory areas - one for LV_Item structure:

Private Type LV_ITEM
    mask As Long
    iItem As Long
    iSubItem As Long
    state As Long
    stateMask As Long
    pszText As Long
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type

, another for text
Private Type ITEM_TEXT
   pszText As String * 80
End Type
'=======================
   Dim li As LV_ITEM
   Dim it As ITEM_TEXT

   liAddr = VirtualAllocEx(hProcess, 0, Len(li), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
   itAddr = VirtualAllocEx(hProcess, 0, LenB(it), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
   For i = 0 To nCount - 1
          ZeroMemory li, Len(li)
          ZeroMemory it, Len(it)
          li.cchTextMax = Len(it)
          li.mask = LVIF_TEXT
          li.pszText = itAddr
          li.iItem = i
'5. Write data into another process memory
          WriteProcessMemory hProcess, ByVal liAddr, li, Len(li), lWritten
          WriteProcessMemory hProcess, ByVal itAddr, it, Len(it), lWritten
'6. Call send message using memory pointer in REMOTE process
          Call SendMessage(hLV, LVM_GETITEMA, i, ByVal liAddr)
'7. Read data back
          ReadProcessMemory hProcess, ByVal liAddr, li, Len(li), lWritten
          ReadProcessMemory hProcess, ByVal itAddr, it, Len(it), lWritten
'8. Enjoy results :)
          Debug.print it.pszText
''Subitems====================
''If you need subitems too, make another loop:
''nHeadersCount = SendMessage(SendMessage(hLV, LVM_GETHEADER, 0, ByVal 0&), HDM_GETITEMCOUNT, 0, ByVal 0&)
'             li.mask = LVIF_TEXT
'             For j = 1 To nHeadersCount
'                 li.iSubItem = j
'                 WriteProcessMemory hProcess, ByVal liAddr, li, Len(li), lWritten
'                 WriteProcessMemory hProcess, ByVal itAddr, it, Len(it), lWritten
'                 Call SendMessage(hLV, LVM_GETITEMA, 0, ByVal liAddr)
'                 ReadProcessMemory hProcess, ByVal liAddr, li, Len(li), lWritten
'                 ReadProcessMemory hProcess, ByVal itAddr, it, Len(it), lWritten
'                 Debug.print "SubItem_" & j & "=" & it.pszText
'             Next j
''Subitems====================
      Next i
'9. Free memory in remote process
      VirtualFreeEx hProcess, ByVal liAddr, 0, MEM_RELEASE
      VirtualFreeEx hProcess, ByVal itAddr, 0, MEM_RELEASE
'10. Close handle
   If hProcess Then CloseHandle hProcess
PS. I have complite sample on duplication of remote StsListView32 (including ImageList!!!). Unfortunatelly, EE doesn't allow attachements (sample contain 8 bas modules + 1 demo form, total 41 kB).

To Bingie: is it OK to paste code here?
I vote yes!
Thanks, Erick:)
BTW, sample contain mCallApiRemote module - Call API functions from remote process address space
Avatar of VIMALCHAND
VIMALCHAND


"it" is structure of listview
when I use ZeroMemory it, Len(it), my program automatically closes without any message.
ASKER CERTIFIED SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
How can read the "ownerdraw" style list view of another program
I am able to reader the header of that listview
>How can read the "ownerdraw" style list view of another program<
Totally impossible. "Ownerdraw" style means that ListView doesn't store list items text and/or icons. Instead, every time its DC have to be redrawn, it send a message to parent program and this program redraw this LV itself.
Is there any other method to read the text of "ownerdraw" style list view of another program
Yes
Subclass (or hook) all API calls from another process
Can I you give an example (having listivew as base)
Please, RTFM about ownerdraw controls. If I'll have nothing to do and will spend a year preparing this sample, probably I'll do it. And in this case VB won't be a language I choose to solve this. So, repeat >Totally impossible (OK, 99.99999999...% impossible)<
Regards
Ark
Boss,

It is a listview control with
fill row selection,
change in the color of the text dynamcially
involves no bitmaps/icons

I need it at any language (not mean to VB)

Please give me some hints so that I can also try
VIMALCHAND, "ownerdraw" means, that whenever control have to be repainted (another window moving across it, new item added or just mouse cursor moves over it), it doesn't use inner values for text, icons etc. (pszText, iImage and other members of LV_ITEM structure, which we can extract via SendMessage API). Instead, control send WM_NOTIFY message to parent application and parent application is responsible for repainting control. It can use ANY method to do this, like DrawText/TextOut for printing text on device context, DrawIcon/BitBlt for drawing icon. Or just using SetPixel API to print text and/or draw icon pixel by pixel. These text/icons can be dynamic - say, loading from file/resourses every time or even downloaded from internet. If parent application use 'standard' API for output (say, DrawText for text and DrawIcon for icon), theoretically, you can hook API calls from another application (it's not a trivial task, I saw some samples with asm/C code, but never seen VB), parse these calls, determining target hwnd and extracting API calls parameters, like text, icons etc. But if another app use SetPixel or other non-standard output - there is no way to extract what you need...
Boss,

My ListView is a application which gets updated from an ftp. I am sure they are reading text from file which gets downloaded from the ftp. (downloaded ftp is not of text format, so I am unable to read it).
Still I have any chance to read.
Hi
>>Still I have any chance to read.<<
In most cases you won't.
Owner draw ListView keep pszText and iImage values = -1. This means that application is responsible to fill them in call back procedure in responce to WM_NOTIFY message. Probaby, you can get smth from lParam? In case of ownerdraw controls it often point to some data. But basically (it's not a joke) IMHO the simpliest way in your case is blitting LV content into DC and use some char recognition algorithm to retrive text
I am trying with WM_NOTIFY.  OK.
I am trying to find solution for my problem, anyway I will give points, since you had given solution for crash.
Multiple accounts for the asker?
Sending to the admins for review before continuing to CV
"Asker" account wanted to reward for solution in one scenario