【问题标题】:How to save and then restore vertical scroll position in RichEdit如何在 RichEdit 中保存然后恢复垂直滚动位置
【发布时间】:2020-07-05 20:53:28
【问题描述】:

我正在尝试保存然后恢复 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

我做错了什么?

【问题讨论】:

    标签: delphi scroll richedit


    【解决方案1】:

    选项 1

    在许多方面,“最干净”的解决方案是使用 EM_GETSCROLLPOSEM_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;
    

    可能是一个可行的选择。

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多