Как синхронизировать две позиции прокрутки RichEdit? - PullRequest
1 голос
/ 15 марта 2019

Я добавляю в мою программу два RichEdit, один из которых отображает двоичное содержимое, а другой показывает индекс байта.Я надеюсь, что эти два редактирования всегда привязываются к одной и той же позиции во время / после прокрутки.

image

Возможным способом является обработка основных сообщений Rich_dit WM_VSCROLL и WM_MOUSEWHEELи передать сообщение и параметры во второй RichEdit.Я пробовал это, но я обнаружил, что два редактирования выровнены не очень хорошо.И еще один недостаток заключается в том, что полоса прокрутки обоих RichEdits должна быть включена. Если я включу только одну, другая не сможет получить сообщение WM_MOUSEWHEEL, но я надеюсь, что отображается только одна полоса прокрутки.

image

Второй способ, который я попробовал, - использовать таймер и регулярно синхронизировать с LINESCROLL по времени (лучше <10 мс).Это работает хорошо в большинстве случаев, но иногда все еще имеет проблему с выравниванием. </p>

Есть ли лучшее решение для удовлетворения такого рода спроса?

//---------------------------------------------------------------------------
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;
}

1 Ответ

1 голос
/ 21 марта 2019

Спасибо за вашу помощь. Я нашел простое решение для моей краткосрочной необходимости.

Как я упоминал ранее, вторая полоса прокрутки 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. Но я думаю, что должно быть лучшее решение, я буду продолжать исследования для улучшения.

...