Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Getting Text From All TTreeView Nodes

Posted on 2002-03-03
10
Medium Priority
?
589 Views
Last Modified: 2010-04-05
Can someone show me how to get the text of all TTreeNodes (parents and children) from a TTreeView of another application and then place the text of each node into the Lines (1 node's text per line) of a TMemo?

Note: I already can locate the TTreeView's Handle (HWND), using FindWindow, etc, so do not worry about that part.
0
Comment
Question by:camou
10 Comments
 
LVL 15

Expert Comment

by:simonet
ID: 6838217


Since you already know the TreeView's handle, here's a simple code that does what you want:

uses CommCtrl;

procedure TForm1.Button1Click(Sender: TObject);
var
  Ct, i : integer;
  item : TTVItem;
begin
  Ct := TreeView_GetCount(aHandle);
  for i := 0 to Ct-1 do
  begin
     with Item do
     begin
       hItem := i;
       mask := TVIF_PARAM;
     end;
     TreeView_GetItem(aHandle, item);
     Memo1.Lines.Add(item.pszText);
  end;
end;


Yours,

Alex
0
 

Author Comment

by:camou
ID: 6838301
I cannot get the code to compile. The compiler gives the error:

"Incompatable types 'Integer and HTREEITEM'"


procedure TForm1.Button1Click(Sender: TObject);
var
 Ct, i : integer;
 item : TTVItem;
begin
 Ct := TreeView_GetCount(aHandle);
 for i := 0 to Ct-1 do
 begin
    with Item do
    begin
      hItem := i;   // << Error Here
      mask := TVIF_PARAM;
    end;
    TreeView_GetItem(aHandle, item);
    Memo1.Lines.Add(item.pszText);
 end;
end;


0
 

Author Comment

by:camou
ID: 6838354
I figured out why the compiler was complaining, had to cast the i variable as a HTREEITEM. However, the code does not seem to work as it was, so i changed

hItem := HTREEITEM(i); // stops the compiler from complaining
mask := TVIF_PARAM; // doesn't add anything to the TMemo

to

hItem := HTREEITEM(i);
mask := TVIF_TEXT;

which, adds a line for each node to the TMemo, but none of the lines have the node's text.

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 2

Expert Comment

by:cqhall
ID: 6838368
What about this...

procedure TForm1.Memo1DblClick(Sender: TObject);
var
 i: integer;
begin
 memo1.Lines.clear;
 for i:=0 to treeview1.items.count-1 do
 begin
  memo1.lines.add(treeview1.items[i].text);
 end;
end;

You could add indents by looking at the items[i].level property and add "x" spaces per Level (0,1,2 ...)

Chuck Hall
0
 

Author Comment

by:camou
ID: 6838386
cqhall,

I think you missed part of my question -- the TTreeView is part of a separate application.
0
 
LVL 1

Expert Comment

by:shibin78
ID: 6838540
I think you must use some methods to inject to the host application process. For you just have the handle of the treeview, when you use any API to do with the handle, you need to be in the same process. For details about how to inject to other process, please refer to <<Advanced Windows>> Forth Edition.
0
 
LVL 20

Accepted Solution

by:
Madshi earned 1200 total points
ID: 6838550
shibin78 is right. These TTreeView APIs end up in messages being sent. Those messages contain pointers and pointers are private to each process. So if you call a TTreeView API which transports a pointer to the TTreeView control, this simply won't work. You won't get the text back. Instead the TTreeView control will write it's strings to wild memory, which may end up in strange behaviour/crashes or in access violations.

You have 2 choices: The usual way is to write a little dll, which you inject into the destination process. This dll can then easily call the APIs and transport the data back to your process (e.g. by using WM_COPYDATA).
A more intelligent way would be to allocate memory in the context of the other process and read it by using ReadProcessMemory. But allocating memory in another process is only possible (by documented means) in NT based systems.

In case you want to have it easy (well, I mean "less difficult", this kind of stuff is never "easy"), you might want to try my package madCodeHook. It contains a function which lets you easily inject a dll into any running 32bit process:

http://help.madshi.net/Data/DllInjecting.htm#InjectLibrary

Or alternatively you could look at my package madRemote, which offers a function, which can allocate memory in other processes in NT *and* win9x based systems:

http://help.madshi.net/Data/AllocFreeMemEx.htm#AllocMemEx

Both packages are free for non-commercial usage, don't come with sources in this version, though...

Regards, Madshi.
0
 
LVL 1

Expert Comment

by:OryxConLara
ID: 6839378
How bout using a global memory object? GloalLock, GlobalUnlock, etc.? it's ugly, but works.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6840926
No, it does not work. Global* was only able to allocate shared memory in 16bit Windows. In 32bit Windows Global* memory is always private to each process...

Regards, Madshi.
0
 

Expert Comment

by:Javen
ID: 8157765
Hi all,

I have followed this thread and have come across the same problem as mentioned.

I have started a new thread of my own asking for an exmaple of how to do this, with 500 points available. I am desperate to get this working, and will increase the point if necessary.

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20553406.html

Cheers,

Javen
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

783 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question