如何同步两个RichEdit的滚动位置?

问题描述 投票:1回答:1

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

image

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

image

我试过的第二种方法是使用定时器并定时与LINESCROLL同步(<10ms更好)。这在大多数情况下运作良好,但有时仍然存在未对齐的问题。

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

//---------------------------------------------------------------------------
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;
}
c++ winapi c++builder vcl richedit
1个回答
1
投票

谢谢你的帮助。我找到了一个简单的解决方案来满足我的短期需求。

正如我之前提到的,应该启用第二个RichEdit的滚动条来接收WM_MOUSEWHEEL消息,但是我不喜欢两个编辑都显示滚动条。因此,我使用EM_LINESCROLL代替鼠标滚轮消息。我编写一个子类派生TRichEdit并覆盖其WM_MOUSEWHEEL处理程序,然后将带有鼠标滚轮delta值的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中的文本垂直偏移量对齐。但我认为必须有更好的解决方案,我会继续研究改进。

© www.soinside.com 2019 - 2024. All rights reserved.