OnScroll event for the TRichEdit control

For scrolling notification in most windowed controls, the standard approach is simply to handle the WM_HSCROLL or WM_VSCROLL messages.  For RichEdit controls, however, one can also scroll the control by moving the caret.  This act, however, will not generate the aforementioned messages.  However, you can use the WM_VSCROLL and WM_HSCROLL messages in conjunction with the EN_VSCROLL and EN_HSCROLL notification messages.  These latter notifications are sent when the user scrolls the RichEdit via caret movement.  Like all Standard Control notification messages, EN_VSCROLL and EN_HSCROLL are sent to the RichEdit's Parent in the form of a WM_COMMAND message.  To handle the message in the implementation of a RichEdit descendant class, use the reflected version of WM_COMMAND -- the CN_COMMAND VCL message.

Create a TRichEdit descendant, in which you use the message mapping macros to handle the WM_HSCROLL and WM_VSCROLL messages.  To handle the EN_VSCROLL notification, use the CN_COMMAND VCL message, also in the TRichEdit descendant implementation.  In order to receive this notification, you'll need to send the RichEdit the EM_SETEVENTMASK message, specifying the ENM_SCROLL flag as part of the event mask -- do this in an augmented CreateWnd() member function so that the changes will be made every time the RichEdit recreates itself.  The following example demonstrates how to create TRichEdit descendant that publishes an OnVertScroll event.  A horizontal scrolling event can be implemented in a similar fashion.

KEYWORDS:  EN_HSCROLL, EN_VSCROLL, EM_SETEVENTMASK, CN_COMMAND.
 

 
//---------------------------------------------------------------------------
// in MyRichEdit header...

class TMyRichEdit : public TRichEdit
{
private:
    TNotifyEvent FOnVertScroll;
    MESSAGE void __fastcall CNCommand(TMessage &Msg);
    MESSAGE void __fastcall WMVScroll(TMessage &Msg);    

protected:
    virtual void __fastcall CreateWnd();

public:
    __fastcall TMyRichEdit(TComponent* Owner);

__published:
    __property TNotifyEvent OnVertScroll =
        {read = FOnVertScroll, write = FOnVertScroll}; 

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CN_COMMAND, TMessage, CNCommand)
    MESSAGE_HANDLER(WM_VSCROLL, TMessage, WMVScroll)
END_MESSAGE_MAP(TRichEdit);
};

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


 
 
 

//---------------------------------------------------------------------------
// in MyRichEdit source...

void __fastcall TMyRichEdit::CreateWnd()
{
    TRichEdit::CreateWnd();
    
    DWORD dwMask = SNDMSG(Handle, EM_GETEVENTMASK, 0, 0);
    dwMask = dwMask | ENM_SCROLL;
    SNDMSG(Handle, EM_SETEVENTMASK, 0, dwMask);
}
//---------------------------------------------------------------------------

void __fastcall TMyRichEdit::CNCommand(TMessage &Msg)
{
    TRichEdit::Dispatch(&Msg);
    if (Msg.WParamHi == EN_VSCROLL)
    {
        if (FOnVertScroll) FOnVertScroll(this);
    }
}
//---------------------------------------------------------------------------

void __fastcall TMyRichEdit::WMVScroll(TMessage &Msg)
{
    TRichEdit::Dispatch(&Msg);
    if (FOnVertScroll) FOnVertScroll(this);
}
//---------------------------------------------------------------------------