これを試してみてください。
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;
以下は、行番号の代わりに文字列の最初の出現を中央に配置するという点で代替です。
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;