Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Implementing the DT_END_ELLIPSIS flag on the Pocket PC

0.00/5 (No votes)
16 May 2004 1  
Extending the DrawText function to display truncated text with a terminating ellipsis

Introduction

It is known that the DrawText function provided by the Windows CE API does not support the DT_END_ELLIPSIS flag. This makes it harder to emulate what the list view control does when in report mode: text cells that do not fit on the column width are displayed with a terminating ellipsis (...).

An approach to solving this problem is available here, but it is based on MFC, and I wanted an API-only version of the thing.

This article presents a very simple solution to this problem by implementing the DrawTextEx function.

The Solution

The solution presented here is simple, straightforward and tries to preserve the spirit of the desktop version of DrawText: provided strings must allow for changes in-place.

To make sure the developer understands this (the function will cast away the char pointer constness), an additional flag must be provided: DT_MODIFYSTRING. Failing this, the function will make no in-place changes to the string, and no ellipsis will be shown.

After determining that the user really understands these issues, the function can start its work by calculating the string length (if it was not supplied) as well as its screen size.

If the string's screen size is larger (in this case wider) than the supplied rectangle's, it needs to be split and an ellipsis Unicode character added to the end of it. Note that the function tries to estimate where the ellipsis character will be placed in order to avoid entering a lengthy trial-and-error loop. This loop will eventually be entered only if the first size estimate is wider than the rectangle's width.

Finally, when the cut string with the appended ellipsis character does fit the specified rectangle, we can display it using the good old DrawText function.

The Code

As you can see, the code is pretty self-explanatory. You can use it right away, or make the changes you see fit (there are plenty of those, for sure!).

//
// The UNICODE ellipsis character
//
#define ELLIPSIS ((TCHAR)0x2026)


// DrawTextEx
//
//      Extended version of DrawText
//
int DrawTextEx(HDC hDC, LPCTSTR lpString, int nCount, LPRECT lpRect,
               UINT uFormat)
{
    //
    // Check if the user wants to use the end ellipsis style
    //
    if(uFormat & (DT_END_ELLIPSIS | DT_MODIFYSTRING))
    {
        SIZE   szStr;
        LPTSTR lpStr  = (LPTSTR)lpString;             // Make it non-const
        int    nWidth = lpRect->right - lpRect->left; // Rect width

        //
        // If the user did not specify a string length,
        // calculate it now.
        //
        if(nCount == -1)
            nCount = _tcslen(lpStr);

        //
        // Check if the text extent is larger than the rect's width
        //
        GetTextExtentPoint32(hDC, lpStr, nCount, &szStr);
        if(szStr.cx > nWidth)
        {
            //
            // Make a worst-case assumption on the char count
            //
            int nEstimate = (nCount * nWidth) / szStr.cx + 1;

            if(nEstimate < nCount)
                nCount = nEstimate;

            //
            // Insert the initial ellipsis, by replacing the last char
            //
            lpStr[nCount-1] = ELLIPSIS;
            GetTextExtentPoint32(hDC, lpStr, nCount, &szStr);

            //
            // While the extents are larger than the width, remove one
            // character at the time
            //
            while(szStr.cx > nWidth && nCount > 1)
            {
                lpStr[--nCount] = 0;        // Remove last
                lpStr[nCount-1] = ELLIPSIS; // Replace last with ...
    
                GetTextExtentPoint32(hDC, lpStr, nCount, &szStr);
            }
        }

        //
        // Remove the formatting options, just in case
        //
        uFormat &= ~(DT_END_ELLIPSIS | DT_MODIFYSTRING);
    }
    
    return DrawText(hDC, lpString, nCount, lpRect, uFormat);
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here