注册 登录
编程论坛 VFP论坛

请教编辑框自动通过改变字号显示全部文字,不出现滚动条,如何实现?辛苦老师给段代码

wxzd123 发布于 2025-05-13 19:39, 1080 次点击
有几个自然段文字,用编辑框来显示,要全部显示则可视编辑框内不出现滚动条,字号尽量大,如何用代码实现?请老师执教,谢谢
18 回复
#2
wxzd1232025-05-13 20:08
请教能返回一共有多少行吗
#3
wcx_cc2025-05-13 23:02
这种情况,是不是说:根据编辑框的尺寸大小,无论文章字数有多少,都要填满整个编辑框,这实际上就是总字数决定了字号,每行的字数和总行数。好像首先必须从手工测试开始,多次测试后总结结果,然后再考虑代码吧!
#4
sam_jiang2025-05-14 01:14
鍥炲 2妤
aline
#5
wxzd1232025-05-14 05:51
回复 4楼 sam_jiang
老师您好,是用ALINES( ) 函数函数吗,这个没用过,这样写对面
nLineCount = ALINES(laLines, Thisform.Edit1.Value)
MESSAGEBOX("编辑框中共有 " + ALLTRIM(STR(nLineCount)) + " 行文本。")
只有本站会员才能查看附件,请 登录
#6
sam_jiang2025-05-14 20:24
回复 5楼 wxzd123
程序代码:

LOCAL ARRAY laLines[1]
nLineCount = ALINES(laLines, Thisform.Edit1.Value) &&wordwrap属性会影响这个值

* 显示总行数
MESSAGEBOX("总行数: " + TRANSFORM(nLineCount))

* 显示每行长度
FOR i = 1 TO nLineCount
    ? "第 " + TRANSFORM(i) + " 行长度: " + TRANSFORM(LEN(laLines[i]))
ENDFOR

如果不能运行,你尝试一下,memlines(),mline(),atline()等函数在试试看

integralheight属性 .t. 可以动态改变edit控件的高度,你也试试看。

 
#7
csyx2025-05-16 19:29
建议改用 Forms.TextBox 替换 vfp.EditBox,Forms.TextBox 提供的 LintCount 属性,就是你需要的自动换行后总行数。
另外,vfp 编辑框的自动换行算法与 windows 标准编辑框换行算法有少许不同,如果你将一段文字分别赋值给 vfp.editbox 和 Forms.TextBox,你会看到 Forms.TextBox 的换行算法更符合公文的行文规范,例如:vfp 经常会把标点符号放在新行的首位,遇到E文单词时,明明后面还有足够空间它也会另起一行。。。同时,这也导致无法利用 win32api 函数精确计算出自动换行后的绘制矩形高度,如果夹杂的E文不多到也近似可用
待我抽空从老代码中简化出一个函数供你参考

[此贴子已经被作者于2025-5-16 19:32编辑过]

#8
wxzd1232025-05-17 05:49
谢谢两位老师的帮助,知道行数也不能准确调整字号大小,只能大体调整。Forms.TextBox不能实现背景透明。
#9
csyx2025-05-17 08:53
示例中也演示了 vfp 与 windows 自动换行的差别,也就解释了为何无法精确计算出 vfp.editbox 最佳字体大小的原因,如果换成 Forms.TextBox,换行规则一致就可精确计算。
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2025-5-17 08:58编辑过]

#10
wxzd1232025-05-17 10:44
谢谢csyx老师,学习一下,有不明白的在请教
#11
hsfisher2025-05-18 12:56
#12
吹水佬2025-11-02 23:13
回复 9楼 csyx
如果只是显示用也可以不用editbox,直接用form就无需转来转去,且可以使用Unicode。

只有本站会员才能查看附件,请 登录

可以测试一下

程序代码:

DECLARE long GetDC          IN user32 long
DECLARE long ReleaseDC      IN user32 long,long
DECLARE long DrawTextExW    IN user32 long,long,long,string,long,string@
DECLARE long SetParent      IN user32 long,long
DECLARE long PostMessageA   IN user32 long,long,long,long

DECLARE long wcscpy IN msvcrt long,string
DECLARE long wcslen IN msvcrt long
DECLARE long malloc IN msvcrt long
DECLARE long free   IN msvcrt as freebuffer long

#define MY_MESSAGE                 0x0401
#define DT_WORDBREAK               0x00000010
#define DT_EXPANDTABS              0x00000040
#define DT_TABSTOP                 0x00000080
#define DT_NOCLIP                  0x00000100
#define DT_EXTERNALLEADING         0x00000200
#define DT_CALCRECT                0x00000400
#define DT_NOPREFIX                0x00000800
#define DT_EDITCONTROL             0x00002000
#define DT_NOFULLWIDTHCHARBREAK    0x00080000

cText = '  在 Visual FoxPro(VFP) 中,AutoYield 属性用于控制程序在执行代码时' ;
      + '是否允许处理 Windows 事件(如鼠标点击、键盘输入等)。默认情况下,' ;
      + 'AutoYield 是开启的(.T.),这意味着VFP会在代码执行期间定期处理事件。';
      + 0h0d0a0d0a ;
      + '  DrawTextEx 是一个在 Windows 图形设备接口(GDI)中用于绘制复杂文本的函数。' ;
      + '它提供了多种文本格式化选项,如文字换行、字体选择、对齐方式等,' ;
      + '允许开发者精确控制文本在屏幕或打印输出上的显示效果。'+0h00

cText = STRCONV(cText, 5)

    * 如果不想保持数字号码或字母单词的完整性,这样右边界会较整齐点。
    * 使用 DT_NOFULLWIDTHCHARBREAK 格式防止遇到数字号码或字母单词后空格(单词分隔符)自动换行。
    * 使用 DT_NOFULLWIDTHCHARBREAK 格式时当遇到半角空格(U+0020)、制表符(U+0009)时会自动换行,
    * 此时,要将半角空格(U+0020)、制表符(U+0009)替换为全角空格(U+00A0)。
cText = STRTRAN(cText, 0h2000, 0hA000)
cText = STRTRAN(cText, 0h0900, REPLICATE(0hA000,4))

pText = malloc(LEN(cText))
wcscpy(pText, cText)

of = CREATEOBJECT("form1")
of.show(1)
freebuffer(pText)
CLEAR ALL
RETURN

DEFINE CLASS form1 as Form
    width = 500
    height = 330
    minwidth = 200
    minheight = 200
    AutoCenter  = .t.
    AllowOutput = .f.
   
    oChild       = 0
    leftMargin   = 0
    topMargin    = 0
    rightMargin  = 0
    bottomMargin = 0
    cFontStyle   = "N"
   
    ADD OBJECT combo1  as combobox      WITH left=10, top=10,width=200,height=24,Style=2
    ADD OBJECT button1 as commandbutton WITH left=220,top=10,width=100,height=24,caption="SetFont"
        
    PROCEDURE init
        BINDEVENT(this.hWnd, MY_MESSAGE, this, "msgPaint")
        this.oChild = CREATEOBJECT("formChild", 10, 50, 400, 200, 3, 8, this)
        SetParent(this.oChild.hWnd, this.hWnd)
        this.leftMargin   = this.oChild.Left - this.Left
        this.topMargin    = this.oChild.Top  - this.Top
        this.rightMargin  = this.Left+this.Width  - this.oChild.left - this.oChild.width
        this.bottomMargin = this.Top +this.Height - this.oChild.Top  - this.oChild.Height
        this.oChild.show
    ENDPROC
   
    PROCEDURE ReSize
        this.oChild.width  = this.Width  - this.leftMargin - this.rightMargin
        this.oChild.height = this.Height - this.topMargin  - this.bottomMargin
        PostMessageA(this.hWnd, MY_MESSAGE, 0, 0)
    ENDPROC
   
    PROCEDURE Destroy
        UNBINDEVENTS(this.hWnd)
    ENDPROC
   
    PROCEDURE combo1.init
        AFONT(arr)
        FOR i=1 TO ALEN(arr)
            this.AddItem(arr[i])
        ENDFOR
        this.value = "宋体"
    ENDPROC
   
    PROCEDURE combo1.InteractiveChange
        thisform.oChild.fontname = ALLTRIM()
        PostMessageA(thisform.hWnd, MY_MESSAGE, 0, 0)
    ENDPROC
   
    PROCEDURE button1.click
        IF ALINES(arr,GETFONT(thisform.oChild.fontname,thisform.oChild.fontsize,thisform.cFontStyle),5,",") == 3
            thisform.oChild.FontName   = arr[1]
            thisform.oChild.FontBold   = IIF(INLIST(arr[3],"B","BI"), .t., .f.)
            thisform.oChild.FontItalic = IIF(INLIST(arr[3],"I","BI"), .t., .f.)
             = arr[1]
            thisform.cFontStyle   = arr[3]
            PostMessageA(thisform.hWnd, MY_MESSAGE, 0, 0)
        ENDIF  
    ENDPROC
   
    FUNCTION msgPaint(hWnd, uMsg, wParam, lParam)
        this.oChild.cls    && 会触发paint事件重绘
    ENDPROC
ENDDEFINE

DEFINE CLASS formChild as Form
    Backcolor   = 0x00FFFFFF
    BorderStyle = 1
    TitleBar    = 0
    FontName    = "宋体"
    AllowOutput = .f.
   
    margin      = 0
    minFontSize = 8
    oParent     = 0
    hdc         = 0
    fmtDrawn    = BITOR(DT_EDITCONTROL,DT_EXPANDTABS,DT_EXTERNALLEADING,DT_NOCLIP,;
                        DT_NOPREFIX,DT_TABSTOP,DT_WORDBREAK,DT_NOFULLWIDTHCHARBREAK)
    fmtNotDrawn = BITOR(this.fmtDrawn, DT_CALCRECT)
   
    PROCEDURE Destroy
        ReleaseDC(this.hWnd, this.hdc)
    ENDPROC
   
    PROCEDURE init(nLeft, nTop, nWidth, nHeight, nMargin, nMinFontSize, oParent)
        this.Left        = nLeft
        this.Top         = nTop
        this.Width       = nWidth
        this.Height      = nHeight
        this.margin      = nMargin
        this.minFontSize = nMinFontSize
        this.oParent     = oParent
        this.hdc         = GetDC(this.hWnd)
    ENDPROC
   
    PROCEDURE paint
        this. = .f.
        this.oParent.button1.Enabled = .f.
        rec = BINTOC(this.margin,"4rs")+BINTOC(this.margin,"4rs")+BINTOC(this.width-this.margin,"4rs")+BINTOC(this.height-this.margin,"4rs")
        nDrawnHeight = this.height - this.margin*2
        this.FontSize = this.minFontSize
        DO WHILE (this.FontSize < 128) AND (nDrawnHeight >= DrawTextExW(this.hdc, pText, -1, rec, this.fmtNotDrawn, NULL))
            this.oParent.caption = " 稍候... FontSize: "+TRANSFORM(this.FontSize)
            this.FontSize = this.FontSize + 1
        ENDDO
        this.FontSize = this.FontSize - 1
        this.oParent.caption = " FontSize: "+TRANSFORM(this.FontSize)
        DrawTextExW(this.hdc, pText, -1, rec, this.fmtDrawn, NULL)
        this. = .t.
        this.oParent.button1.Enabled = .t.
    ENDPROC
ENDDEFINE

使用 DT_NOFULLWIDTHCHARBREAK 格式防止遇到数字号码、字母单词后空格(单词分隔符)自动换行的问题?



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

#13
schtg2025-11-03 05:24
回复 12楼 吹水佬
学习啦,谢谢!
#14
吹水佬2025-11-03 08:50
12楼修复缩放问题
#15
吹水佬2025-11-03 23:44
12楼修复窗口最大化、最小化缩放重新绘制问题
#16
吹水佬2025-11-04 16:28
code标签贴代码也会出现乱码?
改了一下重新补贴上
#17
吹水佬2025-11-05 22:30
12楼代码探讨一下:
如果不想保持数字号码或字母单词的完整性,使用 DT_NOFULLWIDTHCHARBREAK 格式防止遇到数字号码、字母单词后空格(单词分隔符)自动换行的问题?
#18
sych2025-11-06 11:06
每天来群里转一圈,天天有收获,谢谢吹版付出
#19
wxzd1232025-11-06 12:38
给吹版点赞
1