惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
F
Fortinet All Blogs
爱范儿
爱范儿
博客园 - Franky
MyScale Blog
MyScale Blog
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
P
Proofpoint News Feed
IT之家
IT之家
宝玉的分享
宝玉的分享
D
DataBreaches.Net
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
M
MIT News - Artificial intelligence
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
量子位
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

博客园 - 涂磊

TMS可以单独安装控件 02]AdvStringGrid中添加CheckBox 01]TMSadvStringGrid下载与安装 epson投影仪提示,保存时间的电池电量偏低,取消显示 用DeepSeek做的Delphi闹钟 XboxS联网下载完游戏后,要拔掉网线,就能玩游戏了 12]RichEdit某些文本突出显示 delphi的TReeView支持鼠标拖动节点 cnPack里MarkDown里RTF显示 11]delphi中 RichEdit1设置行距 10]RichEdit另存 为BMP图片 09]delphi中richedit查找 08]delphi10.3剪贴板的图片,保存到文件 07]Delphi10.3中Richedit中的链接可以点击 06]delphi10.3中richedit中文本背景颜色 05]delphi10.3中richedit中删除线 delphi10.3中UpDown1使用 04]RichEdit的上标和下标,Delphi10.3 03]RichEdit插入BMP图片 delphi 中tButtonColor颜色选择 02]如何设置RichEdit文本颜色?_编程语言-CSDN问答 01]delphi从TRichEdit获得RTF格式文本(PC版本) Delphi10.3接收从文件管理器拖放过来的文件名
delphi10.3中Tmemo中某些文本显示下划线
涂磊 · 2026-03-14 · via 博客园 - 涂磊
type
  TMemo = class(vcl.stdctrls.TMemo)
  private
    FStartChar, FEndChar: Integer;
    procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
  public
    procedure Underline(StartLine, StartChar, EndLine, EndChar: Integer);
  end;
{ TMemo }////////////////////////
procedure TMemo.Underline(StartLine, StartChar, EndLine, EndChar: Integer);
begin
  FStartChar := SendMessage(Handle, EM_LINEINDEX, StartLine, 0) + StartChar;
  FEndChar := SendMessage(Handle, EM_LINEINDEX, EndLine, 0) + EndChar;
  Invalidate;
end;

procedure TMemo.WMPaint(var Msg: TWMPaint);

  function GetLine(CharPos: Integer): Integer;
  begin
    Result := SendMessage(Handle, EM_LINEFROMCHAR, CharPos, 0);
  end;

  procedure DrawLine(First, Last: Integer);
  var
    LineHeight: Integer;
    Pt1, Pt2: TSmallPoint;
    DC: HDC;
    Rect: TRect;
    ClipRgn: HRGN;
  begin
    // font height approximation (compensate 1px for internal leading)
    LineHeight := Abs(Font.Height) - Abs(Font.Height) div Font.Height+3;  //3为 下划线的高度

    // get logical top-left coordinates for line bound characters
    Integer(Pt1) := SendMessage(Handle, EM_POSFROMCHAR, First, 0);
    Integer(Pt2) := SendMessage(Handle, EM_POSFROMCHAR, Last, 0);

    DC := GetDC(Handle);

    // clip to not to draw to non-text area (internal margins)
    SendMessage(Handle, EM_GETRECT, 0, Integer(@Rect));
    ClipRgn := CreateRectRgn(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
    SelectClipRgn(DC, ClipRgn);
    DeleteObject(ClipRgn); // done with region

    // set pen color to red and draw line
    SelectObject(DC, GetStockObject(DC_PEN));
   // SetDCPenColor(DC, RGB(255, 0 ,0));
    SelectObject(DC, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)) );  //3 为厚度,255为红色

    MoveToEx(DC, Pt1.x, Pt1.y + LineHeight, nil);
    LineTo(DC, Pt2.x, Pt2.y + LineHeight);

    ReleaseDC(Handle, DC); // done with dc
  end;

var
  StartChar, CharPos, LinePos: Integer;
begin
  inherited;
  if FEndChar > FStartChar then begin

    // Find out where to draw.
    // Can probably optimized a bit by using EM_LINELENGTH
    StartChar := FStartChar;
    CharPos := StartChar;
    LinePos := GetLine(CharPos);
    while True do begin
      Inc(CharPos);
      if GetLine(CharPos) > LinePos then begin
        DrawLine(StartChar, CharPos - 1);
        StartChar := CharPos;
        Dec(CharPos);
        Inc(LinePos);
        Continue;
      end else
        if CharPos >= FEndChar then begin
          DrawLine(StartChar, FEndChar);
          Break;
        end;
    end;
  end;
end;
{  --end TMemo-- } 
procedure TForm2.Button1Click(Sender: TObject);
begin
 Memo1.Underline(7, 14, 8, 17);
end;

image