如何根据stdfont中的字体计算给定字符串的宽度和高度
不使用textwidth和textheight方法。

解决方案 »

  1.   

    .Net中用MeasureString,VB中你用API: GetTextExtentPoint32处理吧:GetTextExtentPoint32
    The GetTextExtentPoint32 function computes the width and height of the specified string of text. BOOL GetTextExtentPoint32(
      HDC hdc,           // handle to device context
      LPCTSTR lpString,  // pointer to text string
      int cbString,      // number of characters in string
      LPSIZE lpSize      // pointer to structure for string size
    );
     
    Parameters
    hdc 
    Handle to the device context. 
    lpString 
    Pointer to the string of text. The string does not need to be zero-terminated, since cbString specifies the length of the string. 
    cbString 
    Specifies the number of characters in the string. 
    lpSize 
    Pointer to a SIZE structure in which the dimensions of the string are to be returned. 
      

  2.   

    试试这个:
    =========================================================
    Private Type Size
        cx As Long
        cy As Long
    End TypePrivate Declare Function GetTextExtentPoint32 Lib "gdi32" _
        Alias "GetTextExtentPoint32A" (ByVal hDC As Long, _ 
        ByVal lpsz As String, _
        ByVal cbString As Long, _
        lpSize As Size) As LongPrivate Sub Form_Load()
        Dim lngReturn As Long
        Dim typSize As Size
        Dim lngX As Long
        Dim lngY As Long
        Dim strMyString As String
        
        strMyString = "This is my string"
        
        lngReturn = GetTextExtentPoint32(Me.hDC, strMyString, Len(strMyString), typSize)
        
        With typSize
            lngX = .cx * Screen.TwipsPerPixelX
            lngY = .cy * Screen.TwipsPerPixelY
        End With
        
        MsgBox "X =" & lngX & " Y=" & lngY    
    End Sub
      

  3.   

    //不使用textwidth和textheight方法。其实用textwidth和textheight方法,结合ScaleX ScaleY还是可以满足你的要求的
      

  4.   

    首先感谢各位星星的回复但是抱歉的是解决不了偶的问题,使用GetTextExtentPoint32方法,那么获取的是DC中当前字体的字符串的长度,而我需要的是,不从DC获取。
    也就是给你一个字符串和stdfont对象,求这个字符串的长度和宽度。
    相当于
    public function GetWidth(byref vFont as StdFont,byval vStr as string) as longEnd function
      

  5.   

    首先感谢各位星星的回复但是抱歉的是解决不了偶的问题,使用GetTextExtentPoint32方法,那么获取的是DC中当前字体的字符串的长度,而我需要的是,不从DC获取。
    也就是给你一个字符串和stdfont对象,求这个字符串的长度和宽度。
    相当于
    public function GetWidth(byref vFont as StdFont,byval vStr as string) as longEnd function
      

  6.   

    加一个label,设置autosize=true然后设置font属性,caption属性然后取label的width
      

  7.   

    来晚啦,我想说的就是用label,设置autosize=true的方法,给楼上抢先啦
      

  8.   

    我如果能使用控件,我又何必不取Textwidth。而使用Label!!!
      

  9.   

    //但是抱歉的是解决不了偶的问题,使用GetTextExtentPoint32方法,那么获取的是DC中当前字体的字符串的长度,而我需要的是,不从DC获取。
    也就是给你一个字符串和stdfont对象,求这个字符串的长度和宽度。为什么不能从DC中获取,是项目的要求吗?,如果不能使用控件的话,可以用CreateCompatibleDC创建一个DC,接着CreateFont创建一种字体,用selectobject为DC选定字体后,就可以计算了
      

  10.   

    是这样的,偶现在需要解决的是在DC的一个Rect内写一个字符串,例如写"ABCDEF",其中ABC为粗体大小12,而DEF为粗斜体,并且还要可以设置这个字符串在Rect内是居中还是左对齐,那么我需要根据对齐方式计算出写这个字符串的起始位置,那么我就需要根据字符串的总长度计算。
    而如果先设DC的Font的话,那么程序的顺序将是
    1、设置两次DC的Font才可以计算出这个字符串的长度,如果是多种字体,则需要设置多次。
    2、根据对齐方式计算出写这个字符串的起始位置。
    3、循环根据每段文字设置DC的字体,并在DC中写字符串。
    综上可以看出要写的字符串有两种字体,那么我需要对DC设置4次字体(前两次获取长度,后两次才是写字符串),如果有3个字体,那我需要设置6次,这显示不是正解,也不是我需要的。
    我现在想的是如何省略第一步中对DC的两次字体设置。不知我所说的各位大侠是否能够明白?
      

  11.   

    借用pictureBox.with picture1
    .visable=fasle
    .cls
    .print "测试字符串"msgbox "文字大小为:("& (.ScaleX) &"," &(.Scaley) &")"
    end with
      

  12.   

    //例如在区域(20,10)-(100,40)内以水平居中对齐打印一串字符串(有1至N种字符格式),而如果要求水平居中对齐,则打印字符串的起始位置公式是:(区域宽度-字符串长度)/2。区域宽度是已知的,但这个字符串的长度当然是一段一段字符格式的字符长度相加,对不?所以要找到打印的起始位置,必须先算出字符串的总长度。对不?对,基本上是这个思路//以这样方式打印输出的,应该是左对齐,是吗?这样存在一个问题,在居中对齐或右对齐方式下如何知道字符串打印的起始X和Y坐标。
    这个不一定是左对齐
    你可以看看DrawText的说明:
    【VB声明】
      Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long【别名】
      DrawTextA【返回值】
      Long,描绘文字的高度 【参数表】
      hdc ------------  Long,欲在其中显示文字的一个设备场景的句柄  lpStr ----------  String,欲描绘的文本字串  nCount ---------  Long,欲描绘的字符数量。如果要描绘整个字串(直到空中止符),则可将这个参数设为-1  lpRect ---------  RECT,指定用于绘图的一个格式化矩形(采用逻辑坐标)  wFormat --------  Long,一个标志位数组,决定了以何种形式执行绘图。参考下面总结的常数类型列表
      标志常数
    【说明】
      DT_BOTTOM 
      必须同时指定DT_SINGLE。指示文本对齐格式化矩形的底边 
      DT_CALCRECT 
      象下面这样计算格式化矩形:多行绘图时矩形的底边根据需要进行延展,以便容下所有文字;单行绘图时,延展矩形的右侧。不描绘文字。由lpRect参数指定的矩形会载入计算出来的值 
      DT_CENTER 
      文本垂直居中 
      DT_EXPANDTABS 
      描绘文字的时候,对制表站进行扩展。默认的制表站间距是8个字符。但是,可用DT_TABSTOP标志改变这项设定 
      DT_EXTERNALLEADING 
      计算文本行高度的时候,使用当前字体的外部间距属性(the 
      external leading attribute) 
      DT_LEFT 
      文本左对齐 
      DT_NOCLIP 
      描绘文字时不剪切到指定的矩形 
      DT_NOPREFIX 
      通常,函数认为 & 
      字符表示应为下一个字符加上下划线。该标志禁止这种行为 
      DT_RIGHT 
      文本右对齐 
      DT_SINGLELINE 
      只画单行 
      DT_TABSTOP 
      指定新的制表站间距,采用这个整数的高8位 
      DT_TOP 
      必须同时指定DT_SINGLE。指示文本对齐格式化矩形的顶部 
      DT_VCENTER 
      必须同时指定DT_SINGLE。指示文本对齐格式化矩形的中部 
      DT_WORDBREAK 
      进行自动换行。如用SetTextAlign函数设置了TA_UPDATECP标志,这里的设置则无效 
      

  13.   

    在一个临时的 DC 上同时进行输出文本和计算宽度,这样只要设置 N 次字体,最后根据对齐方式计算输出位置,从临时 DC 上将包含文本输出的块画到实际显示的 DC 上。
      

  14.   

    其实用不用这个API函数都无所谓,即使用了,在VB中效果也达不到,因为,API还是返回该字符串的字符个数,然后乘上一个系数,再乘屏幕的分辨率的系数,前者系数为6,后者系数可用Screen.TwipsPerPixelY。但是该字符串的个数依然是将全角即中文字符和半角即英文或数字字符当做一个字符,这样,还是那个问题解决不了,系统会按照半角字符的宽度求值,含有全角字符的字符串宽度就不准了。
    实际上全角字符应该占两个半角字符的宽度。可采用一个循环,依次提取字符串中的每个字符进行判断,返回其ASCII码值如果在0-255之间,则该字符为半角字符,字符个数加1,否则,该字符为全角字符,字符个数加2.这样求出的总字符个数则为准确的字符个数,再用此个数乘以系数6(即不用API),再乘以Screen.TwipsPerPixelY,最好能加一个误差值(因为所有全角字符会有半个字即1个字符显示不出来,但加1个字符个数会让误差变得更套,所以最好加1个误差值),该值为100缇,这样则比较准确了。
      

  15.   

    使用drawtext有误差,当字符数较大、有分行符,有强行断行等情况时时尤其如此.