如何获取字符串的宽度(以像素为单位)(/逻辑单位)?

时间:2013-04-28 13:16:36

标签: c++ c windows string winapi

我正在关注教程here,将水平滚动条添加到列表控件。除了TextWidth()函数之外的所有东西都有用(VC ++ 2012说它未定义)所以我找到了this个问题。但是我不知道如何初始化hdc,所以我尝试了this。但GetTextExtentPoint32保持返回零。

知道如何解决这个问题吗?

我的代码看起来像这样(编辑后):

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

(szMessage包含用户输入)

2 个答案:

答案 0 :(得分:5)

我的方式:

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

答案 1 :(得分:3)

好的,回答我的问题: 上面的代码(请参阅问题)为Size.cx提供了一个太高的值,因为MESSAGE_SIZE是1000而不是实际字符串的大小所以我使用strMessage.c_str和strMessage.size()代替。这仍然给输出一些小的不准确,我认为这是因为使用了错误的字体,所以我手动制作了一个字体。现在它为Size.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);

编辑:

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

也适用,不需要您制作字体或编辑控件的字体