【问题标题】:How to get the width of a string in pixels(/logical units)?如何以像素(/逻辑单位)获取字符串的宽度?
【发布时间】:2013-04-28 13:16:36
【问题描述】:

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

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

我的代码如下所示(编辑后):

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

(szMessage 包含用户输入)

【问题讨论】:

  • 一个字符串只有在你设置为特定字体时才具有定义的宽度。这就是您需要图形上下文 (hdc) 的原因。使用 hdc 作为输出窗口。
  • @stark 如何为我的输出窗口获取 hdc,这就是我卡住的地方
  • 您可以拨打GetDC(hWnd)获取。
  • 你应该使用SIZE size;并将指针传递给GetTextExtentPoint32(..., &size);
  • @Slava 工作,谢谢。如果需要,请继续发布答案

标签: c++ c windows string winapi


【解决方案1】:

我的方式:

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

【讨论】:

    【解决方案2】:

    好的,回答我的问题: 上面的代码(见问题)为 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));
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-17
      • 2011-09-24
      • 2013-08-22
      • 1970-01-01
      • 2011-06-28
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多