delphi - 如何在 RichEdit 中保存然后恢复垂直滚动位置
问题描述
我正在尝试保存然后恢复 RichEdit 中的垂直滚动位置。
用于存储滚动位置的全局变量:
SI: TScrollInfo;
此代码保存滚动位置:
FillChar( SI, SizeOf(SI), #0 );
SI.cbSize := SizeOf(SI);
SI.fMask := SIF_POS;
GetScrollInfo( RichEdit1.Handle, SB_VERT, SI );
此代码尝试恢复它:
RichEdit1.Perform( WM_VSCROLL, MakeLong(SB_THUMBTRACK, SI.nPos), 0 );
RichEdit 中的文本恢复其旧位置 OK。问题是垂直滚动条不会跳到旧位置。
我的系统:Win 7 64,Delphi 2009
我究竟做错了什么?
解决方案
选项1
在许多方面,“最干净”的解决方案是使用EM_GETSCROLLPOS
andEM_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;
但是,请注意文档中描述的 16 位限制,它限制了您可以使用这些消息表示的垂直范围。如果您显示大型 RTF 文档,这可能是个问题(确实是个大问题)。
选项 2
实际上,您最初的方法似乎(令我惊讶)不受此限制的影响。您将失去精度,而不是范围。您使用滚动条观察到的问题可以通过使用来解决,SB_THUMBPOSITION
而不是SB_THUMBTRACK
.
选项 3
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;
可能是一个可行的选择。
推荐阅读
- verilog - verilog3 中的错误语句
- mysql - 对 mysql 中的列应用强大的缩放
- c# - 如何拆分包含逗号的字符串并存储到 3 个变量中?
- java - HOTP 不会生成与 Google Authenticator 相同的代码
- html - 我的汉堡菜单适用于除 iPad 以外的所有设备
- git - 推荐的允许功能独立部署的 git 工作流
- windows - 进程名"
没有响应” - corda - 带有自定义 cordapps 的 Corda 节点资源管理器
- python - 将键附加到字典(Python)
- c# - ASP.NET MVC 和 ASP.NET WebAPI 的负载平衡