winAPI 函数GetTextExtentPoint32W或GetTextExtentPoint32A可以得出一个字符串的宽度,但这个宽度有时候不准确,如:
字体:
CreateFont(39,14,0,0,0,0,0,0,DEFAULT_CHARSET,
                    OUT_DEFAULT_PRECIS,CLIP_CHARACTER_PRECIS,
    DRAFT_QUALITY,DEFAULT_PITCH,(LPCTSTR)m_strName);wchar_t m_bunicode[1];
m_bunicode[0] = 0xfbfd;  //阿拉伯字符
用GetTextExtentPoint32W(pDC,m_bunicode,1,&pSize)得出来的宽度为20x39,但事实上应该为
21*39,当是一个阿拉伯字符串时有时会与实际相差4,5个象素点,请问有什么办法解决这一难题呢?==========顶者有分==========

解决方案 »

  1.   

    这应当是字符间宽度造成的,如果要精确计算的话,用SetTextCharacterExtra 进行字符间宽度设置,应当就可以解决。
      

  2.   

    试试::DrawText这个API,用DT_CALCRECT参数.
      

  3.   

    感谢大家热情答复!
    1、“GetTextExtent呢”,我再试试。
    2、“DrawText这个API,用DT_CALCRECT”是不可以实现的,MSDN上对于其用法讲得很清楚。
    3、“应当是字符间宽度造成的,如果要精确计算的话,用SetTextCharacterExtra ”单个字符都有不准确的时候,不过我也姑且试一试。
      

  4.   

    1、GetTextExtent是不行的,最终还是调用GetTextExtentPoint32,请看源代码:
    _AFXWIN_INLINE CSize CDC::GetTextExtent(const CString& str) const
    {
    ASSERT(m_hAttribDC != NULL);
    SIZE size;
    VERIFY(::GetTextExtentPoint32(m_hAttribDC, str, str.GetLength(), &size));
    return size;
    }2、SetTextCharacterExtra 函数是用来设置字符串之间额外空白的,不行。不知有没有兄弟写过多过多国语言的软件版本,比如说对中东地区字符串的支持。
      

  5.   

    DrawText用DT_CALCRECT更准确些,我估计你的问题可能和多语言实际上用的是两种字体有关
      

  6.   

    >2、“DrawText这个API,用DT_CALCRECT”是不可以实现的,MSDN上对于其用法讲得很清楚。
    为什么不行?经常用的
      

  7.   

    更正一下,DrawText用DT_CALCRECT是可以计算出字符串宽度(一直误认为只能用来计算高度)
    但也不准确。我是这样来判断是否准确的:将得出的大小返回,以其大小创建一个HBITMAP,然后绘制
    最后保存为一个BMP图片,发现总是有几列被截断了,非要我手工将返回的宽度加大才行。
      

  8.   

    DrawText用DT_CALCRECT是可以计算出字符串宽度的
    而且我一直这么干的 呵呵
    什么叫准确?
      

  9.   

    这样说吧,假如计算出的宽度为20,那么一个20像素宽的RECT可以包含所绘制的字符串了。
    但事实上不是,你必须在一个大于20的RECT中绘制才能包含整个字符串。当然,DrawText或GetTextExtentPoint32在很多情况下面(比如英文字符,汉字)是可以得出准确的结果,但对于泰语,中东地区的语言,肯怕就没那么幸运了!!!
      

  10.   

    起初我也以为可以用GetTextExtent实现,看来...还需向各位请教啊
      

  11.   

    同意 danshuihepan(淡水河畔)
      

  12.   

    问题解决了,用GetTextExtentPoint32W后(这里得到中东地区的语言都是通过输入Unicode码,在Edit控件中无法输入这些文字,至少在中文Windows系统上面不能,所以加上W),
    GetTextExtentPoint32W(... ,&pSize);
    得出SIZE pSize
    然后增加:TEXTMETRIC tm;
    GetTextMetrics(memtempDC,&tm);
    //GetCharABCWidthsW只有在TRUETYPE字体时才能使用,不过如果不是TRUETYPE,GetTextExtentPoint32W也会返回正确的结果了。 :)if(tm.tmPitchAndFamily & TMPF_TRUETYPE)
    {
      ABC abc;
      GetCharABCWidthsW(memtempDC,m_punichar[m_length-1],m_punichar[m_length-1],&abc);
      if(abc.abcC < 0)
        pSize.cx -= abc.abcC;
    }
    ....这样就能显示所有的字符串了。
      

  13.   

    再补充一下:
    GetCharABCWidths得出详细的字符的宽度,abcA是前导空白宽度,abcB是实际的显示宽度,abcC是后面增加的空白列,也可以为负数(特殊字符可能会为负数,如阿拉伯语,越南语,泰语,散含语系等)