Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼


Building a Callout Control

Source Code Accompanies This Article. Download It Now.

August, 2004: Building a Callout Control

Optimizing the Text Box Shape

If you want to reformat a text box, for which we already have an initial width and height, so that it is at most four times as wide as it is high, you only need to combine the equation width×height= area where the area is kept constant, with the upper bound for the width: width£4×height. Simple algebra then gives you the criterion: width£--4×area.

Calculating the Text Box with DrawText()

I found the description of the DT_CALCRECT flag in the documentation for DrawText() confusing and so I did a few experiments to verify the behavior. Fortunately, the DrawText() function is quite robust and more versatile than the documentation suggests.

If the DT_CALCRECT is present in the flags field of the DrawText() function, the function changes the right and the bottom fields of the formatting rectangle, but it does not touch the left and top fields. The value of the right field becomes the left field plus the width of the calculated bounding box of the text after formatting; the bottom field becomes the top field plus the height of the bounding box. Hence, with DT_CALCRECT set, the rectangle parameter is half input and half output.

When you include DT_SINGLELINE in the flags field, the DrawText() function replaces all carriage return (CR) and line feed (LF) characters to a space. There is no special handling of pairs of CR and LF characters; each such character is replaced by a space character.

When neither the flags DT_SINGLELINE and DT_WORDBREAK are set, DrawText() adheres to line-breaking characters in the input string, but it does not otherwise add line breaks. Any occurrence of the CR or LF characters is a line break; a combination like CR-LF or LF-CR counts as a single line break, but CR-CR or LF-LF is a double line break. A line break does not add to the width of the bounding text box, but it does add to its height.

The DT_WORDBREAK flag makes DrawText() use the value of the right field of the formatting rectangle parameter as the right margin and it tries to format the text inside this margin. DrawText() only breaks lines between the words, there is no hyphenation algorithm hidden in the function. If the input string contains a word that is wider than the formatting rectangle, DrawText() extends the formatting rectangle to the width of that word. In a typical situation, after word breaking, the text fits a narrower rectangle than the input formatting rectangle. When DT_WORDBREAK is combined with DT_CALCRECT, DrawText() stores the updated right margin back in the formatting rectangle. So when you use DT_CALCRECT together with DT_WORDBREAK, the resulting formatting rectangle may both be wider (in the presence of a long, nonbreakable word) or narrower than the input rectangle.

I experienced DrawText() entering an infinite loop when the left field of the formatting rectangle was set to a value greater than the right field on input, and the DT_WORDBREAK flag was set. In this case, the input width of the formatting rectangle is negative, so this is arguably an input error and the behavior of DrawText() should be expected to be undefined. DrawText() does not have any difficulty when the left and right fields are set to the same value (input width is zero). I verified this DrawText() behavior on Windows 98/2000, by the way.


Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.