Delphi:通过滚动滚动在TRichEdit中的中心特定线 [英] Delphi: Center Specific Line in TRichEdit by Scrolling

查看:199
本文介绍了Delphi:通过滚动滚动在TRichEdit中的中心特定线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有多行代码的Delphi 2007 TRichEdit.我想垂直滚动RichEdit,以使特定的行号大约位于RichEdit的可见/显示区域的中心.例如,在此示例中,我想编写CenterLineInRichEdit的代码:

I have a Delphi 2007 TRichEdit with several lines in it. I want to scroll the richedit vertically such that a specific line number if approximately centered in the visible/display area of the richedit. For example, I want to write the code for CenterLineInRichEdit in this example:

procedure CenterLineInRichEdit(Edit: TRichEdit; LineNum: Integer);
begin
  ...
  Edit.ScrollTo(...);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  REdit: TRichEdit;
  i: Integer;
begin
  REdit := TRichEdit.Create(Self);
  REdit.Parent := Self;
  Redit.ScrollBars := ssVertical;
  REdit.SetBounds(10, 10, 200, 150);
  for i := 1 to 25 do
    REdit.Lines.Add('This is line number ' + IntToStr(i));
  CenterLineInRichEdit(REdit, 13);
end;

我调查了使用WM_VSCROLL消息的情况,该消息允许向上/向下滚动一行,等等,但不允许滚动以使特定行居中.

I looked into using the WM_VSCROLL message, and it allows scrolling up/down one line, etc. but not scrolling to center a specific line.

推荐答案

尝试一下;

procedure VertCenterLine(RichEdit: TRichEdit; LineNum: Integer);
// I don't know the reason but the RichEdit 2 control in VCL does not
// respond to the EM_SCROLLCARET in Richedit.h but it does so to the
// constant in WinUser.h
const
  EM_SCROLLCARET  = $00B7;
var
  TextPos: lResult;
  Pos: TSmallPoint;
begin
  TextPos := SendMessage(RichEdit.Handle, EM_LINEINDEX, LineNum, 0);

  if TextPos <> -1 then begin
    // Go to top
    SendMessage(RichEdit.Handle, EM_SETSEL, 0, 0);
    SendMessage(RichEdit.Handle, EM_SCROLLCARET, 0, 0);

    // Get the coordinates for the beginning of the line
    Longint(Pos) := SendMessage(RichEdit.Handle, EM_POSFROMCHAR, TextPos, 0);

    // Scroll from the top
    SendMessage(RichEdit.Handle, WM_VSCROLL,
        MakeWParam(SB_THUMBPOSITION, Pos.y - RichEdit.ClientHeight div 2), 0);

    // Optionally set the caret to the beginning of the line
    SendMessage(RichEdit.Handle, EM_SETSEL, TextPos, TextPos);
  end;
end;

下面是另一种选择,它以字符串的首次出现而不是行号为中心;

The below is an alternative in that it centers the first occurance of a string instead of a line number;

procedure VertCenterText(RichEdit: TRichEdit; Text: string);
const
  EM_SCROLLCARET  = $00B7;
var
  FindText: TFindText;
  TextPos: lResult;
  Pos: TSmallPoint;
begin
  FindText.chrg.cpMin := 0;
  FindText.chrg.cpMax := -1;
  FindText.lpstrText := PChar(Text);
  TextPos := SendMessage(RichEdit.Handle, EM_FINDTEXT,
      FR_DOWN or FR_WHOLEWORD, Longint(@FindText));

  if TextPos <> -1 then begin
    SendMessage(RichEdit.Handle, EM_SETSEL, 0, 0);
    SendMessage(RichEdit.Handle, EM_SCROLLCARET, 0, 0);

    Longint(Pos) := SendMessage(RichEdit.Handle, EM_POSFROMCHAR, TextPos, 0);
    SendMessage(RichEdit.Handle, WM_VSCROLL,
        MakeWParam(SB_THUMBPOSITION, Pos.y - RichEdit.ClientHeight div 2), 0);

    SendMessage(RichEdit.Handle, EM_SETSEL, TextPos, TextPos);
  end;
end;

这篇关于Delphi:通过滚动滚动在TRichEdit中的中心特定线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆