Right print margin for RichEdit

In the Delphi IDE a gray line in the editor indicates the right margin for the text should it be printed. How can i do this with the RichEdit control?
GVMAsked:
Who is Participating?
 
heathprovostConnect With a Mentor Commented:
Here is one way to do it that doesnt require creating a descendant control (although you can use this method in a descendant if that is the route you want to take):



unit RETest;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure MyWndProc(var Message: TMessage);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  OldWndProc: TWndMethod;
  PageWidth: integer; //width of page in characters
implementation

{$R *.DFM}

procedure TForm1.MyWndProc(var Message: TMessage);
var
  MyCanvas: TCanvas;
  TextMetric: TTextMetric;
begin
  OldWndProc(Message); //call original WndProc
  if Message.Msg = WM_PAINT then //Paint the line
  begin
        MyCanvas := TCanvas.Create;
        MyCanvas.Handle := GetDC(RichEdit1.Handle);
    GetTextMetrics(MyCanvas.Handle, TextMetric);
    MyCanvas.Pen.Color := clSilver;
    MyCanvas.pen.Width := 1;
    MyCanvas.MoveTo(TextMetric.tmAveCharWidth * PageWidth, 0);
    MyCanvas.LineTo(TextMetric.tmAveCharWidth * PageWidth, RichEdit1.ClientHeight);
            ReleaseDC(RichEdit1.Handle, MyCanvas.Handle);
        MyCanvas.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.Top := 10;
  Edit1.Left := 10;
  Edit1.Width := 150;
  Button1.Left := 170;
  Button1.Top := 10;
  RichEdit1.Top := 20;
  RichEdit1.Align := alBottom;
  PageWidth := 80;
  OldWndProc := RichEdit1.WindowProc; //store original WndProc
  RichEdit1.WindowProc := MyWndProc; //Set new WndProc
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Edit1.Text <> '' then
  begin
    PageWidth := StrToInt(Edit1.Text);
    RichEdit1.Invalidate;
  end;
end;

end.unit RETest;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure MyWndProc(var Message: TMessage);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  OldWndProc: TWndMethod;
  PageWidth: integer; //width of page in characters
implementation

{$R *.DFM}

procedure TForm1.MyWndProc(var Message: TMessage);
var
  MyCanvas: TCanvas;
  TextMetric: TTextMetric;
begin
  OldWndProc(Message); //call original WndProc
  if Message.Msg = WM_PAINT then //Paint the line
  begin
        MyCanvas := TCanvas.Create;
        MyCanvas.Handle := GetDC(RichEdit1.Handle);
    GetTextMetrics(MyCanvas.Handle, TextMetric);
    MyCanvas.Pen.Color := clSilver;
    MyCanvas.pen.Width := 1;
    MyCanvas.MoveTo(TextMetric.tmAveCharWidth * PageWidth, 0);
    MyCanvas.LineTo(TextMetric.tmAveCharWidth * PageWidth, RichEdit1.ClientHeight);
            ReleaseDC(RichEdit1.Handle, MyCanvas.Handle);
        MyCanvas.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.Top := 10;
  Edit1.Left := 10;
  Edit1.Width := 150;
  Button1.Left := 170;
  Button1.Top := 10;
  RichEdit1.Top := 20;
  RichEdit1.Align := alBottom;
  PageWidth := 80;
  OldWndProc := RichEdit1.WindowProc; //store original WndProc
  RichEdit1.WindowProc := MyWndProc; //Set new WndProc
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Edit1.Text <> '' then
  begin
    PageWidth := StrToInt(Edit1.Text);
    RichEdit1.Invalidate;
  end;
end;

end.



Just place a button, edit, and RichEdit on your form and then copy the code over your form code.  entering a number into the edit box changes the pagewidth so you can see what is happening.

Hope this is what you are looking for.

Heath
0
 
heathprovostCommented:
ooops, I pasted twice - just grab up to the first "end." Sorry about that.
0
 
viktornetCommented:
Hello guys!

heathprovost, I'm just wondering what is the reason for saving the original WndProc() of the TRichEdit contro?!?!

-Viktor
0
 
heathprovostCommented:
viktornet, I am not sure I understand your question.  Maybe I am missing something (I know you probably know more about this kind of stuff than I do).  Dont you have to?  I mean how can you call the original WndProc without first storing its Address?  Is there a better way to do this?

Heath
0
 
heathprovostCommented:
BTW - I am still learning this subclassing stuff and Delphi makes it even harder than it is because it can be done so many different ways.  Every example I see is done with a different method.  Some use message procedures, some subclass the WndProc, and others us the CreateSubClass.  I am just confused I guess.  But I am only happy when I am confused :)

Heath
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.