External application List to memo

Hi.

How can i pass the content of a list of an external application to my memo ?

This is a part of my code :
...
     cnt:=ListView_GetItemCount(StrToInt(Edit1.Text)); //Handle of the list component (SysListView)
     GetMem(lpBuff, 200);
     for I:=0 to cnt-1 do
     begin
         ListView_GetItemText(Handle, I, 0, lpBuff, 200);
         Memo1.Lines.Add(string(lpBuff));
     end;
     FreeMem(lpBuff);
...

But his doesnt work. It brings weird stuff..

Thanks in advance.
LVL 16
CodedKSenior Software EngineerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

2266180Commented:
is lpBuff of type pchar or pointer? if pointer, make it pchar. can't see anything else wrong.
0
CodedKSenior Software EngineerAuthor Commented:
Hi Ciuly.

Its Pchar...

One line thats wrong is : >> ListView_GetItemText(Handle, I, 0, lpBuff, 200);

It should be :                 >> ListView_GetItemText(StrToInt(Edit1.Text), I, 0, lpBuff, 200);

But everytime i try to do it the external application crash (I've tried many apps not just one)
0
2266180Commented:
hm.. I did some investigation and it seems that this might be "a process accessing another process memory" issue. I am not exactly sure how to fix this. I was thinking to allocate the memory in adifferent way but can't seem to find a function that would allow me to set a flag so that the memory can be shared across processes. didn't work much with this sort of stuff.
0
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Russell LibbySoftware Engineer, Advisory Commented:

I can provide a solution, but its NT based only due to the call to the API calls used (NT/Win2k/XP/2003). Anyways, you have 2 problems:

1 - Reading / passing memory in another process. (you can't pass memory from your process to another, it just does not work that way.)
2 - A lot of list view handlers don't respond to the ListView_GetItemText, but they ALL respond to ListView_GetItem

So this means allocating memory in the other process, then reading / writing / passing that memory pointer. I have source that simplifies much of this, and can be downloaded from:

http://users.adelphia.net/~rllibby/downloads/processmemory.zip

Include the ProcessMemory unit in your uses clause, then try the following code. The code allocates a block of memory to use as the list view item record, and another to use as the string pointer to pass. Once the remote funtion fills in the list view item, you only have to read the string blocks LocalMemory pointer (which handles the reading from remote to a local storage area).

Let me know if you have problems or questions,
Russell

---
var  pmRemote:      TProcessMemory;
     szString:      String;
     lvItem:        TLVItem;
     handle:        HWND;
     cnt:           Integer;
     i:             Integer;
     idxItem:       Integer;
     idxString:     Integer;
begin

  // Get handle to list view in remote process
  handle:=StrToInt(Edit1.Text);

  // Create handler for remote process
  pmRemote:=TProcessMemory.CreateFromHwnd(handle);
  try
     // Allocate block for the lvItem and the string to read the text from
     idxItem:=pmRemote.Add(SizeOf(TLVItem));
     idxString:=pmRemote.Add(1024);
     // Get list count
     cnt:=ListView_GetItemCount(handle);
     // Walk items
     for i:=0 to cnt-1 do
     begin
        // Clear local item
        FillChar(lvItem, SizeOf(TLVItem), 0);
        // Set params
        lvItem.mask:=LVIF_TEXT;
        lvItem.iItem:=i;
        lvItem.iSubItem:=0;
        lvItem.pszText:=pmRemote[idxString].Memory;
        lvItem.cchTextMax:=1024;
        // Set the remote memory pointer
        pmRemote[idxItem].Write(lvItem, SizeOf(TLVItem));
        // Get the item
        if ListView_GetItem(handle, TLVItem(pmRemote[idxItem].Memory^)) then
        begin
           // Get string from local memory part of handler
           szString:=PChar(pmRemote[idxString].LocalMemory);
           // Read local memory (which handles the transfer)
           Memo1.Lines.Add(szString);
        end;
     end;
  finally
     // Free object
     pmRemote.Free;
  end;

end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CodedKSenior Software EngineerAuthor Commented:
Thank you Russell, it works.
0
Russell LibbySoftware Engineer, Advisory Commented:
Welcome..

You *are* going to close the question? right? <g>

Russell
0
CodedKSenior Software EngineerAuthor Commented:
I'm sorry ...
I thought i did ...
 
0
Russell LibbySoftware Engineer, Advisory Commented:
lol, no worries...
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.