2005. május 4., szerda

How to change the size of the formatting rectangle of a TRichEdit


Problem/Question/Abstract:

On a TRichEdit component a line can be selected by moving the cursor to the very left of the line (the cursor will change to a right pointing arrow) and click the mouse. It seems that the position of the cursor must be in the left most pixel (i.e. only one pixel wide) so is often difficult to use. I would like to extend this functionality to be available for the full width of the border, but I cannot find out where this functionality is implemented. It is not available on the TMemo component so I presume it must be implemented in the TCustomRichEdit component but I can't find it. Can some please point me in the right direction or any suggestions on how to extend this functionality to be applied to the full border width.

Answer:

First, the width of the area where the TRichEdit control allows you to select a whole line is defined by the formatting rectangle of the control. The difference between ClientRect left and formatting rectangle left coordinates normally is 1 pixel, but you can move the left side of the formatting rectangle and the area where the cursor changes to a right pointing arrow and the RichEdit allows to select a line would be wider. You can do it both in the form OnCreate event and in the code of a TRichEdit descendant.

{ ... }
var
  XRect: TRect;
begin
  SendMessage(MyRichEdit1.Handle, EM_GETRECT, 0, integer(@XRect));
  XRect.Left := XRect.Left + 10; {set new left border for formatting rectangle}
  SendMessage(MyRichEdit1.Handle, EM_SETRECT, 0, integer(@XRect));
  { ... }

Regarding the selection of a whole line by clicking on the border, you should respond to the WM_NCHITTEST message and return a HTCLIENT constant in the message result in case the cursor is over border. The example below is a TRichEdit which has a LeftIndent property. By selecting it, you can set the left side of the formatting rectangle of the TRichEdit control.

{ ... }
TMyRichEdit = class(TRichEdit)
protected
  FLeftIndent: integer;
  procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
  procedure SetEditRect;
  procedure SetLeftIndent(AValue: integer);
public
  constructor Create(AOwner: TComponent); override;
published
  property LeftIndent: integer read FLeftIndent write SetLeftIndent;
end;

{ ... }

constructor TMyRichEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FLeftIndent := 0;
end;

procedure TMyRichEdit.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if (Message.Result = HTBORDER) then
    Message.Result := HTCLIENT;
end;

procedure TMyRichEdit.SetEditRect;
var
  XRect: TRect;
begin
  SendMessage(Handle, EM_GETRECT, 0, integer(@XRect));
  XRect.Left := FLeftIndent;
  SendMessage(Handle, EM_SETRECT, 0, integer(@XRect));
end;

procedure TMyRichEdit.SetLeftIndent(AValue: integer);
begin
  if FLeftIndent <> AValue then
  begin
    FLeftIndent := AValue;
    SetEditRect;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése