QUESTION: How can the EN_CHANGE message handler for a CRichEditCtrl differentiate between a user change (eg, typing, cutting and pasting, etc.) and a programmatic change?

Alternatively, how can the message handler differentiate between a change of the actual text, and merely the formatting of the text?


I have a CRichEditCtrl that is editing a simple programming language.

I map the control's EN_CHANGE message to a callback, which examines the current line and sets its color and font to highlight syntax as necessary. To make the change it uses SetSelectionCharFormat().

BEGIN_MESSAGE_MAP( PatchPage, CDialogAttach )
  ON_CONTROL( WM_KEYUP, IDC_PATCH, OnRichKeyUp ) // no, doesn't work
  ON_COMMAND( ID_APPLY,      OnApply   )
Generally it appears to work fine for many months: as soon as I type a character than should change the color/bold/font/etc., it happens immediately.

However its come to my attention that my callback is called both 1) when the user types something and 2) when SetSelectionCharFormat() actually changes something.

What makes this irritating is that when the user hits F5 (mapped to the ID_APPLY command) to compile their little program, my software may identify a bug in the user program. I then use SetSelectionCharFormat() to turn that text red so the user sees where the error is.

However, when the text is changed to red, that's sufficient to cause my OnUpdate() message handler to be called---which changes the text right back to the color it "should" be based on its syntax.

If there was a way to detect that the change is being made by the program, or that the change is not of the text itself but merely formatting, I could check for that in my message handler...

One idea I had was to look for key and mouse events on the RichText, instead of EN_CHANGE events. But I can't figure out how a parent dialog window can access events for a child control.

My next idea was to subclass the RichTextCtrl, but I'm having problems with that as well (which I've asked in a separate thread).