TRichEdit not scrolling line-by-line

466 views Asked by At

I first had a TMemo and when I grabbed the scrollbar thumb, the Memo content scrolled Line-by-line, meaning not smooth pixel-by-pixel.

Then I switched over to use a TRichEdit control instead. But now it scrolls smooth, pixel-by-pixel.

Is there a way to configure the TRichEdit control to behave more like the TMemo control, scrolling a full line at a time?

I do realise that a TRichEdit can have different line height depending on selected style. But this shouldn't be a problem if top line always was aligned (not displayed half).

If there is no simple way, I can just adjust the position in the WM_VSCROLL message...

2

There are 2 answers

1
Max Kielland On BEST ANSWER

Okay so I figure it out.

My solution was to read the scrollbar position and calculate the line number from it. Then calculate the delta number of lines to scroll from the current line position.

I captured the WM_MOUSEWHEEL and WM_VSCROLL and translated them into EM_LINESCROLL messages instead.

// 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() is the original WindowProc() function and GetLineNumber() returns the top line index of the RichEdit control (EM_GETFIRSTVISIBLELINE).

I hope this is helpful if someone else has the same problem.

0
Jeroen On

It is easier to capture the WM_VSCROLL message and then within this message determine the line height (via EM_POSFROMCHAR and EM_LINEINDEX) and then update the thumbposition so that it is a multiple of the line height: pos = floor(pos / lineHeight) * lineHeight