如何在Delphi的TMemo控件中添加行分隔线?
Delphi TMemo 行间添加实线的实现方案
TMemo控件本身没有内置的行分隔线属性,不过可以通过两种常用方式实现需求:
方法一:启用OwnerDraw自绘模式
通过设置OwnerDraw为True,重写OnDrawItem事件自定义每行的绘制逻辑,包括添加底线。
步骤与代码示例:
- 将TMemo的
OwnerDraw属性设置为True - 为
OnDrawItem事件添加如下处理代码:
procedure TForm1.Memo1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var Memo: TMemo; LineText: string; TextRect: TRect; begin Memo := Control as TMemo; LineText := Memo.Lines[Index]; // 绘制行背景与文本(模拟默认样式) TextRect := Rect; InflateRect(TextRect, -2, 0); // 调整文本内边距 Memo.Canvas.Font := Memo.Font; // 处理选中状态 if odSelected in State then begin Memo.Canvas.Brush.Color := clHighlight; Memo.Canvas.Font.Color := clHighlightText; end else begin Memo.Canvas.Brush.Color := Memo.Color; Memo.Canvas.Font.Color := Memo.Font.Color; end; Memo.Canvas.FillRect(Rect); DrawText(Memo.Canvas.Handle, PChar(LineText), Length(LineText), TextRect, DT_LEFT or DT_VCENTER or DT_SINGLELINE); // 绘制行分隔实线 Memo.Canvas.Pen.Color := clGray; // 可自定义线条颜色 Memo.Canvas.MoveTo(Rect.Left, Rect.Bottom - 1); Memo.Canvas.LineTo(Rect.Right, Rect.Bottom - 1); end;
注意点:
- 自绘模式下需要自行处理选中、焦点等状态的样式
- 可通过
Pen.Width调整线条粗细,按需修改颜色参数
方法二:拦截WM_PAINT消息后追加绘制
如果不想完全接管自绘,可以通过继承TMemo并重写WM_PAINT消息,在默认绘制完成后追加线条。
代码示例:
type TMemoWithDividers = class(TMemo) protected procedure WMPaint(var Message: TWMPaint); message WM_PAINT; end; procedure TMemoWithDividers.WMPaint(var Message: TWMPaint); var DC: HDC; PS: TPaintStruct; I: Integer; LineTop, LineHeight: Integer; ClientRect: TRect; begin inherited; // 先执行默认绘制逻辑 DC := BeginPaint(Handle, PS); try GetClientRect(Handle, ClientRect); LineHeight := Canvas.TextHeight('X'); // 基于字体计算行高 for I := 0 to Lines.Count - 1 do begin // 计算当前行底部位置 LineTop := ClientRect.Top + (I + 1) * LineHeight; // 绘制横向实线 MoveToEx(DC, ClientRect.Left, LineTop - 1, nil); LineTo(DC, ClientRect.Right, LineTop - 1); end; finally EndPaint(Handle, PS); end; end;
注意点:
- 这种方式更贴近原生TMemo的表现,但行高计算需考虑字体、行距等因素
- 若Memo存在滚动条,需额外处理可见区域的线条绘制,避免无效绘制
内容的提问来源于stack exchange,提问作者Fionn MacHugh
相关产品推荐
相关产品推荐

