Link to home
Start Free TrialLog in
Avatar of MoonCalf
MoonCalf

asked on

ListView_GetItem

Hi.

I'm having real problems using the ListView_ macros in CommCtrl.pas

Can someone tell me what's wrong with this please?

////////////////////////// Delphi Code ////////////////////////////

procedure ShowItems;
var
  CPManager,
  ListView    : hWnd;
  TmpPC       : PChar;
  ListItem    : LV_ITEM;
  CurrentPos,
  ItemCount   : Integer;
begin
  CPManager:=FindWindow('TCPManager_MainWindow', 'CP Manager');
  ListView:=FindWindowEx(CPManager, 0, 'TListView', nil);
  GetMem(TmpPC, 255);
  ItemCount:=ListView_GetItemCount(ListView);
  for CurrentPos:=0 to ItemCount-1 do begin
    ListItem.mask:=LVIF_TEXT;
    ListItem.iItem:=CurrentPos;
    ListItem.iSubItem:=0;
    ListItem.pszText:=TmpPC;
    ListItem.cchTextMax:=255;
    if ListView_GetItem(ListView, ListItem) then
      ShowMessage(TmpPC);
  end;
  FreeMem(TmpPC);
end;

///////////////////////////////////////////////////////////////////


Thanks for any help,

MoonCalf
Avatar of Alone
Alone

But what are you want to do?
I don't know what exactly you are trying to do, but I do see one glaring problem. You VAR'ed TempPc as PChar and never initliazed it or assigned it a value before assigning ListItem.pszText equal to TempPc. And then you go on the show TempPc, which STILL doesn't have a value.


Good luck!!


BTW, you needn't use GetMem for Pchar... StrPcopy is cleaner. If you insist on using GetMem, you should free up that pointer with FreeMem.


GL

 
I don't know what exactly you are trying to do, but I do see one glaring problem. You VAR'ed TempPc as PChar and never initliazed it or assigned it a value before assigning ListItem.pszText equal to TempPc. And then you go on the show TempPc, which STILL doesn't have a value.


Good luck!!


BTW, you needn't use GetMem for Pchar... StrPcopy is cleaner. If you insist on using GetMem, you should free up that pointer with FreeMem.


GL

 
oops! G-g-g-got a little stutter there! S-S-S-S-Sooorry!

I have to apologize again. I just noticed that you do in fact make a call to FreeMem. What can I say? It's been a long week! <g>

Good luck!!
I guess you want to ask the list view of another process, right? I'm sorry to say, but the list view stuff works internally with messages. And most of them contain pointers. And in 32bit programming a pointer is private to each process. So this all doesn't work with list views of other processes.

The usual solution to your problem would be to put your list view loop into a little dll and inject this dll into the other process. There's also another solution, but it's undocumented...

Regards, Madshi.
Avatar of MoonCalf

ASKER

Hi Guys.

Thank you, everyone, for all comments.  Every comment is appreciated.

Madshi - "There's also another solution, but it's undocumented..."????

Could you explain it a little for me?

Thanks,

MoonCalf.
BTW, Tasomia : Thanks for the example which is great, but I was hoping that by answering the question I could also learn to manipulate an external processeses ListView.  (For example, the Task Manager.)

Thanks,

MoonCalf.
Well, you are sending a pointer to the list view of another process. The other process now wants to write the requested information to the address you gave in. But the other process writes the information in the address in its own memory/address context. Now in NT we can do the following:

(1) Allocate memory in the context of the other process by using VirtualAllocEx.
(2) Send the list view message, giving in the pointer you got from (1). Now the other process can correctly save the requested info to the requested address.
(3) But the info is now in the context of the other process, so we have to use ReadProcessMemory to get access to that info.
(4) Finally you should free the allocated memory from (1) by using VirtualFreeEx.

I'm using this logic quite often, it works absolutely fine. Unfortunately win9x doesn't support VirtualAllocEx/VirtualFreeEx, there comes the undocumented part: You can set up a memory mapped file (CreateFileMapping(-1, ...) + MapViewOfFile). The buffer will be in shared memory (which is shared between all processes system wide), so the other process can successfully write to the address and you can successfully read it - without even using ReadProcessMemory.

Regards, Madshi.
Hi Madshi.  Thanks for the comment, but huh??

Could you do me an example please.  You're talking about something that I have absolutely no idea about!

Thanks,

MoonCalf.
Ehm, sorry, no time for a real tested example. Let me just hack a bit with your sources, maybe it helps you understanding what I mean:

procedure ShowItems;
var
 CPManager,
 ListView    : hWnd;
 TmpPC       : PChar;
 PListItem   : ^LV_ITEM;
 ListItem    : LV_ITEM;
 CurrentPos,
 ItemCount   : Integer;
 pid         : dword;  // process ID
 ph          : dword;  // process handle
 c1          : dword;  // dummy variable
 arrCh
begin
 CPManager:=FindWindow('TCPManager_MainWindow', 'CP Manager');
 ListView:=FindWindowEx(CPManager, 0, 'TListView', nil);

 // ask the process ID of the other process
 GetWindowThreadProcessID(ListView, @pid);

 // open the other process
 ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);

 // allocate memory in the other process
 TmpPC := VirtualAllocEx(ph, nil, 255, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 PListItem := VirtualAllocEx(ph, nil, sizeOf(LV_ITEM), MEM_COMMIT, PAGE_EXECUTE_READWRITE);

 ItemCount:=ListView_GetItemCount(ListView);
 for CurrentPos:=0 to ItemCount-1 do begin
   ListItem.mask:=LVIF_TEXT;
   ListItem.iItem:=CurrentPos;
   ListItem.iSubItem:=0;
   ListItem.pszText:=TmpPC;
   ListItem.cchTextMax:=255;
   WriteProcessMemory(ph, PListItem, @ListItem, sizeOf(ListItem), c1);
   if ListView_GetItem(ListView, PListItem^) then begin
     ReadProcessMemory(
     ShowMessage(TmpPC);
   end;
 end;
 FreeMem(TmpPC);
end;
Thanks.  I'll give it a try and get back.

MoonCalf.
Sorry, I accidently hit the submit button, was not ready yet. Real code comes in a few moment...
ok
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

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
Madshi rulez! :)
What can I say?

Thanks Madshi, that was perfect.

Thanks everyone else, but Madshi's example has give me enough insight into this to get on with the project and do all that other stuff myself.

MoonCalf.
Thanx, guys...   :-)