| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 599 人关注过本帖
标题:如何获得edit框的行数问题
取消只看楼主 加入收藏
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
结帖率:97.78%
收藏
已结贴  问题点数:20 回复次数:9 
如何获得edit框的行数问题
前一段时间有人提问如何获得编辑框里文字的行数,今天就试着写了一段代码,好像还能正确运行,特分享给大家。

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

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


10/5 晚更新代码,符合微软雅黑20号字体。
源代码:
程序代码:
**************************************************
*-- Form:         form1 (d:\documents\visual foxpro 项目\edittest.scx)
*-- 父类:  form
*-- 基类:    form
*-- 时间戳:   11/05/25 09:38:11 PM
*
DEFINE CLASS form1 AS form


    Top = 0
    Left = 0
    Height = 559
    Width = 712
    DoCreate = .T.
    Caption = "Form1"
    Name = "Form1"


    ADD OBJECT edit1 AS editbox WITH ;
        Height = 552, ;
        Left = 0, ;
        Top = 0, ;
        Width = 421, ;
        Name = "Edit1"


    ADD OBJECT text1 AS textbox WITH ;
        Height = 20, ;
        Left = 509, ;
        Top = 12, ;
        Width = 100, ;
        Name = "Text1"


    ADD OBJECT text2 AS textbox WITH ;
        Height = 20, ;
        Left = 509, ;
        Top = 48, ;
        Width = 100, ;
        Name = "Text2"


    ADD OBJECT command1 AS commandbutton WITH ;
        AutoSize = .T., ;
        Top = 96, ;
        Left = 552, ;
        Height = 25, ;
        Width = 84, ;
        Caption = "计算字数与行", ;
        Name = "Command1"


    ADD OBJECT label1 AS label WITH ;
        AutoSize = .T., ;
        Caption = "每行字数:", ;
        Height = 16, ;
        Left = 432, ;
        Top = 16, ;
        Width = 62, ;
        Name = "Label1"


    ADD OBJECT label2 AS label WITH ;
        Caption = "行数:", ;
        Height = 16, ;
        Left = 434, ;
        Top = 50, ;
        Width = 38, ;
        Name = "Label2"


    ADD OBJECT command2 AS commandbutton WITH ;
        AutoSize = .T., ;
        Top = 144, ;
        Left = 480, ;
        Height = 25, ;
        Width = 156, ;
        Caption = "生成一串随机字符再次测试", ;
        Name = "Command2"


    PROCEDURE Init
        this.edit1.Value="SHA-1(Secure Hash Algorithm 1)是一种广泛使用的密码散列函数"+;
                        ",由美国国家安全局(NSA)设计,并由美国国家标准与技术研究院(NIST)"+;
                        "发布为联邦信息处理标准(FIPS PUB 180-1)。它能够将任意长度的"+;
                        "数据(消息)映射为固定长度(160位/20字节)的哈希值,通常用于数据"+;
                        "完整性校验、数字签名和密码存储等领域。"
    ENDPROC


    PROCEDURE command1.Click
        nhead=4 && 首字符距编辑框的距离
        *ntail=6 && fontname="宋体",fontsize=9的情况下 尾字符距滚动条的距离
        ntail=2 && fontname="雅黑",fontsize=20的情况下 尾字符距滚动条的距离
        nscollbar=21 &&滚动条的宽度
        *!*上面3个数据可能根据编辑框的不同字体会有不同结果
        *!*我的编辑框是宋体,9号字体,普通字体

        *!* 设置不同的字体和大小看看
        thisform.edit1.FontName=("微软雅黑")
        thisform.edit1.FontSize=20
        *!* 
        nwidth=0
        i=0
        cchar=""
        cstr=""
        nevenwidth=FONTMETRIC(6,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
        ctemp=thisform.edit1.Value
        PUBLIC lines
        DIMENSION lines[1]
        nindex=0
        DO WHILE .t. 
            i=i+1
            IF i>LEN(ctemp)
                nindex=nindex+1
                DIMENSION lines[nindex]
                lines[nindex]=ctemp
                EXIT
            ENDIF 
            cchar=SUBSTR(ctemp,i,1)
            IF ASC(cchar)>128
                i=i+1
            ENDIF 
            cstr=SUBSTR(ctemp,1,i)
            nstrwidth=TXTWIDTH(cstr,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
            nwidth=nhead+ntail+nscollbar+nstrwidth*nevenwidth
            IF nwidth>thisform.edit1.Width
        *!*            i=i-1
                IF ASC(cchar)>128
                    i=i-2 &&判断该行最后一个字符为汉字
                ELSE 
                    i=i-1 &&英文字母
                ENDIF
                nindex=nindex+1
                DIMENSION lines[nindex]
                lines[nindex]=SUBSTR(ctemp,1,i)
                ctemp=STRTRAN(ctemp,lines[nindex],"")
                IF EMPTY(ctemp)
                    EXIT
                ELSE 
                    i=0
                    LOOP
                ENDIF          
            ELSE 
                LOOP
            ENDIF 
        ENDDO 
        thisform.text1.Value=LEN(lines[1])
        thisform.text2.Value=ALEN(lines)
    ENDPROC


    PROCEDURE command2.Click
        tnlength=256
        Rand(-1)
        lctext = ''
        i = 0
        Do While i < tnlength
            kb = 48 + Rand() * 80
            If kb <= 57 And kb >= 48 Or kb <= 122 And kb >= 97 Or kb <= 90 And kb >= 65
                i = i + 1
                lctext = lctext + Chr(kb)
            Endif
        Enddo

        thisform.edit1.value=lctext
    ENDPROC


ENDDEFINE
*
*-- EndDefine: form1
**************************************************



[此贴子已经被作者于2025-11-5 21:51编辑过]

搜索更多相关主题的帖子: thisform Top lines Name Left 
2025-11-05 15:52
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
没有考虑到编辑框里可能存在换行符的情况,但是处理方式相同,可以以此类推。
2025-11-05 15:55
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 2楼 sam_jiang
不同的字体及size,会有不同的结果,雅黑就是个另类,大写小写的字符宽度都不一样的
2025-11-05 19:49
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
根据@csyx的反馈,更新command1的click代码如下:
图片附件: 游客没有浏览图片的权限,请 登录注册

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

程序代码:
nhead=4 && 首字符距编辑框的距离
*ntail=6 && fontname="宋体",fontsize=9的情况下 尾字符距滚动条的距离
ntail=2 && fontname="雅黑",fontsize=20的情况下 尾字符距滚动条的距离
nscollbar=21 &&滚动条的宽度
*!*上面3个数据可能根据编辑框的不同字体会有不同结果
*!*我的编辑框是宋体,9号字体,普通字体

*!* 设置不同的字体和大小看看
thisform.edit1.FontName=("微软雅黑")
thisform.edit1.FontSize=20
*!* 
nwidth=0
i=0
cchar=""
cstr=""
nevenwidth=FONTMETRIC(6,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
ctemp=thisform.edit1.Value
PUBLIC lines &&方便在命令窗口查看断行效果是否正确。
DIMENSION lines[1]
nindex=0
DO WHILE .t. 
    i=i+1
    IF i>LEN(ctemp)
        nindex=nindex+1
        DIMENSION lines[nindex]
        lines[nindex]=ctemp
        EXIT
    ENDIF     
    cchar=SUBSTR(ctemp,i,1)
    IF ASC(cchar)>128
        i=i+1
    ENDIF 
    cstr=SUBSTR(ctemp,1,i)
    nstrwidth=TXTWIDTH(cstr,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
    nwidth=nhead+ntail+nscollbar+nstrwidth*nevenwidth
    IF nwidth>thisform.edit1.Width
*!*            i=i-1
        IF ASC(cchar)>128
            i=i-2 &&判断该行最后一个字符为汉字
        ELSE 
            i=i-1 &&英文字母
        ENDIF
        nindex=nindex+1
        DIMENSION lines[nindex]
        lines[nindex]=SUBSTR(ctemp,1,i)
        ctemp=STRTRAN(ctemp,lines[nindex],"")
        IF EMPTY(ctemp)
            EXIT
        ELSE 
            i=0
            LOOP
        ENDIF          
    ELSE 
        LOOP
    ENDIF 
ENDDO 
thisform.text1.Value=LEN(lines[1])
thisform.text2.Value=ALEN(lines)



不知道中文中混有英文单词时的换行规则,仍有bug,但已经接近真相了。。。



[此贴子已经被作者于2025-11-5 21:55编辑过]

2025-11-05 21:42
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 8楼 吹水佬
我猜想当编辑框中字符出现空格时,系统触发英文单词判定,并把单词列入判定换行的依据,以防止英文单词被分割,这个判定延续至双字节系统!有了这个猜想,解决它就不是一个问题了!我这两天完善这个算法试试看
2025-11-07 15:32
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 9楼 wcx_cc
一语惊醒梦中人,豁然开朗,确实模拟人工数行数是最为可行的方法!
2025-11-07 16:02
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 13楼 吹水佬
不要找一行删一行,我数行数是用下箭头键来数的,用home和end键快速定位行首和行尾,这样就简单了,我们只需用selstart属性就可以确定每次敲击下箭头后是否位置已变换,那么有效敲击的次数就是行数!同样利用Home和end键可以确定每行的字数!
2025-11-07 20:46
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 15楼 吹水佬
昨晚试了一下,碰到一个疑难问题。

在编辑框里键盘输入时,selstart的值会变化,用keyboard模拟输入某个键时,它的值居然没有变化!!这是什么原理?
2025-11-08 13:42
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
回复 18楼 吹水佬
单次点击command4,可以看到selstart属性的值变化,
当在command3中打算多次模拟downarrow键时,selstart属性却不再变化了。。。
deepseek 也解释不了。。。

程序代码:
**************************************************
*-- Form:         form1 (d:\documents\visual foxpro 项目\edittest.scx)
*-- 父类:  form
*-- 基类:    form
*-- 时间戳:   11/08/25 11:32:10 PM
*
DEFINE CLASS form1 AS form


    Top = 0
    Left = 0
    Height = 559
    Width = 712
    DoCreate = .T.
    Caption = "Form1"
    *-- 记录edit控件的文字行数
    lines = 0
    Name = "Form1"


    ADD OBJECT edit1 AS editbox WITH ;
        Height = 552, ;
        Left = 0, ;
        Top = 0, ;
        Width = 421, ;
        Name = "Edit1"


    ADD OBJECT text1 AS textbox WITH ;
        Height = 20, ;
        Left = 509, ;
        Top = 12, ;
        Width = 100, ;
        Name = "Text1"


    ADD OBJECT text2 AS textbox WITH ;
        Height = 20, ;
        Left = 509, ;
        Top = 48, ;
        Width = 100, ;
        Name = "Text2"


    ADD OBJECT command1 AS commandbutton WITH ;
        AutoSize = .T., ;
        Top = 96, ;
        Left = 552, ;
        Height = 25, ;
        Width = 84, ;
        Caption = "计算字数与行", ;
        Name = "Command1"


    ADD OBJECT label1 AS label WITH ;
        AutoSize = .T., ;
        Caption = "每行字数:", ;
        Height = 16, ;
        Left = 432, ;
        Top = 16, ;
        Width = 62, ;
        Name = "Label1"


    ADD OBJECT label2 AS label WITH ;
        Caption = "行数:", ;
        Height = 16, ;
        Left = 434, ;
        Top = 50, ;
        Width = 38, ;
        Name = "Label2"


    ADD OBJECT command2 AS commandbutton WITH ;
        AutoSize = .T., ;
        Top = 144, ;
        Left = 480, ;
        Height = 25, ;
        Width = 156, ;
        Caption = "生成一串随机字符再次测试", ;
        Name = "Command2"


    ADD OBJECT command3 AS commandbutton WITH ;
        AutoSize = .T., ;
        Top = 216, ;
        Left = 504, ;
        Height = 25, ;
        Width = 132, ;
        Caption = "模拟键盘操作获取行数", ;
        Name = "Command3"


    ADD OBJECT command4 AS commandbutton WITH ;
        Top = 252, ;
        Left = 504, ;
        Height = 25, ;
        Width = 60, ;
        Caption = "DNarrow", ;
        Name = "Command4"


    PROCEDURE Init
        this.edit1.Value="SHA-1(Secure Hash Algorithm 1)是一种广泛使用的密码散列函数"+;
                        ",由美国国家安全局(NSA)设计,并由美国国家标准与技术研究院(NIST)"+;
                        "发布为联邦信息处理标准(FIPS PUB 180-1)。它能够将任意长度的"+;
                        "数据(消息)映射为固定长度(160位/20字节)的哈希值,通常用于数据"+;
                        "完整性校验、数字签名和密码存储等领域。"
    ENDPROC


    PROCEDURE edit1.Click
        NODEFAULT 
        npos=thisform.lines
        KEYBOARD '{DNARROW}'
        INKEY(0.1)
        MESSAGEBOX(trans(thisform.lines))
        DODEFAULT()
    ENDPROC


    PROCEDURE edit1.KeyPress
        LPARAMETERS nKeyCode, nShiftAltCtrl
        IF nkeycode=24
            npos=this.SelStart
            INKEY(0.1)
            *MESSAGEBOX("npos= "+TRANSFORM(npos)+CHR(13)+"totallength= "+TRANSFORM(len(this.value)))
            IF npos#LEN(this.Value)
                thisform.Lines=thisform.lines+1
                *SET MESSAGE TO TRANSFORM(thisform.lines)
                MESSAGEBOX(TRANSFORM(thisform.lines))
            ENDIF
        ENDIF 
    ENDPROC


    PROCEDURE text1.KeyPress
        LPARAMETERS nKeyCode, nShiftAltCtrl
        IF TYPE("npos")="U"
            PUBLIC npos
        ENDIF 
        npos=this.selstart
        SET MESSAGE TO TRANSFORM(npos)
    ENDPROC


    PROCEDURE command1.Click
        nhead=4 && 首字符距编辑框的距离
        *ntail=6 && fontname="宋体",fontsize=9的情况下 尾字符距滚动条的距离
        ntail=2 && fontname="雅黑",fontsize=20的情况下 尾字符距滚动条的距离
        nscollbar=21 &&滚动条的宽度
        *!*上面3个数据可能根据编辑框的不同字体会有不同结果
        *!*我的编辑框是宋体,9号字体,普通字体

        *!* 设置不同的字体和大小看看
        thisform.edit1.FontName=("微软雅黑")
        thisform.edit1.FontSize=20
        *!* 
        nwidth=0
        i=0
        cchar=""
        cstr=""
        nevenwidth=FONTMETRIC(6,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
        ctemp=thisform.edit1.Value
        PUBLIC lines
        DIMENSION lines[1]
        nindex=0
        DO WHILE .t. 
            i=i+1
            IF i>LEN(ctemp)
                nindex=nindex+1
                DIMENSION lines[nindex]
                lines[nindex]=ctemp
                EXIT
            ENDIF 
            cchar=SUBSTR(ctemp,i,1)
            IF ASC(cchar)>128
                i=i+1
            ENDIF 
            cstr=SUBSTR(ctemp,1,i)
            nstrwidth=TXTWIDTH(cstr,thisform.edit1.FontName,thisform.edit1.FontSize,"N")
            nwidth=nhead+ntail+nscollbar+nstrwidth*nevenwidth
            IF nwidth>thisform.edit1.Width
        *!*            i=i-1
                IF ASC(cchar)>128
                    i=i-2 &&判断该行最后一个字符为汉字
                ELSE 
                    i=i-1 &&英文字母
                ENDIF
                nindex=nindex+1
                DIMENSION lines[nindex]
                lines[nindex]=SUBSTR(ctemp,1,i)
                ctemp=STRTRAN(ctemp,lines[nindex],"")
                IF EMPTY(ctemp)
                    EXIT
                ELSE 
                    i=0
                    LOOP
                ENDIF          
            ELSE 
                LOOP
            ENDIF 
        ENDDO 
        thisform.text1.Value=LEN(lines[1])
        thisform.text2.Value=ALEN(lines)
    ENDPROC


    PROCEDURE command2.Click
        tnlength=256
        Rand(-1)
        lctext = ''
        i = 0
        Do While i < tnlength
            kb = 48 + Rand() * 80
            If kb <= 57 And kb >= 48 Or kb <= 122 And kb >= 97 Or kb <= 90 And kb >= 65
                i = i + 1
                lctext = lctext + Chr(kb)
            Endif
        Enddo

        thisform.edit1.value=lctext
    ENDPROC


    PROCEDURE command3.Click
        nlines=thisform.lines
        thisform.edit1.SetFocus()

        DO WHILE .t. 

            KEYBOARD '{DNARROW}'
            *thisform.edit1.KeyPress(24)
            MESSAGEBOX(TRANSFORM(thisform.lines))
            IF thisform.lines=nlines
                thisform.text1.Value=thisform.lines
                thisform.lines=0
                EXIT 
            ELSE 
                nlines=thisform.lines
                INKEY(0.2)
                thisform.edit1.SetFocus()
                loop
            ENDIF 
        ENDDO 
    ENDPROC


    PROCEDURE command4.Click
        thisform.edit1.SetFocus()
        KEYBOARD '{DNARROW}'
    ENDPROC


ENDDEFINE
*
*-- EndDefine: form1
**************************************************
2025-11-08 23:56
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1069
专家分:1660
注 册:2021-10-13
收藏
得分:0 
这个问题已经解决,参考@easyppt的那篇文章 https://bbs. 12楼

只是行数,不带考虑每行的文字,可以稍微快点。

让deepseek给我详细注释一下我的代码,可读性更强了。

deepseek评价:
代码功能分析
‌主要功能‌:通过模拟键盘操作和光标位置检测,精确计算编辑框控件中的文本行数。
...
...
代码特点
可靠性‌:通过实际的光标移动来检测行数,避免文本换行等复杂情况的干扰
稳定性‌:使用Sleep函数确保键盘操作完全执行
实用性‌:适用于各种文本内容的行数统计需求
这段代码在处理多行文本编辑框的行数统计方面具有很好的实用价值。

程序代码:

DECLARE integer Sleep IN WIN32API integer

* 定义局部变量
Local nstartpos, npos, nrows
Local oedit as EditBox  * 定义编辑框引用

* 获取编辑框控件引用
oedit = Thisform.edit1 

* 设置焦点到编辑框
oedit.SetFocus()  

* 模拟键盘按下Ctrl[color=#808080]+Home,将光标移动到文本开头[/color]
Keyboard '{CTRL+HOME}' 
* 处理事件,确保键盘操作完成
Doevents 
sleep(600)
* 记录当前光标位置作为起始位置
nstartpos = oedit.SelStart 

* 初始化行计数器
nrows = 1  

* 开始循环计算行数
Do while .t. 

    Keyboard '{DNARROW}' 
    * 处理事件
    Doevents 
    sleep(600)    
    * 记录新的光标位置
    npos = oedit.SelStart 
    
    * 判断是否到达文本末尾(位置没有变化)
    If nstartpos = npos 
        * 如果位置没有变化,说明已到达最后一行,退出循环
        nrows=nrows-1
        Exit 
    Else 
        * 否则更新起始位置为新的行首
        nstartpos = npos 
        * 行计数器加1
        nrows = nrows + 1 
    EndIf 
EndDo 

* 模拟键盘按下Ctrl[color=#808080]+Home,将光标重新移动到文本开头[/color]
Keyboard '{CTRL+HOME}' 

* 将最终行数赋给外部参数
thisform.text1.value = nrows


[此贴子已经被作者于2025-11-11 11:39编辑过]

2025-11-11 11:25
快速回复:如何获得edit框的行数问题
数据加载中...
 
   



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

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