Question

Getting text from treeview from outside

Asked by: andla

Does anybody know how to get text from a treeview control that does not belong to my process ?

When i run this code i get an access violation in comctl32.dll

Please help me.

 int wfp=(int)(hWnd=(HWND)WindowFromPoint(pt));

HTREEITEM hti = TreeView_GetRoot(hWnd);
if(hti)
{
item.mask =TVIF_TEXT;
item.cchTextMax=199;
item.pszText=new char[300];
strcpy(item.pszText,"");
item.hItem = hti;
hti=(HTREEITEM)TreeView_GetNextItem(hWnd,&item,TVGN_CARET);

TreeView_GetItem(hWnd,&item);//This macro always fails.


int x=0;//Just to stop the debugger inside brackets
x=1;

}


Regards
Andla

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2001-03-24 at 08:23:54ID20096218
Tags

treeview_getitem

Topic

Windows Programming

Participating Experts
3
Points
100
Comments
15

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Retrieving CTreeCtrl Item HTREEITEMs  (not RootItem)
    I am using a TreeCtrl from within a CTreeView derived class and have called GetTreeCtrl() method to retrieve a reference. All fine there. I would like to get a handle to one of the TVITEMs using GetItem() and passing a TV_ITEM structure reference. Using this method I can re...
  2. TreeView control- getting the TV_ITEM form HTREEITEM
    Hi, I'm using a tree view control. I need to go through all sons of a specific tree item, and use some private information I have about each node in the tree. I can do it by using the (HTREEITEM) hItem. (I have this handle)_ What I need is not the hItem, but the (TV_ITEM)tvi ...
  3. Trouble with treeview control.
    Please help me with this. The code posted here works fine on my Windows 2000 Advanced Server but when running on a Windows 2000 Professional it fails. Don't know if the problem is the operating system. Note that the application is a dll attached as a plugin to another proces...
  4. a question about strcpy
    int main(int argc, char* argv[]){ char str[1]; strcpy(str, "abcd"); strcpy(str, "abcde"); return 0; } the second strcpy will raise a runtime error while the first won't, why? does it means compiler allocates 5 bytes (inluding a '\0') to str? P...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: NickRepinPosted on 2001-03-24 at 14:16:43ID: 5955710

It doesn't work because you pass to TreeView_GetItem() a memory buffer which is in the address space of another (your) process and therefore inaccessible.

2 ways possible:

1)Install a hook (for example, SetWindowHookEx(WH_GETMESSAGE)) on the treeview thread (GetWindowThreadProcessId(hTreeView,0)).
Inside the hook procedure you can do anything with the treeview, because the procedure is executed in the address space of the treeview process. The hook procedure must reside in a DLL. After calling TreeView_GetItem(), you have to pass the data to your application, you can do it by WM_COPY, for example.

This will work on any version of Windows - 9x/me/nt/2k/xp.

2) For Windows NT/2000/xp:
Allocate memory in the treeview process address space using pMem=VirtualAllocEx(). Use pMem as a buffer for  TreeView_GetItem(). You can write and read pMem using ReadProcessMemory/WriteProcessMemory.

a) Obtain process id of B by GetWindowThreadProcessId(hTV,&pid)

b) Get the process handle of B by OpenProcess(PROCESS_VM_WRITE| PROCESS_VM_OPERATION | PROCESS_VM_READ)

c) Allocate the memory in the address space of B by VirtualAllocEx. Allocated block must be large enough
to hold TVITEM structure and the buffer for the item text. Like this:

struct S {
   TVITEM it;
   char buf[120];
} s;

S* ps=VirtualAllocEx(... sizeof(s)...)

d) Fill allocated memory by WriteProcessMemory:

 s.it.iItem=...;
 ...
 s.pszText=LPSTR(
    LPBYTE(ps)+(LPBYTE(s.buf)-LPBYTE(&s))  );
 s.cchTextMax=sizeof(s.buf);

Now copy s struct to ps by WriteProcessMemory.

e) Call TreeView_GetItem(hTV,ps);

f) Read contents of ps->buf by ReadProcessMemory()

g) Use VirtualFreeEx to free memory and CloseHandle to close process handle.


Also there is a way for Win9x to allocate shared memory and then pass this memory to TreeView_GetItem, but it is undocumented therefore is not totally safe.

 

by: andlaPosted on 2001-03-24 at 16:49:31ID: 5955885

Thankt there are hope :-)

How would this dll look like ?
How would i use the WM_COPY ?

I'm using windows 98.

/Andla

 

by: NickRepinPosted on 2001-03-25 at 02:27:49ID: 5956380

Note I use ListView_GetItem, because it was easier to find a listview on my computer.

//----------
// Main.cpp
//----------

//cl /LD /MD hook.cpp user32.lib kernel32.lib comctl32.lib
//cl main.cpp hook.lib user32.lib

#include <windows.h>
#include <stdlib.h>
#include <iostream.h>

HWND hTV;

bool setHook(HWND hTV,HWND w);

LRESULT CALLBACK wndProc(HWND w,UINT msg,WPARAM wp,LPARAM lp)
{
   switch(msg) {
   case WM_COPYDATA:
   {
      PCOPYDATASTRUCT c=(PCOPYDATASTRUCT)lp;
      LPSTR t=new CHAR[c->cbData];
      memcpy(t,c->lpData,c->cbData);                                    
      ReplyMessage(0);
      MessageBox(0,t,"Item text",MB_OK);
      delete[] t;
      SendMessage(w,WM_CLOSE,0,0);
      break;
   }
   case WM_USER:
      setHook(hTV,w);
      break;
   case WM_CREATE:
      PostMessage(w,WM_USER,0,0);
      return 0;
   case WM_RBUTTONDOWN:
   case WM_CLOSE:
      PostQuitMessage(0);
      DestroyWindow(w);
      return 0;
   }
   return DefWindowProc(w,msg,wp,lp);
}

//int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
void main(int argc,char* argv[])
{
   if(argc<2)
   {
      cout<<"Usage: main.exe <listview handle (eg: 0x123400)>"<<endl;
      return;
   }
   hTV=HWND(strtoul(argv[1],0,0));
   if(!hTV)
   {
      cout<<"Not a window"<<endl;
      return;
   }

   WNDCLASS cls;
   memset(&cls,0,sizeof(cls));
   cls.lpfnWndProc=wndProc;
   cls.hInstance=GetModuleHandle(0);
   cls.hIcon=0;
   cls.lpszClassName="test";
   cls.hbrBackground=HBRUSH(COLOR_WINDOW+1);
   RegisterClass(&cls);
   HWND w=CreateWindowEx(0,"test","test",
      WS_POPUP|WS_VISIBLE|WS_SYSMENU|WS_CAPTION,
      5,5,200,200,0,0,cls.hInstance,0);
   MSG msg;
   while(GetMessage(&msg,0,0,0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
}

//----------
// Hook.dll
//----------
#include <windows.h>
#include <commctrl.h>

#pragma data_seg(".shared")
HHOOK hHook=0;
HWND hTV=0;
HWND hW=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.shared,RWS")

HINSTANCE hDll;

LRESULT CALLBACK hookProc(int code,WPARAM wParam,LPARAM lParam)
{
   char buf[120];
   LVITEM t;
   t.mask=LVIF_TEXT;
   t.pszText=buf;
   t.cchTextMax=sizeof(buf);
   t.iItem=0;
   t.iSubItem=0;
   ListView_GetItem(hTV,&t);
   COPYDATASTRUCT c={0,strlen(buf)+1,buf};
   SendMessage(hW,WM_COPYDATA,WPARAM(hTV),LPARAM(&c));
   LRESULT r=CallNextHookEx(hHook,code,wParam,lParam);
   UnhookWindowsHookEx(hHook);
   return r;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID)
{
   if(fdwReason==DLL_PROCESS_ATTACH)
      hDll=hinstDLL;
   return TRUE;
}

_declspec(dllexport) bool setHook(HWND htv,HWND w)
{
   hTV=htv;
   hW=w;
   DWORD tid=GetWindowThreadProcessId(hTV,0);
   hHook=SetWindowsHookEx(WH_GETMESSAGE,hookProc,hDll,tid);
   PostThreadMessage(tid,WM_GETTEXTLENGTH,0,0);
   return hHook!=0;
}

_declspec(dllexport) void removeHook()
{
   if(hHook) UnhookWindowsHookEx(hHook);
}

 

by: andlaPosted on 2001-03-25 at 06:37:12ID: 5956590

I see that you use a library instead of a dll.

I did try to make a dll project but i don't have much experience with this.

If i'm not entirely wrong I have read that LoadLibrary mostly returns 0x10000000 witch should be normal. But i don't understand way GetLastError return 120.

When i use the GetProcAddress it return NULL and GetLastError returns 126 because it could not find the module.

I then tried to use GetModuleHandle but this functions always returns 0 and GetLastError return 126. I tried both the filename and the whole path with the filename.

I think i have to try to make a library file instead and se if i have more luck with that :-)


Regards
Andreas.

 

by: andlaPosted on 2001-03-25 at 09:29:15ID: 5956899

How do i avoid this ?


Compiling...
program.cpp
Linking...
LINK : warning LNK4075: ignoring /INCREMENTAL due to /FORCE specification
AndySLib.lib(prg.obj) : warning LNK4006: "struct HWND__ *  hTV" (?hTV@@3PAUHWND__@@A) already defined in program.obj; second definition ignored
AndySLib.lib(prg.obj) : warning LNK4006: "struct HWND__ *  hTV" (?hTV@@3PAUHWND__@@A) already defined in program.obj; second definition ignored

 

by: andlaPosted on 2001-03-25 at 10:03:57ID: 5956962

Oops sorry i fixed it with the extern keyword.

 

by: andlaPosted on 2001-03-25 at 10:36:43ID: 5957013

I did fix so your program worked.

I can now get the text from lisview items. I did some changes and added a timer procedure so that i just could point on the window.

void CALLBACK Timer(HWND hw,UINT msg,UINT ident,DWORD time)
{
     if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
     {
     MessageBeep(0xffffffff);

     POINT pt;
     GetCursorPos( &pt );
     hTV=(HWND)WindowFromPoint(pt);
     setHook(hTV,hWnd);

     }
     
}



Thanks for your help i think i can continue now. :-)

I would be happy if you could stay in this posting if you got some time over to aid me on my way. If you want i can post my solution with treeview laiter.

Regards
Andreas.

 

by: andlaPosted on 2001-03-25 at 10:38:58ID: 5957016



I can now get the text from lisview items. I did some changes and added a timer procedure so that I just could point on the window.

void CALLBACK Timer(HWND hw,UINT msg,UINT ident,DWORD time)
{
     if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
     {
     MessageBeep(0xffffffff);

     POINT pt;
     GetCursorPos( &pt );
     hTV=(HWND)WindowFromPoint(pt);
     setHook(hTV,hWnd);

     }
     
}



Thanks for your help i think i can continue now. :-)

I would be happy if you could stay in this posting if you got some time over to aid me on my way. If you want i can post my solution with treeview laiter.

Regards
Andreas.I did fix so your program worked.

 

by: NickRepinPosted on 2001-03-25 at 12:35:32ID: 5957240

>>I see that you use a library instead of a dll.
It must be a DLL and not LIB. The main program must be linked with the import library (LIB) of the DLL.

So you compile and link the DLL code, and get DLL and LIB files. Then you compile the main code and link it with LIB. No need to load library explicitly, it will be done automatically.

 

by: andlaPosted on 2001-03-25 at 16:06:52ID: 5957563

Thanks :-)

Here is what i did and it worked.

I created a lib project and added the code.
I create a win32 project and added the .lib file in
the project. I added your code and did some small changes and added the timer procedure.

If you don't believe me i can send you the project :-D

From above i had some problem with dll's and thats because Microsoft for some reason forgot to add    extern "C" {}. So now i succeded with a dll (hurray). But i have trouble understand what dllimport is used for.

Regards
Andreas

 

by: geissomatikPosted on 2002-10-18 at 13:00:57ID: 7345929

The solution provided above by Nick is fantastic.  I only ran into one problem: you can't call PostThreadMessage() with the WM_GETTEXTLENGTH message; the MSDN page for WM_GETTEXTLENGTH says the message should only be sent, not posted.  On Win2k this caused the call to PostThreadMessage() to fail, so the hook procedure was never called and the messagebox never came up.

I'm not sure what the best alternative is, but calling it with WM_USER seems to work just fine.  From there, you can easily build on Nick's example code to accomplish whatever you need.

 

by: andlaPosted on 2002-10-21 at 06:46:09ID: 7352074

geissomatic >>I'm glad to se something happening on old qestions even if it is one year old. What are you trying to accomplish ? I'm Curious.

Yours sincerely
Andla

 

by: NickRepinPosted on 2002-10-21 at 11:42:52ID: 7353309

WM_USER is not good, because it might cause some undesired action in the destination window procedure.

WM_NULL must be better.

 

by: geissomatikPosted on 2002-10-21 at 12:06:42ID: 7353396

Nick - Thanks!  I'll try using WM_NULL instead.

Andla - I'm working on running intensively animated graphics (i.e. hardware-accelerate stuff) as your wallpaper (behind the icons) without using overlays.  But, there's really no way to do this without recreating an articial desktop... so I need to query the desktop's listview child window for all of its icon positions, text labels, and PIDL's (which, it turns out, seem to be pointed to by the 32-bit userdata parameter for each item text).  It should be posted, with most of the source code, at http://www.nullsoft.com/free/vms/ within a week or so.  For a beta demo, go to http://www.geisswerks.com/ryan/whatsnew-graphics.html and download the 3 files in the 10/20/02 entry. (Requires Winamp 2.x)

This is great stuff!  Thanks for everyone's help!

 

by: AlacazamPosted on 2003-05-04 at 03:48:20ID: 8454276

I've read that from NickRepin :
" It doesn't work because you pass to TreeView_GetItem() a memory buffer which is in the address space of another (your) process and therefore inaccessible ".

I'm not sure to understand ...
To get a text from a window, I do that (which is working) :

char t[500];
SendMessage(H0, WM_GETTEXT, (WPARAM) 500, (LPARAM) &t);

Why that works, and not the same thing for TListView, please ?

char t[1000];
LV_ITEM p;
p.mask = LVIF_TEXT;
p.pszText = t;

for (int i = 0 ; i < ListView_GetItemCount(H0) ; i++) {
     p.iItem = i;
     p.iSubItem = 0;
     p.cchTextMax = 1000;
     SendMessage(H0, LVM_GETITEM, 0, (LPARAM) (LV_ITEM FAR *) &p);
     ListBox1->Items->Add(t);
     }

Thanks
Mathieu

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...