如何在TMemo中突出显示一行?

时间:2014-07-03 12:19:09

标签: delphi delphi-2007

我想在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。

4 个答案:

答案 0 :(得分:6)

TMemo本身不支持该功能,尝试添加该功能会导致头痛无法结束。

相反,请考虑使用不同的文本编辑控件。这就是Delphi IDE的功能。例如,SynEdit支持此功能:将ActiveLineColor属性设置为clNone以外的其他属性。

答案 1 :(得分:4)


如果您的问题是, 如何'通过选择突出显示TMemo行(行) ,这是你的答案。


全线突出显示鼠标单击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;

整行突出显示在TMemo上滚动键上下的选择原因

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;