【问题标题】:How to synchronize two RichEdit's scrolling position?如何同步两个 RichEdit 的滚动位置?
【发布时间】:2019-03-15 03:28:18
【问题描述】:

我添加我的程序两个 RichEdit,一个显示二进制内容,另一个显示字节的索引。我希望这两个编辑在滚动时/滚动后始终锚定在同一位置。

一种可能的方法是处理主 RichEdit 的 WM_VSCROLL 和 WM_MOUSEWHEEL 消息,并将消息和参数传递给第二个 RichEdit。我试过这个,但我发现这两个编辑不是很好对齐。另一个缺点是两个RichEdits的滚动条都需要启用,如果我只启用一个,另一个不能收到WM_MOUSEWHEEL消息,但我希望只显示一个滚动条。

我尝试的第二种方法是使用计时器并定期与 LINESCROLL 同步(

有没有更好的解决方案来处理这种需求?

//---------------------------------------------------------------------------
void __fastcall TBinaryEdit::Timer1Timer(TObject *Sender)
{
    int srcLine = 0;
    int trgLine = 0;

    if (Sender == Timer1) {
        srcLine = GetRichEditLineNo(MainEdit);
        trgLine = GetRichEditLineNo(IndexEdit);

        if (srcLine != trgLine) {
            SendMessage(IndexEdit->Handle, EM_LINESCROLL, 0, srcLine - trgLine);
        }
    }
}
//---------------------------------------------------------------------------
int TBinaryEdit::GetRichEditLineNo(TRichEdit* RE)
{
    int line;
    int wordpos;

    TRect rt;
    POINTL pt;

    SendMessage(RE->Handle, EM_GETRECT, 0, LPARAM(&rt));
    pt.x = RE->Left + rt.left;
    pt.y = RE->Top + rt.top;
    wordpos = SendMessage(RE->Handle, EM_CHARFROMPOS, 0, LPARAM(&pt));
    line = SendMessage(RE->Handle, EM_LINEFROMCHAR, wordpos, 0);

    return line;
}

【问题讨论】:

  • 你在写一个十六进制编辑器吗? github.com/bonecode/BCHexEditor
  • 致米勒:是的,我是。此外,我希望在编辑器上有查找、替换和允许直接编辑十六进制的功能。我会参考你提供的链接,非常感谢。
  • 同步 WM_SCROLL 消息如果正确实施就足够了。无论如何,如果您在创建十六进制编辑器后会发现它很有用:codeproject.com/Tips/1271133/MFC-HEX-Control
  • 为什么要把 RichEdit 硬塞进去?它不太适合这个应用程序。
  • 我不会为此使用单独的编辑控件。单个编辑控件就足够了,只需使用EM_SETMARGINSEM_SETRECT 在左侧为其提供额外的边距空间,然后将编辑控件子类化以自定义绘制该空间内的字节偏移量。或者,最简单的解决方案是将字节偏移量添加到您添加到编辑控件的文本行的前面。但是,如果您真的想同步 2 个编辑控件,请查看 this discussion,请参阅接近尾声的 Ferruccio Accalai 的示例。

标签: c++ winapi c++builder vcl richedit


【解决方案1】:

感谢您的帮助。我为我的短期需求找到了一个简单的解决方案。

正如我之前提到的,应该启用第二个 RichEdit 的滚动条以接收 WM_MOUSEWHEEL 消息,但我不喜欢两个编辑都显示滚动条。出于这个原因,我使用 EM_LINESCROLL 代替鼠标滚轮消息。我编写了一个子类派生 TRichEdit 并覆盖其 WM_MOUSEWHEEL 处理程序,然后将带有鼠标滚轮增量值的 EM_LINESCROLL 消息传递给两个 RichEdits。

int zDelta = GET_WHEEL_DELTA_WPARAM(Message.WParam);
int scroll = zDelta == -120 ? 1 : -1;

SendMessage(MainEdit->Handle, EM_LINESCROLL, 0, scroll);
SendMessage(IndexEdit->Handle, EM_LINESCROLL, 0, scroll);

这使得 RichEdits 中的文本垂直偏移对齐。但我认为必须有更好的解决方案,我会继续研究改进。

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    相关资源
    最近更新 更多