• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 662
  • Last Modified:

Finding screen co-ordinates of DrawText output.

I have written a DLL that intercepts calls to DrawTextA to read text sent by
another program to the screen, and to get the text coordinates. My problem
is that the coordinates passed to DrawTextA() are relative to the specific
device context, and I need the screen coordinates.

DrawTextA must use the HDC parameter to determine the screen coordinates at
which the text is to be printed – it has no other way of knowing. So how can
I find out? I have tried calling WindowFromDC, but it returns NULL. Calls to
GetCurrentPositionEx, GetViewportOrg and GetWindowOrg give inconsistent and
apparently meaningless results, and passing their output to LPtoDP or DPtoLP
doesn’t help. What should I do?
1 Solution
Jaime OlivaresCommented:
Maybe you can intercept the window's sizing event (WM_SIZE) before, to know corners coordinates. This information will help you in client to screen coordinates calculus.
Halan2Author Commented:
This does not solve the problem, as there is more than 1 window to which the
text may be directed. I want to find the target window for each text string intercepted.
I need to know the text screen coordinates so that I can use
Halan2Author Commented:
More details:
The application I'm intecepting opens 2 or more windows.
To give some code example:

BOOL ReadDrawTextStrings()
    for(Index = 0; Index < BUFF_COUNT ;Index++) {
        if(_tcslen(Buffer[Index].Buffer) == 0) {
            return TRUE;
    Text.Format("[%d, %d] %s\n", Buffer[Index].Location.x, Buffer[Index].Location.y, Buffer[Index].Buffer);

From this I get:
[510,80] Hello world
[510,80] Hello there

The problem is that the first line is from one of the windows and the next (might be) from the other but I cannot tell which is which.
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Is the DC perhaps released when you try the call WindowFromDC? Can you try it earlier on in your interception routine?
WindowFromDC will work only if the DC belongs to a window (doh!). When an application uses double buffering (drawing the text into a bitmap and blitting the bitmap to the window DC) then WindowFromDC can't work, because the DC is a bitmap DC and no window DC.

I guess that's the problem you're facing here. Probably you're catching draw events on a bitmap DC. In the moment of drawing there's no way to know onto which screen position the bitmap will later be blitted. Maybe it won't be blitted at all but is just used internally for some strange reason?
You also need to hook all DC creation/destroy APIs, such as BeginPaint,GetDC,GetDCEx, GetWindowDC ,CreateCompatibleDC,CreateDC,ReleaseDC,DeleteDC,EndPaint etc.,
You only need to save the array such as:
struct DCinfo
      HDC hdc;
      HWND hwnd;
}mydcinfo[1024];  you'd better make it dynamical expandable, here just a demo
each time you hook the DC-creation APIs, you can simply search the list and if the hdc hasn't been inserted just add the new hdc and hwnd into your list, when the DC-destroy APIs are called, just delete it from you list....
OK, then when you catch the DrawTextA APIs, you just search your HDC from the list and find the corresponding HWND handle....

Hope this can help you.
Halan2Author Commented:
Madshi, it was the double-buffering and it was a bit difficult to sort out, but is all working now.

Thanks for your advice.
Hello. Could you share with us the way you did sort this thing out?

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now