TRichEdit не прокручивается построчно

Сначала у меня был TMemo, и когда я схватил большой палец полосы прокрутки, содержимое Memo прокручивалось построчно, то есть не плавно, попиксельно.

Затем я переключился на использование элемента управления TRichEdit. Но теперь он прокручивается плавно, пиксель за пикселем.

Есть ли способ настроить элемент управления TRichEdit, чтобы он вел себя как элемент управления TMemo, прокручивая всю строку за раз?

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

Если нет простого способа, я могу просто изменить позицию в сообщении WM_VSCROLL...


person Max Kielland    schedule 13.01.2014    source источник


Ответы (2)


Хорошо, так что я разбираюсь.

Мое решение состояло в том, чтобы прочитать позицию полосы прокрутки и вычислить из нее номер строки. Затем вычислите дельта-количество строк для прокрутки от текущей позиции строки.

Я захватил WM_MOUSEWHEEL и WM_VSCROLL и вместо этого перевел их в сообщения EM_LINESCROLL.

// Translate Mouswheel
case WM_MOUSEWHEEL:
  Message.Msg = EM_LINESCROLL;
  Message.LParam = (long)Message.WParamHi == 120 ? -3 : 3;
  Message.WParam = 0;
  PrevWndProc(Message);
  break;

// Handle thumbscroll
case WM_VSCROLL: {
  if (Message.WParamLo == SB_THUMBTRACK || Message.WParamLo == SB_THUMBPOSITION) {
    SCROLLINFO scrInfo = { sizeof(SCROLLINFO), SIF_ALL };
    int ratio,delta;

    // Get scrollbar position
    GetScrollInfo(Script_Edit->Handle,SB_VERT,&scrInfo);

    // Calculate line number
    ratio = (scrInfo.nMax/Script_Edit->Lines->Count);
    delta = (Message.WParamHi/ratio)-GetlineNumber();

    // Don't update if delta is 0
    if (delta == 0)
      break;

    // Change to EM_LINESCROLL message
    Message.Msg = EM_LINESCROLL;
    Message.WParam = 0;
    Message.LParam = delta;
  }
  PrevWndProc(Message);
} break;

PrevWndProc() — это исходная функция WindowProc(), а GetLineNumber() возвращает индекс верхней строки элемента управления RichEdit (EM_GETFIRSTVISIBLELINE).

Я надеюсь, что это полезно, если у кого-то еще есть такая же проблема.

person Max Kielland    schedule 14.01.2014
comment
У меня такая же проблема... Это такой позор, что есть только решения базуки для такой крошечной проблемы. Я имею в виду, что я бы никогда не включил это в свой код, лучше оставьте проблему. Это так излишне... Не критикую вас, а компоновщика С++. - person ; 21.02.2014

Легче захватить сообщение WM_VSCROLL, а затем в этом сообщении определить высоту строки (через EM_POSFROMCHAR и EM_LINEINDEX), а затем обновить позицию бегунка так, чтобы она была кратна высоте строки: pos = floor(pos / lineHeight) * lineHeight

person Jeroen    schedule 02.11.2015