Как получить ширину строки в пикселях(/логических единицах)?

Я следую учебник здесь, чтобы добавить горизонтальную полосу прокрутки в элементе управления "список". Все там работает, кроме функции TextWidth () (VC++ 2012 говорит, что это неопределенно), поэтому я нашел этой вопрос. Но я понятия не имею, как инициализировать hdc, поэтому я попытался этой. Но GetTextExtentPoint32 продолжает возвращать ноль.

есть идеи, как я могу это решить?

мой код выглядит так (после edit):

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

(szMessage содержит пользовательский ввод)

2 ответов


мой путь:

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);

Ok, чтобы ответить на мой вопрос: Код выше (см. вопрос) дает слишком высокое значение для размера.cx, потому что MESSAGE_SIZE-1000, а не размер фактической строки, поэтому я использовал strMessage.c_str и strMessage.размер() вместо этого. Это все еще давало некоторые небольшие неточности с выходом, я предположил, что это было потому, что использовался неправильный шрифт, поэтому я вручную сделал шрифт. Теперь он дает правильное значение размера.cx. Код теперь выглядит так:

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;
    }
}

позже в код:

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

Edit:

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

тоже работает и не требует, чтобы вы делали шрифт или редактировали шрифт элемента управления