Getting text from another window

How can I grab the text from another window?  Say if I wanted the text that's in the rectangle 100,100,400,120 on window otherHWND.  For example sake, let's say the text is written with the GDI command TextOut.

Who is Participating?
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.

There's no easy generic solves-everything way.

a) OCR - trying to figure out text from bitmap (babylon uses this) If you find y good OCR package you can pay, then go for it.
b) Hyped up GetWindowFromPoint+GetWindowText. You can add support for gettign item text fro common classes like edit, tree, list, etc. Can fail quickly
c) Accessibility interfaces. Does b) in a consistent very thorough level for all standard windows controls, and is extensible by individual control developers.

For a lengthy discussion:

trying to doig out more links...
Roshan DavisCommented:
Use SetWindowLong function for setting additional data to a window. When u get the window handle, use GetWindowLong for retrieving the value.
One thing to take care is that DrawText data and Window long data must be the same.

jbirkAuthor Commented:
Well I don't have control over the window which I'm retrieving the data from, and it does not use standard window controls unfortunately.  It's a 'psuedo gui'.  I'll look into that lengthy discussion later today.

Thanks for the responses.
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

jbirkAuthor Commented:
I tried to read that question you referred to but the messages are ALL out of order.  I can't follow the thread at all since it jumps from 7/31 to 6/05 to 7/27, etc.  What's going on with that?  Does it look like that for you, or is it because I bought it from the paq?

My 2 cents:

You have 4 choices:

(1) OCR.
(2) Accessibility stuff.
(3) System wide GDI hook (SetDDIHook in win9x and a little video hook driver in winNT based systems). Perhaps this is the same as (2), I'm not sure. I don't know much about (2).
(4) Hooking (Ext)TextOutA/W by a good API hooking method, then use InvalidateRect to invalidate the area under the mouse.

All those 4 choices are quite difficult to implement. A friend of mine is using my API hooking package to go after (4), and he sais that it's working fine. But that's just one possibility - and also a very difficult one... Here is the documentation for my API hooking package, it's for Delphi, but my package is also available for C++:

Regards, Madshi.
jbirkAuthor Commented:
Madshi your method 4 is what I was thinking of when I first posted this question, but I have no idea how to implement that.  I'm using C++.  Could you give me a little more detail on how to go about using your package to get text from the screen?

Just as a first note: This stuff is *really* difficult!

Well, the theory is quite easy:
(1) Get the mouse position (GetCursorPos).
(2) Get the window the mouse is currently over (WindowFromPoint).
(3) Get the thread ID to which that window belongs (GetWindowThreadProcessID).
(4) Inject a little dll into that thread/process, e.g. by misusing SetWindowsHookEx (by setting up a dummy message hook which does nothing).
(5) In the dll hook the API TextOut process wide.
(6) Invalidate the area under the mouse (InvalidateRect).
(7) Now the window should redraw itself and call TextOut for this purpose. As a result your hook should get fired. However, it might happen, that the window does not only redraw the word under the mouse, but also the whole paragraph. So you need a good algorythm to find out which word is exactly under the mouse.
(8) Unhook the API hook.
(9) Uninstall the SetWindowsHookEx dummy hook.
(10) Done.

Please note that when using my API hooking package to hook TextOut in win9x, you need to set the "forceMixtureMode" parameter to true, because the TextOut API code is structured in a strange way in win9x. This does not apply to winNT based systems.

Regards, Madshi.

P.S: If you will be using my stuff, watch out for a new version this or next weekend.

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
jbirkAuthor Commented:
OK, that looks like the plan I will go with.  When I get the time, I will download your C++ code and give it a try.  I'll probably be back here asking some more detailed questions regarding this until I get it working.  I can give you more points (I have 3234 right now) if it turns out to be a lot more work, but I want to keep the topic here on this question.

>> I will download your C++ code

I hope you didn't understand me wrong. My library is written in Delphi. The source code is not available (for free). Even if it was, it would be Delphi code, not C++ code. There are some little demos available with C++ code. But the library itself comes only as a dll (plus lib + h). Also my library is only free for non-commercial purpose.

Regards, Madshi.
jbirkAuthor Commented:
Yes I understood that.  Sorry if I worded it wrong.  I plan to use it now for non-commercial use, but if I can get it to work nicely and I can convince my boss we need it, I may use it at work, in which case we'll purchase it.

No worries.

jbirkAuthor Commented:
I know it's been 3 months, but I just had some time at work, and decided to look into this again.  I downloaded your code and got the samples to work.  Then I tried for my own sample just to inject a dll into freecell.txt.  But I keep getting the error "The Handle is Invalid" even though I know it's valid (cause I can send messages like key strokes to the message handle and it works).  Any ideas what would cause that?  Here's my code:
  HWND hwnd,      // handle to parent window
  LPARAM lParam   // application-defined value
 char buffer[256],*ret;
 ret = strstr(buffer,"FreeCell");
 if (ret != NULL && (ret - buffer == 0))
  fcHWND = hwnd;
  return false;
 return true;

then later in a button press code:
int retval = _spawnlp(_P_NOWAIT,"freecell.exe","freecell.exe",NULL);
if (retval <= 0)
 MessageBox("Unable to launch freecell");
while (fcHWND == NULL)

if (!InjectLibrary(fcHWND,"dll inject.dll"))
 LPVOID lpMsgBuf;
 MessageBox( (LPCTSTR)lpMsgBuf, "Error" );
 // Free the buffer.
 LocalFree( lpMsgBuf );

The code in the dll captures the translatemessage function like your example (though I translated from delphi to C++):
BOOL TranslateMessageCallbackProc(MSG *lpMsg)
 BOOL result;
 // first of all call the original function to let the message be translated
 result = TranslateMessageNextHook(lpMsg);
 // now check whether we have a WM_CHAR message
 if (lpMsg->message == WM_CHAR)
 // control keys are accepted
 if (lpMsg->wParam > 32)
  switch (lpMsg->wParam)
  // also upper case "madshi" characters
   case 'M':
   case 'A':
   case 'D':
   case 'S':
   case 'H':
   case 'I': break;
   // lower case "madshi" characters are made upper case
   case 'm':
   case 'a':
   case 'd':
   case 's':
   case 'h':
   case 'i':
    lpMsg->wParam = (char)lpMsg->wParam - 'a' + 'A';
   // everything else is simply killed
    lpMsg->message = WM_NULL;
 return result;

I tried using your CreateProcessEx to launch notepad and test this, and it worked ok.  It crashed notepad though anytime you did something like F3, or ctr-f which launches the find window.

My system is Win2K service pack 2 in case you need it.  I can post more points for you here if you want them for your continued help (I have 3674, lol)

Thanks a lot,
jbirkAuthor Commented:
Oh I forgot to mention that I won't be able to use CreateProcessEx in the end, because the application I'm using will have already been launched outside the application.  I only used it to see if the dll was working ok.
jbirkAuthor Commented:
Still there Madshi?  I have more points if you want them.
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
Microsoft Development

From novice to tech pro — start learning today.