Posted on 1998-07-26
Last Modified: 2013-12-03
If you have Charles Petzold's "Programming Windows 95" book,  look at figure 12.4 on page 603. I am trying to write code that will get the highlighted text "PSM_APPLY" into a string. My approach is to use sendmessage using TVM_GETITEM. So far all attempts have failed. I am attempting this with VB and may not have my TV_ITEM structure quite right. Any thoughts??
Question by:jdwarren
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Author Comment

ID: 1411071
Edited text of question

Expert Comment

ID: 1411072
What does your TV_ITEM structure look like?

Author Comment

ID: 1411073
Currently I presume all records of the structure are 32 bit as shown below:
  mask AS LONG
  hItem AS LONG
  state AS LONG
  stateMask AS LONG
  pszText AS LONG
  cchTextMax AS LONG
  iImage AS LONG
  SelectedImage AS LONG
  cChildren AS LONG
  lParam AS LONG

Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now


Expert Comment

ID: 1411074
Are you passing the structure of your TV_ITEM or the address of the structure?  You need to pass the address so it can be populated.  Does SendMessage always return FALSE here?

What are you setting hItem and mask to?

go here to see a full explanation of the structure:

from microsoft.

I need you to tell me if SendMessage is returning TRUE or FALSE and make sure you zero initialize the structure before setting any of the parms. and then lastly I need you to make sure you are putting a valid number for the cchTextMax


Author Comment

ID: 1411075
To test code I first run Ctlmacro.exe. This is a sample program that came with the book I referenced above. It displays the same treeview as shown in the book. My code trys to get the folder and item text lables that are displayed in that window. My code is run seperately as an executable.

My Procedure:
I first determine hwnd1 with GetForegroundWindow(), then GetNextDlgGroupItem(hwnd1,NULL,FALSE) to get hwnd2, I then loop using GetNextDlgGroupItem(hwnd1,hwnd2,0) until I find the handle that has a title of "Tree1" and a ClassName of "SysTreeView32".
SendMessage(hwnd2,TVM_GETCOUNT,0,0), and TVM_GETINDENT, and TVM_GETVISIBLECOUNT, provide me with values that suggest that I have the right handle (hwnd2).
Next I get hItem for the root with SendMessage(hwnd2,TVM_GETNEXTITEM,TVGN_ROOT, 0), This returns a non-zero value. Also I can get other non-zero hItem values using TVGN_CARET, TVGN_FIRSTVISIBLE, etc.

On each attempt I set .hItem in the TV_ITEM structure to one of these values and then try to retrieve the text with a SendMessage to hwnd2, TVM_GETITEM and a pointer to pitem which is my TV_ITEM structure.

So far no luck. The text I am after is the name next to a folder or the name of an item that is shown after it has been expanded. I think that is what this supposed to be returned as text.
Sendmessage with TVM_GETITEM returns 0 when on Windows 95 and returns 1 when on NT 4.0 and with both cases the text is not updated. GetLastError() always returns zero just after a SendMessage with TVM_GETITEM

pitem.mask= TVIF_TEXT = 1
Also I set the .cchTextMax and .pszText the exact same way I set .cch and .dwTypeData in the MENUITEMINFO structure(i.e. pointing to 128 character string). Note that GetMenuItemInfo works fine in other applications.

At the start of my code I set:
  pitem.mask = 0
  pitem.hItem = 0
  pitem.state = 0
  pitem.stateMask = 0
  pitem.pszText = 0
  pitem.cchTextMax = 0
  pitem.iImage = 0
  pitem.SelectedImage = 0
  pitem.cChildren = 0
  pitem.lParam = 0          
Is this OK?

Author Comment

ID: 1411076
Adjusted points to 150

Author Comment

ID: 1411077
Adjusted points to 200

Expert Comment

ID: 1411078
So if I understand you correctly, you are setting .cchTextMax  to 128?

If you run Spy++ and spy over the controls, if the caption of these folders is set to the text you expect to find, then you should be able to retrieve the information.  If it is not, check to see what the other captions of the controls look like in the window.

In windows, controls themselves are little windows, but in the case of a control, its caption is the text you see.

Let me know what you find.  I don't have the book so I cannot look directly at the code.  YOu could email it to me if you want though....


Author Comment

ID: 1411079
Yes I am setting .cchTextMax  to 128. Also tried setting it to 127. Also just sent you the sample program from the book via email.

I just found an error where I had defined TVM_GETITEM = (TV_FIRST + 62). It should have been (TV_FIRST + 12). With that corrected, SendMessage now returns 1 on Windows 95.
Still no text is returned when the mask set to TVIF_TEXT  .
 I have also tried the TVIF_CHILDREN mask and that does not update my TV_ITEM structure regardless of which hItem I try. This has nothing to do with text so I am suspicious that something else causing a problem.

Expert Comment

ID: 1411080
spy didn't help me in this case....
LVL 15

Accepted Solution

Tommy Hui earned 200 total points
ID: 1411081
The common control messages cannot be used across process boundaries. You will need to use an injected DLL and communicate with the DLL as to what the common controls contain.

I think this is an oversight with the common controls, but from a speed perspective, it was probably okay.

Author Comment

ID: 1411082
Before I accept this answer please note that:

SendMessage has so far returned what appears to be valid results with the TVM_GETNEXTITEM, TVM_GETCOUNT, TVM_GETGETINDENT, and TVM_GETVISIBLECOUNT  messages.
You stated that "common control messages cannot be used across process boundaries" but it appears to me that this is not completely true. Please Comment on the above  exceptions.

Expert Comment

ID: 1411083
Thui is a pretty good judge at this.  He used to help me all the time back in '93....

Author Comment

ID: 1411084
Since it has been difficult for me to find descriptive information on the common controls, like the tidbit you gave me about it being unable to cross process boundaries, make this expert-exchange very valuable. Thanks for taking a look at this problem!!

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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

Suggested Solutions

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

756 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