游戏开发论坛

 找回密码
 立即注册
搜索
楼主: 大元帅

请问如何获得字符串的尺寸?

[复制链接]

187

主题

6490

帖子

6491

积分

论坛元老

团长

Rank: 8Rank: 8

积分
6491
发表于 2008-5-28 19:15:00 | 显示全部楼层

Re: Re: Re:请问如何获得字符串的尺寸?

大元帅: Re: Re:请问如何获得字符串的尺寸?



我觉得不太现实

好像有些字符是整块的黑色,测起来很方便啊。

有些字体每个字符宽度都不一样,比如"1"就很瘦,很麻烦的。

29

主题

475

帖子

483

积分

中级会员

Rank: 3Rank: 3

积分
483
 楼主| 发表于 2008-5-29 08:32:00 | 显示全部楼层

Re: Re: Re: Re:请问如何获得字符串的尺寸?

Miu.C: Re: Re: Re:请问如何获得字符串的尺寸?


好像有些字符是整块的黑色,测起来很方便啊。

有些字体每个字符宽度都不一样,比如"1"就很瘦,很麻烦的。


TrueType的字体是规则的,但是有些就不是TrueType类型的,这就比较麻烦了。

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2008-5-29 09:06:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

我的Form.Handle.ToInt32返回的倒不是0,但最后一个Size参数却不论传值传址取回结果始终为0。
有C++人士用GetTextExtentPoint32不成功说是需要先用SetObject设置设备场景字体,然后才能判断长度,可system.drawing.font字体却得不到句柄,不只怎么去尝试

12

主题

423

帖子

428

积分

中级会员

Rank: 3Rank: 3

积分
428
QQ
发表于 2008-5-29 09:29:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

我来给你们写一个吧~~
Public Function GetStringX(ByVal str As String) As Integer
  Dim count As Integer = 0
  Dim i As Integer = 0
  Dim len As Integer = 0
  Dim s As String = ""
  Dim x As Integer = 11'这是:新宋体,大小=16,无粗体,无下画线,无斜体的半角单个字符的宽度
  For i = 0 To str.Length - 1
    s= str.Substring(i,1)
    len+=x
    count=System.Text.UnicodeEncoding.Unicode.GetByteCount(s)
    If count=2 Then len+=x'全角的加陪
  Next i
  Return len
End Function

12

主题

423

帖子

428

积分

中级会员

Rank: 3Rank: 3

积分
428
QQ
发表于 2008-5-29 09:38:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

上面的代码我没有VB.NET测试,不知能不能通过,就当是伪代码吧~~
这个是我的VC代码,我一直都用GetTextExtentPoint32没发现异常哦
另外是用窗体的Form.hDC不是用Form.hWnd
long GetStringWidth(HDC hDC,char *str)
{
  SIZE strw;
  GetTextExtentPoint32(hDC,str,strlen(str),&strw);
  return strw.cx;
}

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2008-5-29 15:24:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

见鬼!同样这几句代码,今天再试怎么又灵了?

Private Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" (ByVal hwnd As Integer) As Integer
Private Declare Function GetTextExtentPoint32& Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hdc As Integer, ByVal lpsz As String, ByVal cbString As Integer, ByRef lpSize As Size)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim S As String = "用完后一定要用ReleaseDC函数释放场景"
        Dim DC As Integer = GetWindowDC(Me.ActiveForm.Handle.ToInt32)
        Dim mySize As Size
        GetTextExtentPoint32(DC, S, S.Length, mySize)        
End Sub

难道GetTextExtentPoint32还跟系统的DirectX有什么联系(代码没改动,只是上午把DirectX重装了一遍)?
要注意一点:ByRef lpSize
另外想获得GetTextExtentPoint32的返回值将会导致算术运算溢出错误

29

主题

475

帖子

483

积分

中级会员

Rank: 3Rank: 3

积分
483
 楼主| 发表于 2008-5-29 23:07:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

谢谢各位的帮忙,我试下各位的方法,谢谢各位的方法

29

主题

475

帖子

483

积分

中级会员

Rank: 3Rank: 3

积分
483
 楼主| 发表于 2008-5-30 13:59:00 | 显示全部楼层

Re: 请问如何获得字符串的尺寸?

问题解决!感谢系统崩溃的方法,自己还研究了加了一些改善的东西,得出来的结果与VB6中TextWidth的结果是一样的,好东西不敢独享,拿出来给大家看下~我写成了个函数,以方便使用,大家也都可以复制,直接使用了~代码中有详尽的注释

    Public Function GetStringSize(ByVal vText As String, ByRef vFont As Font) As Size
        '待测量的字符串
        Dim S As String = vText
        '待测量的字体
        Dim f As Font = vFont
        '通过默认编码获取字符串长度,这种编码是半角一个字符,全角两个字符,只有这样才符合要求
        Dim l As Integer = Encoding.Default.GetBytes(S).Length
        '声明设备上下文
        Dim DC As Integer = GetWindowDC(Me.ActiveForm.Handle.ToInt32)
        '将字体句柄传入系统
        SelectObject(DC, f.ToHfont.ToInt32)
        '准备传址的参数,字体尺寸将被保存在该尺寸中
        Dim mySize As Size
        '通过GetTextExtentPoint32函数获取尺寸
        GetTextExtentPoint32(DC, S, l, mySize)
        '释放设备上下文
        ReleaseDC(Me.ActiveForm.Handle.ToInt32, DC)
        '返回变量
        Return mySize
    End Function

需要使用到的API在下面:
    Private Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" (ByVal hwnd As Integer) As Integer
    Private Declare Function GetTextExtentPoint32& Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hdc As Integer, ByVal lpsz As String, ByVal cbString As Integer, ByRef lpSize As Size)
    Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Integer, ByVal hdc As Integer) As Integer
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Integer, ByVal hObject As Integer) As Integer

截图里面有与VB6的对比结果,果然一样~
sf_200853013590.jpg

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2008-5-30 16:50:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

我只尝试到mySize得到值为止,没再试验具体精度,你的代码与网上一些C++人士的思路完全一致(恭喜终于有了VB.Net版)。
不过现在我倒是有了一个疑问:
Dim l As Integer = Encoding.Default.GetBytes(S).Length得到的是字节数而不是字符数,l作为参数难道意味着GetTextExtentPoint32只能用于计算半角字符?

29

主题

475

帖子

483

积分

中级会员

Rank: 3Rank: 3

积分
483
 楼主| 发表于 2008-5-30 17:32:00 | 显示全部楼层

Re:请问如何获得字符串的尺寸?

Default编码下,全角会算成是16位字节,而半角是8位字节,因此GetTextExtentPoint32是可以计算全角的,我测试使用的字符串是“GameRes游戏开发论坛”,字体是Arial,9号,普通
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 07:04

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表