Adding a permanent margin to a Memo or RichEdit

Windows allows the formatting of the visible and editable area of an Edit or RichEdit control by using the EM_SETRECT message.  SImply send the edit control this message, specifying the formatting rectangle as the long parameter (LParam).  The main pitfall here is that the EM_SETRECT message only works if the Memo or RichEdit is already visible.  As such, sending the message in the functions such as CreateWnd() method won't work.  What you want to do is set the gutter the first time the Memo or RichEdit is painted, and in response to the CreateWnd() method (since the handle has changed).  The CreateWnd() method response is necessary since the handle of the Memo or RichEdit is destroyed then recreated when certain Properties are changed.  The example below demonstrates creating a RichEdit component with a left offset.

KEYWORDS: EM_GETRECT, EM_SETRECT, CreateWnd
 

 

//in derived RichEdit (TMyRichEdit) header...

    bool FFirstPaint;
    void __fastcall CreateWnd();
    void __fastcall WMPaint(TMessage &Msg);

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_PAINT, TMessage, WMPaint)
END_MESSAGE_MAP(TRichEdit)
 

 


 
 

//---------------------------------------------------------------------------
//in derived RichEdit (TMyRichEdit) source...

__fastcall TMyRichEdit::TMyRichEdit(TComponent* Owner)
        : TRichEdit(Owner)
{
    FFirstPaint = true;
}

//---------------------------------------------------------------------------

void __fastcall TMyRichEdit::CreateWnd()
{
    FFirstPaint = true;
    TRichEdit::CreateWnd();
}

//---------------------------------------------------------------------------

void __fastcall TMyRichEdit::WMPaint(TMessage &Msg)
{
    TRichEdit::Dispatch(&Msg);
    if (FFirstPaint == true)
    {
        RECT R;
        Perform(EM_GETRECT, 0, (LPARAM)&R);
        R.left = R.left + 32;
        Perform(EM_SETRECT, 0, (LPARAM)&R);

        FFirstPaint = false;
    }
}