CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat()?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat()?

  1. #1
    Join Date
    May 2013
    Posts
    14

    CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat()?

    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().

    Code:
    BEGIN_MESSAGE_MAP( PatchPage, CDialogAttach )
      ON_CONTROL( EN_CHANGE, IDC_PATCH, OnUpdate )
      ON_CONTROL( WM_KEYUP, IDC_PATCH, OnRichKeyUp ) // no, doesn't work
      ON_COMMAND( ID_APPLY,      OnApply   )
    END_MESSAGE_MAP()
    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).

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,274

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Quote Originally Posted by Swiss Frank View Post
    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).
    RichTextCtrl or MFC CRichEditCtrl?
    If the latter then what is the problem? Derive a new class from CRichEditCtrl, override methods you need to, and then use this new class instead of CRichEditCtrl (create a control member variable of the type of your new derived class rather than CRichEditCtrl)
    Victor Nijegorodov

  3. #3
    Join Date
    May 2013
    Posts
    14

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Hi Victor,

    You're in Wallisellen? I don't know NE Zurich well but lived in worked on the south shore of Zuerisee for six years...

    Yes, I'm using MFC CRichEditCtrl. As you may have seen in a separate thread, I have indeed tried to subclass it, and while I've subclassed from CButton for 3-4 successful applications, I'm having one issue with subclassing from CRichEditCtrl.

    That problem is that the example code in Visual Studio, one gets the WNDCLASS struct for the superclass with GetClassInfo() which needs the superclass's class name. For CButton its "button" (I know from the example code) but how can one find this name for other control classes? I've tried RichEditCtrl, RICHEDIT50W (the value of the MSFTEDIT_CLASS #define), and lower-case versions...

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,274

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Quote Originally Posted by Swiss Frank View Post
    Hi Victor,

    You're in Wallisellen?
    Yes, our office is in Wallisellen.

    Quote Originally Posted by Swiss Frank View Post
    ...
    That problem is that the example code in Visual Studio, one gets the WNDCLASS struct for the superclass with GetClassInfo() which needs the superclass's class name. For CButton its "button" (I know from the example code) but how can one find this name for other control classes? I've tried RichEditCtrl, RICHEDIT50W (the value of the MSFTEDIT_CLASS #define), and lower-case versions...
    Why do you need this example? I guess it is for Win32, not for MFC.
    All you need to subclass control in MFC I showed you in my previous post.
    Victor Nijegorodov

  5. #5
    Join Date
    May 2013
    Posts
    14

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Hello again Victor,

    > Derive a new class from CRichEditCtrl, override methods you need to, and then use this new class instead of CRichEditCtrl

    One extra question. I've used VS2008's dialog editor to lay out the window. If I use a Custom Control (and provide the name of my new class), is there a way for the CRichEditCtrl's properties to show up on the properties window? Or will I need to set them all programmatically?

    Thanks in advance for your help.

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,274

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    But why do you select a Custom Control with the following registering a "new" class for richedit rather than select the rechedit control?
    Victor Nijegorodov

  7. #7
    Join Date
    May 2013
    Posts
    14

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    > But why do you select a Custom Control with the following registering a "new" class for richedit rather than select the rechedit control?

    I don't understand your question. For the last several months, I was using a dialog that was built based on Rich Edit 2.0 Control selected off the Toolbox. It worked OK, but I needed to do something that seems impossible with the stock Rich Edit 2.0 Control.

    No problem, as you said, just subclass it! OK. Now, I need to use the resource editor to put a control OF THAT NEW SUBCLASS on the dialog, right? Otherwise I'd continue to get the Rich Edit 2.0 Control.

    Still, no problem. My app calls the following function at startup, allowing my class to be recognized by name as SCRichEdit.

    Code:
    BOOL SCRichEdit::RegisterControlClass() {
    
      // STEP 1: check to see if a class is already registered with this name.
      // If it is, and the WndProcHook is ours, then WE'VE already registered
      // and its OK.  Otherwise someone else is using the same class name.  Not OK.
    
      WNDCLASS           wclsSCRichEdit;
      static const TCHAR szClass[] = _T( "SCRichEdit" );
    
      if ( ::GetClassInfo( AfxGetInstanceHandle(), szClass, &wclsSCRichEdit ) )
          return wclsSCRichEdit.lpfnWndProc == (WNDPROC) SCRichEdit::WndProcHook;
    
    
    
      // STEP 2: No "SCRichEdit" is registered, so register ourselves.  To do this,
      // we call RegisterClass() after filling out a WNDCLASS structure.  Rather
      // than fill it all out ourselves, we'll just duplicate the one used by
      // the built-in "button" class and change a couple fields.
    
      VERIFY( ::GetClassInfo( NULL, _T( "RichEdit20A" ), &wclsSCRichEdit ) ); // <---- Thanks Spy++, thanks VictorN, thanks CodeGuru!!!
      lpfnSuperEdit = wclsSCRichEdit.lpfnWndProc;
    
      wclsSCRichEdit.lpfnWndProc   = SCRichEdit::WndProcHook;
      wclsSCRichEdit.hInstance     = AfxGetInstanceHandle();
      wclsSCRichEdit.lpszClassName = szClass;
    
      return RegisterClass( &wclsSCRichEdit ) != 0;
    }
    The final thing to do is to use the resource editor: delete the Rich Edit 2.0 Control, and create a Custom Control. I then open the Properties dialog, and put SCRichEdit in the Class field.



    I'm happy to take any advice though. If you think this isn't a good approach I'm eager to learn a better one.

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,274

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Ok I usderstand you now.
    Victor Nijegorodov

  9. #9
    Join Date
    May 2013
    Posts
    14

    Re: CRichEditCtrl VC2008 Win7: differentiating user edits and SetSelectionCharFormat(

    Thanks again for your help Victor.

    By the way, the main reason I'm doing this subclassing is a pretty simple one: when I get the EN_CHANGE message from the RichText, I can't tell whether it was the user editing the text (important to me--so I can do real-time syntax-based formatting, keyword highlighting etc.), or if it was the program changing the font/color/etc. formatting in response to an edit.

    Does this sound right to you? Can you think of any way my message handler for EN_CHANGE can tell what the change actually was? (A hack I thought of: save a copy of the CString content of the Rich Text... then with callback, see if the TEXT matches. If not, a user edit; see if I need to format the text. If the same though, the change was actually the program formatting the text, further formatting.) Do you see any other ("reasonably efficient?") way I could simply ignore the updates I'm making myself?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center