| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 663 人关注过本帖
标题:RichTextbox控件如何根据自身宽、高,以及用户设定的字体、字号和行距,计算 ...
只看楼主 加入收藏
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:420
专家分:648
注 册:2019-10-11
收藏
得分:0 
EM_POSFROMCHAR(&HD6或&H426)这个消息是否可以实现
取得指定字符偏移的显示位置行列号,行列是按编辑控件的客户区左上角为原点(0,0)计算的。字符偏移是相对于文本头部的偏移。

EM_CHARFROMPOS(&HD7=215),0, //取得编辑控件中指定位置的字符相对于文本头部的偏移量。使用本操作应先在第4个参数的高16位指定行号,低16位指定列号(或一个POINTAPI结构),行列是按编辑控件的客户区左上角为原点(0,0)计算的。如果指定的位置超出控件客户区则返回-1

[此贴子已经被作者于2025-9-3 15:21编辑过]

3 天前 15:19
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10698
专家分:43295
注 册:2014-5-20
收藏
得分:0 
官方参考:https://learn.
3 天前 15:20
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10698
专家分:43295
注 册:2014-5-20
收藏
得分:0 
以下是引用cssnet在2025-9-3 11:11:31的发言:



不太清楚。我让DC猜测这个“校正参数”,我设置行距 lnlineSpacing = 行高的1.5倍,它给出的调整建议:


初始值:从 lc校正参数 = 0.08 开始测试
根据行间距调整:
1.0倍行距:校正参数 ≈ 0.04-0.06
1.5倍行距:校正参数 ≈ 0.08-0.12
2.0倍行距:校正参数 ≈ 0.12-0.16
根据字体大小调整:
小字体(8-10pt):减少校正参数
大字体(12-14pt+):增加校正参数

最终公式:
lnLinesPerPage = INT(thisform.RichTextBox1.Height / lnFontHeight / ;
                  (lnlineSpacing - (0.08 + (lnlineSpacing - 1) * 0.06)))


然而,结果并不理想。

获取RichEdit字体对象句柄代码中有个转换函数:
MulDiv(cf.yHeight / 20, 96, 72)
就是(cf.yHeight / 20) * 96 / 72

程序代码:
DLLIMPORT_C HFONT GetRichEditFontHandle(HWND hRichEdit)
{
    CHARFORMAT cf;
    ZeroMemory(&cf, sizeof(CHARFORMAT));
    cf.cbSize = sizeof(CHARFORMAT);

    // 获取当前选择文本的字符格式
    SendMessage(hRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);

    // 从CHARFORMAT创建字体对象
    return CreateFont(
        -MulDiv(cf.yHeight / 20, 96, 72), // 转换单位
        0, 0, 0,
        (cf.dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL,
        (cf.dwEffects & CFE_ITALIC) ? TRUE : FALSE,
        (cf.dwEffects & CFE_UNDERLINE) ? TRUE : FALSE,
        (cf.dwEffects & CFE_STRIKEOUT) ? TRUE : FALSE,
        DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS,
        DEFAULT_QUALITY,
        DEFAULT_PITCH | FF_DONTCARE,
        cf.szFaceName
    );
}
3 天前 15:26
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:420
专家分:648
注 册:2019-10-11
收藏
得分:0 
获取行数,如果最后一行没有完整显示,则不计算在内
Declare INTEGER SendMessage in WIN32API as sendmessage_n INTEGER hwnd , INTEGER wMsg , INTEGER wParam , integer lParam
#defi EM_GETFIRSTVISIBLELINE 0XCE
#defi EM_LINEINDEX  0xbb
#defi EM_POSFROMCHAR  0xd6
iFirstLine = SendMessage_n(thisform.Olecontrol5.hwnd, EM_GETFIRSTVISIBLELINE,0,0)
FOR i=0 TO 100
    cpFirst = SendMessage_n(thisform.Olecontrol5.hwnd,EM_LINEINDEX,iFirstLine+i,0)
    aa=SendMessage_n(thisform.Olecontrol5.hwnd, EM_POSFROMCHAR,cpFirst,0)
    aa=BITrSHIFT(aa,16)
    IF i>0
        IF aa=1
            EXIT
        endif
        IF aa>thisform.Olecontrol5.Height
            i=iif(aa>thisform.Olecontrol5.Height+5,i-1,i)  &&判断上一行是否完整显示,这个5是预估值,也可以用获取的行间距
            EXIT
        endif
    ENDIF
next
MESSAGEBOX(i)
retu


[此贴子已经被作者于2025-9-3 18:03编辑过]

3 天前 17:12
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:489
专家分:372
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2025-9-3 13:55:00的发言:
与.gov的无关吧


搞笑搞笑,贴错了网址,应该是这一个的:

https://bbs.bc-cn.net/viewthread.php?tid=508544&page=1#pid2758685



3 天前 17:34
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:489
专家分:372
注 册:2013-10-4
收藏
得分:0 
以下是引用sych在2025-9-3 17:12:05的发言:

获取行数,如果最后一行没有完整显示,则不计算在内
Declare INTEGER SendMessage in WIN32API as sendmessage_n INTEGER hwnd , INTEGER wMsg , INTEGER wParam , integer lParam
#defi EM_GETFIRSTVISIBLELINE 0XCE
#defi EM_LINEINDEX  0xbb
#defi EM_POSFROMCHAR  0xd6
iFirstLine = SendMessage_n(thisform.Olecontrol5.hwnd, EM_GETFIRSTVISIBLELINE,0,0)
lh=0
lt=0
FOR i=0 TO 100
    cpFirst = SendMessage_n(thisform.Olecontrol5.hwnd,EM_LINEINDEX,iFirstLine+i,0)
    aa=SendMessage_n(thisform.Olecontrol5.hwnd, EM_POSFROMCHAR,cpFirst,0)
    aa=BITrSHIFT(aa,16)
    IF i>0
        IF aa=1
            i=i-1
            EXIT
        endif
        lh=MAX(aa-lt,lh)
        IF lh+aa>thisform.Olecontrol5.Height
            EXIT
        endif
    ENDIF
    lt=aa
next
MESSAGEBOX(i)
retu


太牛B了!英雄!
3 天前 17:35
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:420
专家分:648
注 册:2019-10-11
收藏
得分:0 
又修改了一下
3 天前 17:58
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:489
专家分:372
注 册:2013-10-4
收藏
得分:0 
实战的话,其实是有一点点尴尬的:
必须填满Richtextbox1一整屏后,才能够得到正确的行、列结果。
表单初始化时,倘若客户区空白,那么只能返回0列和1行。
倒是可以设置visible = .F. 或 LockScreen = .T.,
先用垃圾将客户区填满,得到行、列值,然后再恢复现场。
不过,拖动改变表单大小,特别是拉大表单,导致Richtextbox客户区不再被填满,那么也将得到小于实际值的行的结果。

当然,解决方案也有,就是浪费一点资源:
复制一个一毛一样的Richtextbox2,
并设置Richtextbox2.left = - Richtextbox2.width - 10,再用垃圾将它填满。
计算行、列值,就用Richtextbox2;而真正用,则是Richtextbox1。

话说,我老人家是不是冰雪聪明来着?
3 天前 21:44
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:420
专家分:648
注 册:2019-10-11
收藏
得分:0 
你这是量子纠缠,牛逼plus
3 天前 21:49
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:420
专家分:648
注 册:2019-10-11
收藏
得分:0 
顺着你的思路走,可以用半角或者全角空格填满,再获取行列值,是不是可以省掉一个2
前天 06:05
快速回复:RichTextbox控件如何根据自身宽、高,以及用户设定的字体、字号和行距 ...
数据加载中...
 
   



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

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