Solved

Getting text from another window

Posted on 2002-03-06
13
1,354 Views
Last Modified: 2013-12-03
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.

Thanks,
Josh
0
Comment
Question by:jbirk
13 Comments
 
LVL 7

Expert Comment

by:peterchen092700
ID: 6845659
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:
http://www.experts-exchange.com/questions/Q.10336912.html

trying to doig out more links...
0
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 6846340
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.

GOOD LUCK
0
 
LVL 8

Author Comment

by:jbirk
ID: 6846955
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.
-Josh
0
 
LVL 8

Author Comment

by:jbirk
ID: 6851428
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?

-Josh
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6852481
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++:

http://help.madshi.net/Data/madCodeHook.htm
http://help.madshi.net/Data/madRemote.htm

Regards, Madshi.
0
 
LVL 8

Author Comment

by:jbirk
ID: 6867785
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?

Thanks,
Josh
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 20

Accepted Solution

by:
Madshi earned 200 total points
ID: 6868000
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.
0
 
LVL 8

Author Comment

by:jbirk
ID: 6878172
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.

Thanks,
Josh
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6879140
>> 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.
0
 
LVL 8

Author Comment

by:jbirk
ID: 6879561
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.

-Josh
0
 
LVL 8

Author Comment

by:jbirk
ID: 7090641
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 fcHWND;
BOOL CALLBACK GetFreeCellHwnd(
  HWND hwnd,      // handle to parent window
  LPARAM lParam   // application-defined value
)
{
 char buffer[256],*ret;
 GetWindowText(hwnd,buffer,255);
 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");
 return;
}
while (fcHWND == NULL)
{
 EnumWindows(GetFreeCellHwnd,0);
}

if (!InjectLibrary(fcHWND,"dll inject.dll"))
{
 LPVOID lpMsgBuf;
 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
 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';
    break;
   // everything else is simply killed
   default:
    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,
Josh
0
 
LVL 8

Author Comment

by:jbirk
ID: 7090645
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.
0
 
LVL 8

Author Comment

by:jbirk
ID: 7111141
Still there Madshi?  I have more points if you want them.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

746 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now