| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5095 人关注过本帖, 1 人收藏
标题:picturebox 文本换行。
只看楼主 加入收藏
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
结帖率:0
收藏(1)
已结贴  问题点数:20 回复次数:18 
picturebox 文本换行。
第一次发帖。不好意思,可能发出来的格式什么的不好看。见谅。
用途:我在实现监视程序,并把监视结果用图片框显示出来。
问题:以下哪一个效果更棒。或者其他算法。第3途径,我该注意些什么。谢谢了大神。
途径:
    1。  硬性的规定长度x。 if len(Mystr) mod x =0 :换行。(当然会有字符长度判断。用left,right循环取值)
    2。  等提字宽法:Wordwidth。 x=int(pictue1.scalewidth / wordwidth).he   
    3.   随机字宽:  1:循环取单个字符,再用标准fontsize 对比缩放其他字体,获得字宽。 并求字宽和 与 picture1.width 比较?  大于则换行。
                     2:还是随机取字符串,求平均字宽。提高效率?
本人尝试了下。发现在系统的单位转换的基础上薄弱。  比如默认是缇,但是有疑问用像素好还是缇好?     如果代码中设置了scalemode后, 是对后面的print起作用还是前面的也行?    printer  picture  form 的默认单位都是缇一样吗?。。是15 ,20关系吗?    等等
我是在网上也百度了 , 但还是不确定,无奈再次提问大家,想问个确切的答案。

随便问一个问题,我也开发了一些按键外挂,但是还是忧郁,封包,内挂(sendkey),还是mousevent 他们的安全性比较。
谢谢大神们花时间来看。 不当之处,望见谅。

[此贴子已经被作者于2016-11-29 02:44编辑过]

搜索更多相关主题的帖子: 图片 
2016-11-29 02:42
xiangyue0510
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:86
帖 子:938
专家分:5244
注 册:2015-8-10
收藏
得分:7 
1. 硬性的规定长度x。

这个方法显然是不合理的, 比如“123”和“好的”,前者长度为3,但是显示的时候可能没有后者长度大。 另外这个还跟字体设置有关,需要来回尝试才能得到比较一个比较好的x

后面的两个方法似乎可以。我找到的代码是这样的,你测试一下
程序代码:
Dim StrLine As String, StrALL As String
StrALL = "本人在图形(PictureBox)控件上用Print 方法显示文本,但字数太多,让其自动换行。"
For i = 1 To Len(StrALL)
StrLine = StrLine & Mid(StrALL, i, 1)
If Picture1.TextWidth(StrLine) + 200 >= Picture1.Width Then
Picture1.Print StrLine
StrLine = ""
End If
Next
Picture1.Print StrLine

不过一般情况下,我会直接用textbox, multiline改成true,再设置Locked=true就可以实现了,没有必要搞的这么麻烦。
2016-11-29 08:57
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4943
专家分:30067
注 册:2008-10-15
收藏
得分:7 
单位缇还是像素区别不大。
缇与像素的换成,使用 Screen.TwipsPerPixelX  和 Screen.TwipsPerPixelY 属性得到这个比例关系


以前写的一个过程,在指定区域内,按左右上下居中显示的方式显示字符串,该过程适用于 在图像框上显示内容,也适用于在打印机上打印内容
因为是自己用的代码,所以注释量偏少
程序代码:
Private Sub viewtext(cs As String, obj As Object, lefts As Long, tops As Long)
'每一个参数格式:X1,Y1,X2,Y2,显示内容,[字体[,字号]]
'字体为可选,字号也为可选,如果需要指定字号,就必须指定字体

On Error Resume Next

Dim fj() As String
Dim vx As Long, vy As Long
Dim Fx As Long, Fy As Long
Dim hx As Long, hy As Long
Dim m As String, n As String
Dim i As Long, j As Long, k As Long
Dim o As Long
Dim H() As String

    fj = Split(cs, ",")             '分解传进来的参数
    If UBound(fj) > 4 Then          '有字体设置
        If Len(fj(5)) > 0 Then      '字体名不为空
            obj.FontName = fj(5)
        End If
    Else
        obj.FontName = "宋体"       '默认为宋体
    End If
    
    If UBound(fj) > 5 Then          '有字号设置
        If Val(fj(6)) > 2 Then      '字号最小不得小于2
            obj.FontSize = fj(6)
        End If
    Else
        obj.FontSize = 字体大小
    End If
    
    Fy = obj.TextHeight(fj(4))           '字体高
    Fx = obj.TextWidth(fj(4))            '字体宽
    
    hx = Val(fj(2)) - Val(fj(0))        '有效宽
    hy = Val(fj(3)) - Val(fj(1))        '有效高
    
    If Fx > hx Or InStr(1, fj(4), "\") > 0 Then         '如果需要换行或人工指定的多多行
        
        If InStr(1, fj(4), "\") > 0 Then                '如果人工指定的多多行
            H = Split(fj(4), "\")                       '直接分解为每一行
            k = UBound(H)                '取行数
        Else
        
            k = Fx / hx          '计算需要分成多少行
            
            ReDim H(k)
            i = 0
            j = 1
            o = 1
            Do
                H(i) = Mid(fj(4), j, o)                     '一个字符一个字符的试下去
                If obj.TextWidth(H(i)) > hx - 100 Then      '试到撑满格子为止
                    j = j + o                               '本行结束,保存各变量
                    o = 1
                    i = i + 1
                Else
                    o = o + 1                               '本行未结束,长度加一,继续试下去
                End If
                
            Loop While j + o < Len(fj(4)) + 2           '<原来就 要加1,因为循环前是o+1,所以这里要再加1
        
        End If
        
        For i = 0 To k                          '处理每一行
       
            Fx = obj.TextWidth(H(i))            '字体宽
            vx = lefts + Val(fj(0)) + (hx - Fx) / 2
            vy = tops + Val(fj(1)) + (hy - Fy * (k + 1 + (k) * 0.2)) / 2 + Fy * (i) * 1.2           '行距为1.2,总高度为 行数*1+(行数-1)*0.2
            obj.CurrentX = vx
            obj.CurrentY = vy
            obj.Print H(i)
        
        Next i
    
    Else                    '没有多行,直接计算坐标显示
        vx = lefts + Val(fj(0)) + (hx - Fx) / 2
        vy = tops + Val(fj(1)) + (hy - Fy) / 2
        obj.CurrentX = vx
        obj.CurrentY = vy
        obj.Print fj(4)
    End If    
End Sub

授人于鱼,不如授人于渔
早已停用QQ了
2016-11-29 09:05
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:7 
有一个currentx、currenty属性可以利用,自动智能识别最大字宽,可获得满意自动换行,代码及效果如下:
Private Sub Command1_Click()
  Dim a As String, fs As Integer, oldX As Integer, i As Integer
  a = "本人尝试了下。发现在系统的单位转换的基础上薄弱。比如默认是缇,但是有疑问用像素好还是缇好?如果代码中设置了scalemode后,是对后面的print起作用还是前面的也行?printer  picture  form 的默认单位都是缇一样吗?是15 ,20关系吗?等等"
  fs = Picture1.FontSize
  oldX = 0
  For i = 1 To Len(a)
    If Picture1.ScaleWidth - Picture1.CurrentX < fs Then Picture1.Print
    If Picture1.CurrentX - oldX > fs Then fs = Picture1.CurrentX - oldX     '将字宽调整到最大字宽
    oldX = Picture1.CurrentX                                                '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
    Picture1.Print Mid(a, i, 1);
    'oldX = Picture1.CurrentX  该句放这里就会溢出图片框
  Next  
End Sub
图片附件: 游客没有浏览图片的权限,请 登录注册
2016-11-29 09:27
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 2楼 xiangyue0510
多谢大神回复。 起床上个wc看看,那么快速的响应,你们太好了。  不过过会上班,先继续睡一觉,,有空测试了在公布下结果。哈哈谢谢你。

先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-29 09:31
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 3楼 风吹过b
昨天上班,无意浏览到你们的网站,看到你回复的众多帖子,你真是个语重心长 技术过硬的好人,很佩服,给我很深的印象,所以回来鼓起勇气发了个求助帖子,这么多年第一次发类似帖子,以前都是自己百度,算法等自己想办法解决。但解决问题效率和运行效率,真的不敢肯定是否最优,虽然知道知识只有讨论才能升华,但个人性格问题。。。。  所以谢谢你的所有留言,当然还有其他版主,你们都给我了精神上的榜样。只有精神 才能有顶级的知识。 以后很多要向你学习,麻烦了。  此次结果有空测试就验证下,继续睡觉偷个懒,过会上班。。。。嘿嘿  谢谢你。    对了,你们的一个女版主?  哈哈看到她和别人用技术和心态和别人吵了一架,她太让人深刻了,很棒。  你们的这个团队很棒,我们众多网游的精神食粮。

先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-29 09:41
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 4楼 xzlxzlxzl
你的ID. ,虽然昨天才接触这个,但是已经足够熟悉了。我想不止是技术,更是心态和精神。  谢谢哈。  没法,要上班,只能抽空再次测试代码,但相信你们的算法肯定是ok的,对我,算法比语法本身更重要。  你们的各种方法,真的是给我的一个定心丸。  谢谢你版主,早安,不过我先睡觉了。。。

先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-29 09:46
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
以下是引用xzlxzlxzl在2016-11-29 09:27:23的发言:

有一个currentx、currenty属性可以利用,自动智能识别最大字宽,可获得满意自动换行,代码及效果如下:
Private Sub Command1_Click()
  Dim a As String, fs As Integer, oldX As Integer, i As Integer
  a = "本人尝试了下。发现在系统的单位转换的基础上薄弱。比如默认是缇,但是有疑问用像素好还是缇好?如果代码中设置了scalemode后,是对后面的print起作用还是前面的也行?printer  picture  form 的默认单位都是缇一样吗?是15 ,20关系吗?等等"
  fs = Picture1.FontSize
  oldX = 0
  For i = 1 To Len(a)
    If Picture1.ScaleWidth - Picture1.CurrentX < fs Then Picture1.Print
    If Picture1.CurrentX - oldX > fs Then fs = Picture1.CurrentX - oldX     '将字宽调整到最大字宽
        oldX = Picture1.CurrentX                                                '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
    Picture1.Print Mid(a, i, 1);
    'oldX = Picture1.CurrentX  该句放这里就会溢出图片框
  Next  
End Sub


程序代码:
Public Sub MyPrint(myStr As String, linemark As Long)
'*******************************************************
'picturebox换行处理
    Dim i As Integer, fs As Integer, oldX As Integer
    Dim a As String
    linemark = linemark + 1'行标
    'count8 = count8 + 1
    'count9 = count9 + 1
    
    fs = Form1.Picture3.FontSize
    oldX = 0
    For i = 1 To Len(myStr)
        If Form1.Picture3.ScaleWidth - Form1.Picture3.CurrentX < fs Then Form1.Picture3.Print Tab(Len(linemark) + 3);                   '同一记录的下一行输出位置应该在此处确定!
        
        If Form1.Picture3.CurrentX - oldX > fs Then fs = Form1.Picture3.CurrentX - oldX       '将字宽调整到最大字宽
        oldX = Form1.Picture3.CurrentX                                                        '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
        If i = 1 Then
            Form1.Picture3.Print linemark; Tab(Len(linemark) + 3); ":"; Mid(myStr, i, 1);
        Else
            Form1.Picture3.Print Mid(myStr, i, 1);
        End If
        
        '可爱翻页。但是条件简陋,当同一个记录的下一行的可用高度大于currenty小于字体高度就发生溢出少许。办法:字体高度加入判断条件,或者改变picturebox height属性到等倍字高。
        If Form1.Picture3.ScaleHeight < Form1.Picture3.CurrentY Then
            i = 0                                                                              ' 不可以吧i初始化为i=1原因:i在next会自动+1。
        End If
        Call 图片显示清屏处理
        'oldX = Form1.Picture3.CurrentX ' 该句放这里就会"最后一个字符一些部位"可能溢出图片框. 原因:CurrentX指定的是“下一个”打印位置。解决办法:加入宽度判断或者 将此句放在print前面。
    Next
    Form1.Picture3.Print  ’这是多次打印必须的。否则乱麻。 
End Sub


     你的核心源码没动,暂且称之为:自动等宽处理法?。自己理解了一下你的注释。大约增加了一个行标。  要上班 没来得及对注释中的bug处理。  另外两个版主大神的代码没来得及看。  有空再试试你们的方法,并简短封装一下,把几种方法融合,方便学习使用。再次谢谢
   
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2016-11-29 13:52编辑过]


先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-29 13:43
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
以下是引用xzlxzlxzl在2016-11-29 09:27:23的发言:

有一个currentx、currenty属性可以利用,自动智能识别最大字宽,可获得满意自动换行,代码及效果如下:
Private Sub Command1_Click()
  Dim a As String, fs As Integer, oldX As Integer, i As Integer
  a = "本人尝试了下。发现在系统的单位转换的基础上薄弱。比如默认是缇,但是有疑问用像素好还是缇好?如果代码中设置了scalemode后,是对后面的print起作用还是前面的也行?printer  picture  form 的默认单位都是缇一样吗?是15 ,20关系吗?等等"
  fs = Picture1.FontSize
  oldX = 0
  For i = 1 To Len(a)
    If Picture1.ScaleWidth - Picture1.CurrentX < fs Then Picture1.Print
    If Picture1.CurrentX - oldX > fs Then fs = Picture1.CurrentX - oldX     '将字宽调整到最大字宽
    oldX = Picture1.CurrentX                                                '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
    Picture1.Print Mid(a, i, 1);
    'oldX = Picture1.CurrentX  该句放这里就会溢出图片框
  Next  
End Sub


进一步改进(已经测试了不同字体和字号,和不同scalemode):
程序代码:
'picturebox换行处理
    Dim i As Integer, fs As Integer, oldX As Integer
    Dim a As String
    linemark = linemark + 1 '行标
    'count8 = count8 + 1
    'count9 = count9 + 1
    Form1.Picture3.ScaleMode = 1
    '‘fs = Form1.Picture3.FontSize
    'fs =
    
    oldX = 0
    For i = 1 To Len(mystr)
        fs = Form1.Picture3.TextWidth(Mid(mystr, i, 1))'/**/版主用字号来做判断条件太简陋了,不恰当的box宽度,肯定会出现空格。改进为宽度判断。
        If Form1.Picture3.ScaleWidth - Form1.Picture3.CurrentX < fs Then Form1.Picture3.Print Tab(Len(linemark) + 3);               '/**/同一记录的下一行输出位置应该在此处确定!
        
        'If Form1.Picture3.CurrentX - oldX > fs Then ' fs = Form1.Picture3.CurrentX - oldX '将字宽调整到最大字宽。  /**/基于上面fs的解释,这句就多余了。
            oldX = Form1.Picture3.CurrentX                                                        '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
        If i = 1 Then
            Form1.Picture3.Print linemark; Tab(Len(linemark) + 3); ":"; Mid(mystr, i, 1);
        Else
            Form1.Picture3.Print Mid(mystr, i, 1);
        End If
        
        '可爱翻页。但是条件简陋,当同一个记录的下一行的可用高度大于currenty小于字体高度就发生溢出少许。办法:字体高度加入判断条件,或者改变picturebox height属性到等倍字高。
        If Form1.Picture3.ScaleHeight < Form1.Picture3.CurrentY Then
            i = 0                                                                              ' 不可以吧i初始化为i=1原因:i在next会自动+1。
        End If
        Call 图片显示清屏处理
        'oldX = Form1.Picture3.CurrentX ' 该句放这里就会"最后一个字符一些部位"可能溢出图片框. 原因:CurrentX指定的是“下一个”打印位置。解决办法:加入宽度判断或者 将此句放在print前面。
    Next
    Form1.Picture3.Print  '这是多次打印必须的。否则乱麻。


效果:
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册

先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-30 03:04
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
以下是引用xzlxzlxzl在2016-11-29 09:27:23的发言:

有一个currentx、currenty属性可以利用,自动智能识别最大字宽,可获得满意自动换行,代码及效果如下:
Private Sub Command1_Click()
  Dim a As String, fs As Integer, oldX As Integer, i As Integer
  a = "本人尝试了下。发现在系统的单位转换的基础上薄弱。比如默认是缇,但是有疑问用像素好还是缇好?如果代码中设置了scalemode后,是对后面的print起作用还是前面的也行?printer  picture  form 的默认单位都是缇一样吗?是15 ,20关系吗?等等"
  fs = Picture1.FontSize
  oldX = 0
  For i = 1 To Len(a)
    If Picture1.ScaleWidth - Picture1.CurrentX < fs Then Picture1.Print
    If Picture1.CurrentX - oldX > fs Then fs = Picture1.CurrentX - oldX     '将字宽调整到最大字宽
    oldX = Picture1.CurrentX                                                '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
    Picture1.Print Mid(a, i, 1);
    'oldX = Picture1.CurrentX  该句放这里就会溢出图片框
  Next  
End Sub


进一步优化:翻页,简单解决行高溢出问题。重新对oldx 和oldy 优化。
程序代码:
'*******************************************************
'picturebox换行处理
    Dim i As Integer, fsx As Integer, fsy As Integer, oldX As Integer, oldY As Integer
    Dim a As String
    linemark = linemark + 1 '行标
    Form1.Picture3.ScaleMode = 4
    '‘fs = Form1.Picture3.FontSize
    'fs =
    
    oldX = 0
    For i = 1 To Len(mystr)
        fsx = Form1.Picture3.TextWidth(Mid(mystr, i, 1))
        fsy = Form1.Picture3.TextHeight(Mid(mystr, i, 1))
        oldX = Form1.Picture3.CurrentX       '记下当前字符位置,Picture1.CurrentX - oldX就是刚打印的字符宽度,该句放这里效果最佳
        oldY = Form1.Picture3.CurrentY
        If Form1.Picture3.ScaleWidth - Form1.Picture3.CurrentX < fsx Then Form1.Picture3.Print Tab(Len(linemark) + 3);               '同一记录的下一行输出位置应该在此处确定!
        
        'If Form1.Picture3.CurrentX - oldX > fs Then ' fs = Form1.Picture3.CurrentX - oldX '将字宽调整到最大字宽(已取消)

        If i = 1 Then
            Form1.Picture3.Print linemark; Tab(Len(linemark) + 3); ":"; Mid(mystr, i, 1);
        Else
            Form1.Picture3.Print Mid(mystr, i, 1);
        End If
        
        '可爱翻页。
        If Form1.Picture3.ScaleHeight - oldY - fsy < 0 Then
            i = 0                                                                              ' 不可以吧i初始化为i=1原因:i在next会自动+1。
        End If
        
        If Form1.Picture3.ScaleHeight - oldY - fsy < 0 Then
            Form1.Picture3.Cls
        End If
        'Call 图片显示清屏处理
        'oldX = Form1.Picture3.CurrentX ' 该句放这里就会"最后一个字符一些部位"可能溢出图片框. 原因:CurrentX指定的是“下一个”打印位置。解决办法:加入宽度判断或者 将此句放在print前面。
    Next
    Form1.Picture3.Print  '这是多次打印必须的。否则乱麻。


效果:(谢谢大神引导,暂时告一段落,满足了我的需求。再看看另外两个版主的方法)
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2016-11-30 03:31编辑过]


先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-11-30 03:30
快速回复:picturebox 文本换行。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020494 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved