| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5201 人关注过本帖, 1 人收藏
标题:picturebox 文本换行。
只看楼主 加入收藏
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:0 
嗯,要实现题主这样的效果,应该可以充分利用picture属性和方法,让函数更科学、通用,代码更精炼合理。
2016-11-30 12:24
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
以下是引用lingyuan1021在2016-11-30 03:30:05的发言:



进一步优化:翻页,简单解决行高溢出问题。重新对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  '这是多次打印必须的。否则乱麻。

效果:(谢谢大神引导,暂时告一段落,满足了我的需求。再看看另外两个版主的方法)


进一步优化:上面那个代码原来有个大bug:惹高度溢出为第一行时,下页输出会出错。嘿嘿 还好细心分析了下。麻雀虽小,强迫症。。。 优化下算法(解决bug。同时提升利用率。)。如下:
程序代码:
Public Sub MyPrint(mystr As String, linemark As Long, obj As Object) '’如obj=form1.picture3
    'picturebox
    Dim i As Integer, fsx As Integer, fsy As Integer, oldX As Integer, oldY As Integer
    Dim a As String
    linemark = linemark + 1 '行标
    obj.ScaleMode = 1
    oldX = 0
    For i = 1 To Len(mystr)
        fsx = obj.TextWidth(Mid(mystr, i, 1))
        fsy = obj.TextHeight(Mid(mystr, i, 1))
        oldX = obj.CurrentX       
        oldY = obj.CurrentY
        If obj.ScaleWidth - obj.CurrentX < fsx Then obj.Print Tab(Len(linemark) + 3); 
        If obj.ScaleHeight - oldY - fsy < 0 Then
            If i = 1 Then
                obj.Cls
            Else
                obj.Cls
                obj.Print Tab(Len(linemark) + 3);
            End If
        End If
        If i = 1 Then
            obj.Print linemark; Tab(Len(linemark) + 3); ":"; Mid(mystr, i, 1);
        Else
            obj.Print Mid(mystr, i, 1);
        End If 
    Next
    obj.Print 
End Sub


[此贴子已经被作者于2016-12-1 01:44编辑过]


先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-12-01 01:35
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 10楼 lingyuan1021
进一步优化,和完善一些小功能。 反正没事做,,,  
连续自动打印效果(20-24 没打印就截图了):
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2016-12-1 13:38编辑过]


先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-12-01 13:37
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:0 
对你12楼的代码进行了测试,发现一些问题
1:你字宽取第一个字符的字宽,如果第一个字符是ascii码,宽度只有中文字符的一半,此时换行处中文字符可能只显示一半,另中国字为方块字,字高就是字宽,因此不需要fzy变量
2:当显示字符足够多,一个图片框装不下时,只显示后面的字符,而不是从头显示然后等待翻页
3:使用TAB作为格式符,当字体大小不同时,显示格式就对不齐
4:当显示字符里含有换行符时,显示格式就乱了
2016-12-01 15:52
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:0 
下午没什么事,模仿你的功能需求也做了个,我使用了显示缓冲区概念,不管追加多少字符,均可通过翻页完成显示,自动累加并显示行号,可设置显示字符大小和颜色,不管设置字符大小如何,显示格式的对齐位置不变,反正可能出现的极端情况尽量考虑进去(比如字符显示刚好在边界处有换行符导致的重复换行),核心代码及显示效果如下:
程序代码:
Public Function picPrint(sPic As PictureBox, inChar As String) As Integer
  Dim a As String, i As Integer, j As Integer, locStart As Integer, fSize As Integer
  inChar = Trim(inChar)
  picPrint = -1                              '先假设函数调用失败
  j = sPic.FontSize
  sPic.FontSize = 9
  locStart = sPic.TextHeight("") * 8         '设置标准的格式起点,确保任何大小的字符起点一致
  sPic.FontSize = j
  fSize = sPic.TextHeight("")                '按方块字的规则,字高等于字宽
  If sPic.ScaleHeight < fSize Or sPic.ScaleWidth < locStart + fSize Then Exit Function   '如果图片没有足够的宽高则调用失败,返回-1
  If inChar = "" And sPic.DataMember = "" Then
    picPrint = 0
    sPic.Cls
    sPic.DataField = 0
    Exit Function                             '显示字符和显示缓冲字符都为空则清屏、行标清0
  End If
  If inChar <> "" Then sPic.DataMember = sPic.DataMember & Chr(1) & inChar  '待显示字符添加到显示缓冲区
  If sPic.CurrentX > 0 Then sPic.Print        '确保另起一行显示
  If sPic.CurrentY + fSize > sPic.ScaleHeight Then sPic.Cls  '如果当前显示位置不足以显示一个字符高度,说明要换页显示
  For i = 1 To Len(sPic.DataMember)
    a = Mid(sPic.DataMember, i, 1)
    If Asc(a) > 0 And Asc(a) < 14 Then
      '属于控制符的处理,1是我自定义的追加字符和缓冲区未显示完字符的分隔符
      If Asc(a) = 1 Then
        If sPic.CurrentX > 0 Then sPic.Print
        If sPic.CurrentY + fSize > sPic.ScaleHeight Then
          i = i - 1
          Exit For
        End If
        sPic.Print Val(sPic.DataField) & ":";
        sPic.DataField = Val(sPic.DataField) + 1
        sPic.CurrentX = 0
      End If
      If Asc(a) = 13 Then sPic.Print
    Else
      If sPic.CurrentX = 0 Then sPic.CurrentX = locStart
      sPic.Print a;
      If sPic.CurrentX + fSize > sPic.ScaleWidth Then sPic.Print
    End If
    If sPic.CurrentY + fSize > sPic.ScaleHeight Then Exit For
  Next
  If i > Len(sPic.DataMember) Then i = i - 1
  sPic.DataMember = Right(sPic.DataMember, Len(sPic.DataMember) - i)
  picPrint = Len(sPic.DataMember)
End Function

图片附件: 游客没有浏览图片的权限,请 登录注册
2016-12-01 16:10
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 14楼 xzlxzlxzl
手机回复。  十二楼代码的确有问题。十三楼就解决了一些。  不过  那个字宽,是每一个字符宽度,不是第一个字符。     不过你说的那几个问题要回家才能测试。   你说的是不是同一行不同字体带来的问题?       初步猜想是没有最大字宽变量下,     原代码又没有考虑字高来设计打印位置 ,另一方面,不同字体间可能间隙,width 函数不能测出的原因。   回家再看看,同时发上新代码。

先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-12-01 16:43
lingyuan1021
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2016-11-28
收藏
得分:0 
回复 15楼 xzlxzlxzl
谢谢新的思路,缓冲区这些。  有点不同的是,那是个自动打印,要把指定字符加颜色,就像十三效果。  现在是ok了。    回家再把你的新方式和可能bug考虑进去。。

[此贴子已经被作者于2016-12-1 16:54编辑过]


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

对你12楼的代码进行了测试,发现一些问题
1:你字宽取第一个字符的字宽,如果第一个字符是ascii码,宽度只有中文字符的一半,此时换行处中文字符可能只显示一半,另中国字为方块字,字高就是字宽,因此不需要fzy变量
2:当显示字符足够多,一个图片框装不下时,只显示后面的字符,而不是从头显示然后等待翻页
3:使用TAB作为格式符,当字体大小不同时,显示格式就对不齐
4:当显示字符里含有换行符时,显示格式就乱了


现在程序运行到很符合我的要求。但有你说的一些问题,但是为了进一步完善,再啰嗦几天 呵呵,实在没时间写代码,完善了再发上来让你们修改。 以后网友感兴趣的也可以直接引用,不用那么麻烦了。

回家看了下,找了你说的原因。
    1。 ASCII VBLF TAB 等相当于"操作" 。  我封装的那个函数功能是对 “字符串” 做出处理。   
        ASCII 暂时测试正常。放第一个位置也是正常的。 特殊ASCII无法显示的会用?表示。但是格式不受影响。
        VBLF 这些换行之类的 行为操作,暂时没有单独对他们处理,不支持而已,如果存在,所以会错位。 因为该操作会暂时中断,或者说优先于函数体对后面字符的处理,所以会错排。需要单独解决。但是感觉没有必要,这不是该函数的功能。现在考虑下。
        字体大小突然变换引起排版问题: 这个的确没有注意到。回头按照你说的,设置标准点阵。或者回头我想用等比缩放试试。
    2。。。  完了 忘了要说什么。刚才还想起的。那就先这样吧。
    3。。。  对了,翻页显示问题。那个我就做的 可爱翻页,因为很简单,至少不会出现溢出。可以溢出了重新显示。  但是时间太少了,没有考虑太多,你说的存-显模式,提醒了我。早这样交流就不会这么笨了。。有空试试罗。。

[此贴子已经被作者于2016-12-2 05:05编辑过]


先天下之忧而忧,后天下之乐而乐。这里的天下,指黎民百姓。
2016-12-02 05:01
dsasada
Rank: 1
等 级:新手上路
帖 子:54
专家分:3
注 册:2018-3-30
收藏
得分:0 
学习了,不错
2018-04-17 14:03
快速回复:picturebox 文本换行。
数据加载中...
 
   



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

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