[英]How to save and then restore vertical scroll position in RichEdit
I am trying to save and then restore the vertical scroll position in RichEdit.我正在尝试保存然后恢复 RichEdit 中的垂直滚动 position。
A global var to store scroll pos:用于存储滚动位置的全局变量:
SI: TScrollInfo;
This code saves the scroll position:此代码保存滚动 position:
FillChar( SI, SizeOf(SI), #0 );
SI.cbSize := SizeOf(SI);
SI.fMask := SIF_POS;
GetScrollInfo( RichEdit1.Handle, SB_VERT, SI );
This code tries to restore it:此代码尝试恢复它:
RichEdit1.Perform( WM_VSCROLL, MakeLong(SB_THUMBTRACK, SI.nPos), 0 );
The text in RichEdit restores its older position OK. RichEdit 中的文本恢复其较旧的 position OK。 The problem is the vertical scrollbar won't jump to the older location.
问题是垂直滚动条不会跳到旧位置。
My system: Win 7 64, Delphi 2009我的系统:Win 7 64,Delphi 2009
What am I doing wrong?我究竟做错了什么?
In many ways, the "cleanest" solution would be to use the EM_GETSCROLLPOS
and EM_SETSCROLLPOS
messages:在许多方面,“最干净”的解决方案是使用
EM_GETSCROLLPOS
和EM_SETSCROLLPOS
消息:
const
EM_GETSCROLLPOS = $04DD;
EM_SETSCROLLPOS = $04DE;
var
P: TPoint;
procedure TForm1.btnSaveClick(Sender: TObject);
begin
RichEdit1.Perform(EM_GETSCROLLPOS, 0, @P)
end;
procedure TForm1.btnRestoreClick(Sender: TObject);
begin
RichEdit1.Perform(EM_SETSCROLLPOS, 0, @P)
end;
However , beware of the 16-bit limitation described in the documentation, which limits the vertical range you are able to represent using these messages.但是,请注意文档中描述的 16 位限制,它限制了您可以使用这些消息表示的垂直范围。 If you display large RTF documents, this might be an issue (a showstopper, really).
如果您显示大型 RTF 文档,这可能是个问题(确实是个大问题)。
Actually, your initial approach seems (to my surprise) not to suffer from this limitation.实际上,您最初的方法似乎(令我惊讶的是)不受此限制的影响。 You will lose in precision, not range.
您将失去精度,而不是范围。 The problem you are observing with the scrollbar can be fixed by using
SB_THUMBPOSITION
instead of SB_THUMBTRACK
.您使用滚动条观察到的问题可以通过使用
SB_THUMBPOSITION
而不是SB_THUMBTRACK
来解决。
var
Y: Integer;
procedure TForm1.btnSaveClick(Sender: TObject);
begin
y := RichEdit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
end;
procedure TForm1.btnRestoreClick(Sender: TObject);
var
NewY: Integer;
begin
NewY := RichEdit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
RichEdit1.Perform(EM_LINESCROLL, 0, Y - NewY);
end;
might be a viable option.可能是一个可行的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.