我想在TMemo
控件中突出显示包含插入符号的行,类似于Delphi IDE中的编辑器。我尝试了以下代码,它有点工作:
(抱歉With语句,这需要重构。)
procedure TMemo.WMPaint(var Message: TWMPaint);
var
PS: TPaintStruct;
DC: Hdc;
Canvas: TCanvas;
LineIdx: Integer;
X, Y: Integer;
Max: Integer;
s: string;
h: Integer;
begin
DC := Message.DC;
if DC = 0 then
DC := BeginPaint(Handle, PS);
Canvas := TCanvas.Create;
try
Canvas.Handle := DC;
Canvas.Font.Name := Font.Name;
Canvas.Font.Size := Font.Size;
with Canvas do begin
Max := TopLine + VisibleLines;
if Max > Pred(Lines.Count) then
Max := Pred(Lines.Count);
Brush.Color := Self.Color;
FillRect(Self.ClientRect);
Brush.Color := clYellow;
h := Canvas.TextHeight('Mg');
Y := (Line - TopLine) * h;
Marker.Top := y + self.Top;
FillRect(Rect(0, Y, ClientRect.Right, Y + h));
Brush.Color := Self.Color;
Y := 1;
for LineIdx := TopLine to Max do begin
X := 2;
s := Lines[LineIdx];
if LineIdx = Line then
Brush.Color := clYellow
else
Brush.Color := Self.Color;
TextOut(X, Y, s);
Inc(Y, h);
end;
end;
finally
if Message.DC = 0 then
EndPaint(Handle, PS);
end;
Canvas.Free;
inherited;
end;
(此代码通过插入器类添加到备忘录中。)
这很有效,但它并不经常被触发。例如。当我使用向下箭头滚动时。
我当然可以开始添加各种事件,以便调用备忘录的无效方法,从而强制重新绘制,但这看起来并不正确。也许已经有这样的组件,我可以使用?我已经从TJvMemo
检查了Jvcl
,但似乎没有这样的功能。
编辑:我最终使用了SynEdit。
答案 0 :(得分:6)
TMemo
本身不支持该功能,尝试添加该功能会导致头痛无法结束。
相反,请考虑使用不同的文本编辑控件。这就是Delphi IDE的功能。例如,SynEdit支持此功能:将ActiveLineColor
属性设置为clNone
以外的其他属性。
答案 1 :(得分:4)
如果您的问题是, 如何'通过选择突出显示TMemo行(行)
,这是你的答案。
Procedure SelectMemoLine(Memo : TCustomMemo) ;
Var LineNumber : Integer;
Begin
LineNumber := Memo.Perform(EM_LINEFROMCHAR, Memo.SelStart, 0);
Memo.SelStart := Memo.Perform(EM_LINEINDEX, LineNumber, 0);
Memo.SelLength := Length(Memo.Lines[LineNumber]) ;
Memo.SetFocus;
End;
Procedure TMainForm.MemoActorClick(Sender: TObject);
Begin
SelectMemoLine(MemoActor);
End;
Procedure SelectMemoAtLine(Memo : TCustomMemo; LineNumber : Integer) ;
Begin
Memo.SetFocus;
Memo.SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, LineNumber, 0);
Memo.SelLength := Length(Memo.Lines[LineNumber]);
End;
Procedure TMainForm.MemoActorKeyUp(Sender: TObject; Var Key: Word;
Shift: TShiftState);
Var LineNumber : Integer;
Begin
Case Key of
VK_UP, VK_DOWN : begin
LineNumber := SendMessage(MemoActor.Handle, EM_LINEFROMCHAR,
MemoActor.Selstart, 0);
SelectMemoAtLine(MemoActor, LineNumber);
end;
end;
End;
这两个方法是相同的一个使用Memo.Perform(..)另一个使用SendMessage(Memo.Handle,..),它很容易组合在一起。
而且,这就是你需要的一切
答案 2 :(得分:1)
如果目标仅仅是引起用户对文本的注意,请考虑简单地着色试图突出显示的文本
6.6.5
答案 3 :(得分:0)
当备忘录中的wordwrap为true时使用此
Procedure TfrmMain.Memo1Click(Sender: TObject);
var
Line: Integer;
wrap : boolean;
begin
wrap := (Sender as TMemo).WordWrap;
if wrap then
(Sender as TMemo).WordWrap := false;
with (Sender as TMemo) do
begin
Line := Perform(EM_LINEFROMCHAR, SelStart, 0);
SelStart := Perform(EM_LINEINDEX, Line, 0);
SelLength := Length(Lines[Line]);
end;
if wrap then
(Sender as TMemo).WordWrap := wrap;
end;