May 23, 2019, 07:38:04 am


Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........

Calculating button width

Started by sapero, June 09, 2009, 02:56:46 pm

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


June 09, 2009, 02:56:46 pm Last Edit: June 09, 2009, 03:36:04 pm by sapero
I have an owner drawn button with image and text. Button text can wrap into two lines. The minimum button width is 2*margin + image_width.
If button text contains a large word wider (in pixels) than the image, button width should be adjusted to MAX(minimum_width, 2*margin + width_of_largest_word).

I've created the following function to calculate this. It tokenizes the string (strtok/wcstok CRT api's), measures the width of each word and returns the widest result.
What Punctuation Marks (separators) should I use? Space - always. Digits? No, I dont think so.
Code Select
. ? ! : ; - ~ ( ) [ ] . ’ â€Ã...“ â€Ã, / ,
Is this enough?
Code Select
sub CalculateTextWidths(HDC hdc, wstring *pwsztext, int *ppTextWidth, int *ppMaxWordWidth)
int maxw = 0;
*ppTextWidth = 0;

RECT rc;
if (pwsztext)
DrawTextW(hdc, pwsztext, wcslen(pwsztext), &rc, DT_SINGLELINE|DT_CALCRECT);
*ppTextWidth = rc.Width();

// copy the string because tokenizing modifies the text
BSTR bstrText = SysAllocString(pwsztext);

WCHAR *token = wcstok(bstrText, L" "); // L".?!:;-~()[].’â€Ã...“â€Ã,/,"
while (token)
DrawTextW(hdc, token, wcslen(token), &rc, DT_SINGLELINE|DT_CALCRECT);
maxw = __max(maxw, rc.Width());
token = wcstok(NULL, L" ");
*ppMaxWordWidth = maxw;

To draw button text on the window, I'm using DrawText with DT_WORDBREAK flag.


Could "GetTextExtentPoint32" maybe simplify the calculation? :o
Just guessing. :D


No, DrawText with DT_CALCRECT flag computes the width and height of the specified string of text, also does same job as GetTextExtentPoint32.
The subroutine above does not draw any text, it is used to resize the button if needed.

For button text "Button 1" and image 32x32, the "Button" string part is drawn in the first line, and the second part "1" in second line. 32 pixels is enough for "Button" string, but "MySuperDuperButton 1" is too large, I need to resize the button to the width of "MySuperDuperButton" plus margins.