using API functions, can i get the text rectangule?

Recommended Answers

All 11 Replies

Not that I know of, but you can get the text itself. The size of the rectangle would depend on the font being used.

Not sure exactly what you want, but I guess you can get the text displayed within the window and the size of the window easily enough. This should give you enough information to call DrawText. If you include DT_CALCRECT in the uFormat parameter this won't actually draw the text but instead will calculate the size of the drawn text. I think that is what you need.

imagine the text is more big than control. i want resize the control until see the text. i use the:
- GetWindowText() for get the text;
- SendMessage() for get the font and then select the object;
- GetTextExtentPoint32() for get the font lengh in pixels;
- GetWindowRect() for get the window position(and size);
- GetWindowLongPtr() for get the Styles and Extended Styles;
- AdjustWindowRectEx() for get the control size with borders;
- SetWindowPos() for change the window size.
these code works fine, but imagine that the text have '\t' or '\n', by some reason these code didn't work for the right size. but if is just a single text line and without '\t', works fine.
what you can advice me, please?

It sounds exactly what DrawText with DT_CALCRECT is made for. From MSDN:

Determines the width and height of the rectangle. If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by the lpRect parameter and extends the base of the rectangle to bound the last line of text. If the largest word is wider than the rectangle, the width is expanded. If the text is less than the width of the rectangle, the width is reduced. If there is only one line of text, DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, DrawText returns the height of the formatted text but does not draw the text.
It does mean that you should get the width roughly right first. To do that you might use GetTextExtentPoint32 first to find the width of drawn all on 1 line. If that is too much to fit on 1 line, set the control width to the maximum you can accept and then use DrawText to calculate the required control height.

If you need to be more creative with the way you adjust the control size, such as maintaining aspect ratio, then I guess you need an iterative approach to home in on the optimum size. An initial calculation based on text area using the height & width from GetTextExtentPoint32 might get you close.

sorry SalmiSoft, but i'm very confuse:(
because i only know that the DrawText() is for show us a text on control\hdc.
so please give me more information

i did a new search i did these code:

void setAutoSize(bool autosize)
    {
        if (autosize==true)
        {
            char a[256];
            GetWindowText(this->hwnd,a,256);
            RECT c = { 0, 0, 0, 0 };            
            DrawText(GetDC(hwnd), a, strlen(a), &c, DT_CALCRECT);
            LONG s=GetWindowLongPtr(hwnd,GWL_EXSTYLE);
            LONG g=GetWindowLongPtr(hwnd,GWL_STYLE);
            AdjustWindowRectEx (&c,g,FALSE,s );
            SetWindowPos(hwnd, 0, 0, 0, c.right+2, c.bottom+2,
            SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|
            SWP_DRAWFRAME | SWP_FRAMECHANGED);
        }
    }

but i see 2 problems:
1 - the "\t" is ignored;
2 - i must add '+2'... why? for show the last character correctly.

what you can tell me about these?

The "\t" is ignored because you haven't specified that tabs should be expanded. You will need DT_EXPANDTABS as well as DT_CALCRECT.
I think the +2 is needed because AdjustWindowRectEx sets the window size including the border (and caption bar and menu bar). Does your window have a border width of 1 (so 2 for 2 sides)?

thanks for all.
but can i avoid the '+2'???(i think, depending on fontsize or even anotherthing, the '+2' can be less than we need)

You will have to add something, but of course it is good to avoid hard-coding "+2" and as you say the amount to add could vary. I think this will do the trick:

    void setAutoSize(bool autosize)
        {
            if (autosize==true)
            {
                char a[256];
                GetWindowText(this->hwnd,a,256);
                RECT c = { 0, 0, 0, 0 };            
                DrawText(GetDC(hwnd), a, strlen(a), &c, DT_CALCRECT);
                LONG s=GetWindowLongPtr(hwnd,GWL_EXSTYLE);
                LONG g=GetWindowLongPtr(hwnd,GWL_STYLE);
                AdjustWindowRectEx (&c,g,FALSE,s );
                SetWindowPos(hwnd, 0, 0, 0, c.right+2*GetSystemMetrics(SM_CXSIZEFRAME), c.bottom+2*GetSystemMetrics(SM_CYSIZEFRAME),
                SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|
                SWP_DRAWFRAME | SWP_FRAMECHANGED);
            }
        }

anotherthing: if we use DT_EXPANDTABS with DT_CALCRECT, the rectangle size include the tab size too:

DrawText(GetDC(hwnd), a, strlen(a), &c, DT_CALCRECT | DT_EXPANDTABS);

sorry.. it's give me much more big than i need :(

heres the code corrected for give us the text rectangule and more 2(for we never lose 1 or 2 pixles of the letter):

//Getting the DC Font amd select it
            HDC hdc = GetDC(hwnd);
            HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
            HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);


            //Getting the
            RECT c = { 0, 0, 0, 0 };

            //Getting the text rectangle from actual caption
            char a[256];
            GetWindowText(this->hwnd,a,256);
            DrawText(hdc, a, strlen(a), &c, DT_CALCRECT | DT_EXPANDTABS);

            //add 2 to the size
            TEXTMETRIC v;
            GetTextMetrics (hdc,&v);
            c.right=c.right+(v.tmAveCharWidth / 2);
            c.bottom=c.bottom+(v.tmAveCharWidth / 2);

            //Clean the Font DC
            ReleaseDC(hwnd,hdc);
            DeleteFont(hOldFont);
            DeleteFont(hFont);

            //Getting the actual styles
            LONG s=GetWindowLongPtr(hwnd,GWL_EXSTYLE);
            LONG g=GetWindowLongPtr(hwnd,GWL_STYLE);

            //change the rectangle size for borders
            AdjustWindowRectEx (&c,g,FALSE,s );

            //Update the control            
            intWidth=c.right-intLeft;
            intHeight=c.bottom-intTop;            
            SetWindowPos(hwnd, 0, 0, 0, c.right, c.bottom,
                SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE |SWP_NOCOPYBITS);

these code is excelent for do autosize of the control... very cool

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.