Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the width of a string in pixels(/logical units)?

I am following a tutorial here, to add a horizontal scrollbar to a list control. Everything there works except the TextWidth() function (VC++ 2012 says it's undefined) so I found this question. But I have no idea how to initialize a hdc, so I tried this. But GetTextExtentPoint32 keeps returning zero.

Any idea how I can solve this?

My code looks like this (after edit):

SIZE Size;
HDC hdc=GetDC(hWnd);
iResult=GetTextExtentPoint32(hdc, szMessage, MESSAGE_SIZE, &Size);

(szMessage contains user input)

like image 894
BioCycle Avatar asked Apr 28 '13 13:04

BioCycle


People also ask

How do you find the width of a string in C++?

The C++ String class has length() and size() function. These can be used to get the length of a string type object. To get the length of the traditional C like strings, we can use the strlen() function.

How do I get text size in C++?

You can get the length of a string object by using a size() function or a length() function. The size() and length() functions are just synonyms and they both do exactly same thing.


2 Answers

My way:

SIZE sz;
HFONT font = GetFont();     //GetFont() is part of WTL. If using raw WinAPI it needs to get font in other means.
HDC hdc = GetDC(NULL);
SelectObject(hdc, font);    //attach font to hdc

GetTextExtentPoint32(hdc, text, lstrlenW(text), &sz);
ReleaseDC(NULL, hdc);
like image 129
ST3 Avatar answered Nov 11 '22 12:11

ST3


Ok so to answer my question: The code above (see question) gives a way too high value for Size.cx because MESSAGE_SIZE is 1000 and not the size of the actual string so I used strMessage.c_str and strMessage.size() instead. This still gave some small inaccuracies with the output, I assumed this was because the wrong font was used, so I manually made a font. Now it gives a correct value for Size.cx. The code now looks like this:

int iHorExt=0;
SIZE Size;
int iCurHorExt=0 // iCurHorExt is actually a global var to prevent it from being reset to 0 evertime the code executes
string strMessage="Random user input here!"

HDC hdc=GetDC(hDlg);

//Random font
HFONT hFont=CreateFont(15, 5, NULL, NULL, FW_MEDIUM, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_ROMAN, "Times New Roman");

//change font of the control
SendDlgItemMessage(hDlg, IDC_LIST1, WM_SETFONT, (WPARAM)hFont, true);


SelectObject(hdc, hFont);

int iResult=GetTextExtentPoint32(hdc, strMessage.c_str(), strMessage.size(), &Size);
if(iResult!=0)
{
    iHorExt=Size.cx;
    if(iHorExt>iCurHorExt)
    {
        iCurHorExt=iHorExt;
    }
}

later in the code:

SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETHORIZONTALEXTENT, iCurHorExt, NULL);

Edit:

SelectObject(hdc, (HFONT)SendDlgItemMessage(hDlg, IDC_LIST1, WM_GETFONT, NULL, NULL));

Works too and doesn't require you to make a font or edit the font of the control

like image 30
BioCycle Avatar answered Nov 11 '22 11:11

BioCycle