Finding screen co-ordinates of DrawText output.

Posted on 2004-11-21
Last Modified: 2009-05-02
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?
Question by:Halan2
    LVL 55

    Expert Comment

    by:Jaime Olivares
    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.

    Author Comment

    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

    Author Comment

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

    Expert Comment

    Is the DC perhaps released when you try the call WindowFromDC? Can you try it earlier on in your interception routine?
    LVL 20

    Accepted Solution

    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?
    LVL 9

    Expert Comment

    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.

    Author Comment

    Madshi, it was the double-buffering and it was a bit difficult to sort out, but is all working now.

    Thanks for your advice.

    Expert Comment

    Hello. Could you share with us the way you did sort this thing out?

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    What Should I Do With This Threat Intelligence?

    Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

    Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
    This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
    The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

    761 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

    9 Experts available now in Live!

    Get 1:1 Help Now