I need simple TMemo that does NOT display scroll bars when they are not needed (ie insufficient text), but does when they are. something like ScrollBars = ssAuto
or like the TRichEdit HideScrollBars
.
I have tried to subclass a TMemo and use the ES_DISABLENOSCROLL
in the CreateParams like in the TRichEdit
but it does not work.
Edit: This should work with or without WordWrap
enabled.
Head to Settings > Ease of Access > Display and scroll down to the “Simplify and personalize Windows” section and turn off the “Automatically hide scroll bars in Windows” switch.
Click Start > Settings. Under Windows Settings, scroll down, and then click Ease of Access > Display. Scroll down, and then set Automatically hide scroll bars in Windows to Off.
Use overflow: auto . Scrollbars will only appear when needed. (Sidenote, you can also specify for only the x, or y scrollbar: overflow-x: auto and overflow-y: auto ).
If your memo is placed on the form, the form will be notifed with an EN_UPDATE
when the text has been changed and the contents will be redrawn. You can decide here if there will be any scroll bars. I'm assuming we're playing with the vertical scroll bar and there's no horizontal scrollbar:
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
protected
procedure WMCommand(var Msg: TWMCommand); message WM_COMMAND;
public
...
procedure SetMargins(Memo: HWND);
var
Rect: TRect;
begin
SendMessage(Memo, EM_GETRECT, 0, Longint(@Rect));
Rect.Right := Rect.Right - GetSystemMetrics(SM_CXHSCROLL);
SendMessage(Memo, EM_SETRECT, 0, Longint(@Rect));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.ScrollBars := ssVertical;
Memo1.Lines.Text := '';
SetMargins(Memo1.Handle);
Memo1.Lines.Text := 'The EM_GETRECT message retrieves the formatting ' +
'rectangle of an edit control. The formatting rectangle is the limiting ' +
'rectangle into which the control draws the text.';
end;
procedure TForm1.WMCommand(var Msg: TWMCommand);
begin
if (Msg.Ctl = Memo1.Handle) and (Msg.NotifyCode = EN_UPDATE) then begin
if Memo1.Lines.Count > 6 then // maximum 6 lines
Memo1.ScrollBars := ssVertical
else begin
if Memo1.ScrollBars <> ssNone then begin
Memo1.ScrollBars := ssNone;
SetMargins(Memo1.Handle);
end;
end;
end;
inherited;
end;
The thing with setting the right margin is that, removing/putting vertical scroll bar looks utter ugly if the text has to be restructured to fit in.
Note that the above example assumes a maximum of 6 lines. To know how many lines could fit in your memo see this question:
How do I determine the height of a line of text in a TMemo programmatically?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With