Question

Locate a child window, and retrieve its contents

Asked by: _Stilgar_

Hi,

I want my application to execute another process (EXE file) and then enumuerate its child windows and find one of them, and retrieve its data. Specifically, thats a TStringGrid (apparently thats a Delphi application), and I need to get the text of the first element in that grid/list.

Since I'm executing the app myself I will have the handle to the process. How do I get the handle to the main window, and then find that child window? what parameters do I have at my disposal when searching for it? and how can I get the data of that element - is there an API function that does that?

I need this solution in C++, Windows API, and can utilize MFC/ATL/WTL if needed. I'm using VC++ 2005.

Stilgar.

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
2007-11-02 at 04:25:51ID22934462
Tags

window

,

child

,

api

Topics

C++ Programming Language

,

Windows Programming

,

Windows MFC Programming

Participating Experts
3
Points
150
Comments
8

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. Date's in ATL & VARIANT
    I am writing a control that takes a date as a property from a VB client. It is passed in as a VARAINT, and the value in the VARIANT->Date contains a double representing the date passed. How do I get the date for Today, to compare the difference between the two dates? Th...
  2. mfc/atl or none -?
    I want to write a gui application. I want it to be small. Should I use MFC (in a shared dll), MFC (in a static lib), ATL or pure win32 API ? What I'd like to know is how bigger the mfc app will be than the non-mfc one? Let's say my non-mfc app is 200kb. what size it will be i...
  3. Adding ATL object in MFC project
    Hi, I am trying to add an ATL object into my MFC project using MS VC++ 6.0. I went to ClassView->New ATL Object, it gives me the following errors: ATL Object Wizard: AddIncludeFile(ProjectNameHeader, MIDLHeader) You must have ATL setup correctly to insert an ATL object...
  4. ATL objects memory problem
    I have defined 2 ATL interface objects IBase IChild The IChild class has 2 private members m_sString m_dId the base class has m_sBaseString m_sBaseId CMapStringToPtr m_oChilds (all strings and id's have properties to put and get). In the IBase class I have expos...
  5. EXE ATL COM with MFC
    Hi I am trying to create an EXE ATL COM object with support MFC but the VC++ disable that option (its available only with DLL). How can I do it? if Not - why? David

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: NickGeorghiouPosted on 2007-11-02 at 06:02:26ID: 20200405

Hi,

Ok, there are few steps you need to do:


1. If you are using the ::CreateProcess api to run the process then you can get the process id from the PROCESS_INFORMATION structure (dwProcessId member).
- refer to   http://msdn2.microsoft.com/en-us/library/ms682425.aspx   for ::CreateProcess
- refer to   http://msdn2.microsoft.com/en-us/library/ms684873.aspx   for PROCESS_INFORMATION structure


2. The next step is to enumerate all top-level windows using the ::EnumWindows and an EnumWindowsProc. You must write your own EnumWindowsProc and then pass a pointer to EnumWindows. Your EnumWindowsProc will be called multiple times; each time the handle to a top-level window will be passed in the callback. At this point you can use the GetWindowThreadProcessId api to check whether the process id of a particular top-level window matches the process id of the process you kicked off. If it does then store the handle because this is the processes main window. (Although note that some applications may have multiple top-level windows in which case you will get more than one match).
- refer to   http://msdn2.microsoft.com/en-us/library/ms633497.aspx   for EnumWindows
- refer to   http://msdn2.microsoft.com/en-us/library/ms633498.aspx   for EnumWindowsProc
- refer to   http://msdn2.microsoft.com/en-us/library/ms633522.aspx   for GetWindowThreadProcessId


3. Once you have your top level window(s) you can use the FindWindowEx to attempt to findow a window of the TStringGrid class.
- refer to   http://msdn2.microsoft.com/en-us/library/ms633500.aspx   for FindWindowEx


NOTE: If you know the name of the main window of the process you can skip points 1 and 2 and use FindWindowEx to first retrieve a handle to the main window by setting the first parameter to null and passing the name as the 4th parameter.


Hope this helps,
Nick

 

by: _Stilgar_Posted on 2007-11-02 at 07:09:23ID: 20200972

If I know the main window to be of class TBoardWindow (thats what Spy++ says), can I do this then:

// I have the app process ID as dwMyProcess;
HWND hWnd = NULL;
DWORD dwProcess = NULL;
do {
   hWnd = FindWindowEx(NULL,  hWnd, _T("TBoardWindow"), NULL);
   if (!hWnd) break;
   dwProcess = GetWindowThreadProcessId(hWnd,NULL);
   if (dwProcess == dwMyProcess) break;
   else dwProcess=NULL;
} while(true);

To find my window instead of using EnumWindows?

And then I will use the same way to locate the TStringGrid instance. The thing I have no idea how to achieve is how to get the data from the first entry of the TStringGrid control. What API function I have for that? Also, if it is within a tab control and not visible at the moment, would it make any difference when I come to read its data?

Stilgar.

 

by: mahesh1402Posted on 2007-11-02 at 22:58:07ID: 20206077

>>how can I get the data of that element - is there an API function that does that?

You will be verywell able to enumerate all the top windows, and locate the window you are looking for and can list all the child windows ie controls etc. But For example using functions like GetWindowText to spy data of edit control which is in another process will not work.  You will have to use the WM_GETTEXT message instead for this.

-MAHESH

 

by: itsmeandnobodyelsePosted on 2007-11-05 at 10:56:09ID: 20218386

>>>> using functions like GetWindowText to spy data of
>>>> edit control which is in another process will not work.  
>>>> You will have to use the WM_GETTEXT message instead for this.

No. Sending a WM_GETTEXT message to a window is the same than calling GetWindowText. In both cases you'll get a char pointer which cannot be interpreted as it comes from a different process environment.  

>>>> The thing I have no idea how to achieve is how to
>>>> get the data from the first entry of the TStringGrid control.
That isn't the main issue. You first need step into the process you want to 'spy' from. There are two techniques: first, you can act like a debugger and read the other process' virtual memory; second, you can 'hook' into the other process by 'installing' a dll function you have to provide in a dll. For the second, the application will call the hook function in the context of its processes, so - if called - you could read char pointers valid for the hooked process.

'debugging' or 'hooking' is both a new game where you need admin priviliges and have to know a lot from the application in question. I hardly can think that it is easy to get a valid pointer of a grid control and have access to some cell contents if not knowing the internals of that control. Note, if the TStringGrid is a active-x all data is accessed via a COM interface and can only be retrieved if you exactly rebuild the needed COM environment. I would think, grabbing a bitmap from the screen and calling some OCR library is more likely to have success than that you want to achieve.

Regards, Alex

 

by: mahesh1402Posted on 2007-11-06 at 07:01:44ID: 20224345

>>No. Sending a WM_GETTEXT message to a window is the same than calling GetWindowText

Definately not ! there is differnece .....and my comments here are related to edit, combo and button controls in another process and WM_GETTEXT verywell works with that.

See live Example and  COMPARISON between WM_GETTEXT and GetWindowText:
Article :Getting the Text of a Window in Another Application
http://msdn.microsoft.com/msdnmag/issues/01/08/c/ <=======

**See comparison code  :
http://msdn.microsoft.com/msdnmag/issues/01/08/c/figures.asp <======

-MAHESH

 

by: mahesh1402Posted on 2007-11-06 at 07:06:06ID: 20224398

As said in article :

GetWindowText doesn't just send WM_GETTEXT. GetWindowText only sends WM_GETTEXT if the window belongs to the current process. If the window belongs to a different process, GetWindowText does something else.

The documentation is explicit:
If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string. This behavior is by design.
In other words, you can get the caption from the main window of another process, but not the text of a child window such as an edit control, combobox, or button within it.

-MAHESH

 

by: itsmeandnobodyelsePosted on 2007-11-06 at 08:05:38ID: 20224931

>>>> Definately not ! there is difference
You are right. I would have bet that there is no difference but the docs are stating like you said.

That means 'titles' and 'captions' of a window are stored by using global memory. Then, Windows can make a copy of that text to the buffer you provided with SendMessage(hwnd, WM_GETTEXT, wparam_bufsiz, lparam_buf) respectively with the GetWindowText(hwnd, buf, bufsiz). I could have made that clear to me earlier cause the FindWindow must find the titles and captions as well. So, it must be global memory to make that work.

But, edit text is stored by means of a local pointer which belongs to the other process. Windows can only return the pointer and the pointer is not valid in any other process.

For the above question that doesn't make a difference. The text stored in a grid control definitively isn't a 'window's caption'. Hence you need 'debugging' or 'hooking' to be able to interpret char pointers of the other process.

 

by: _Stilgar_Posted on 2007-12-04 at 12:54:18ID: 20406347

@itsmeandnobodyelse - when you say I will need to know the "internals", what does this mean exactly, that grid control being coded in Delphi?
And say I will go the OCR way, what good OCR library can I use? and how would I capture that window into a bitmap (can it be done even if the window is not visible on the screen, for example minimized or hidden by another window?)?

Stilgar.

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...