c++mfcformattingrichedit-control

mfc richedit2 formatting


I am trying to use a rich edit control to output some text on the screen:

Monday Press 1.
Your day is Monday
Tuesday Press 2.

I can't really find any simple examples of how to do this. all i have been able to sort out is setting the window text (setWindowText), but everything else is escaping me. Any short examples?


Solution

  • Despite the comments, I'm going to answer the question you asked, about how to format data in a Rich Edit control. A few years ago, I had to do this, and came up with something that I could treat a little like an IOstream (if I were doing it today, I'd probably do it a bit differently, but such is life).

    First, code to act like an IOstream, but write to a rich-edit control:

    // rich_stream.h:
    #ifndef RICH_STREAM_H
    #define RICH_STREAM_H
    
    class rich_stream { 
        CRichEditCtrl &ctrl;
    public:
        rich_stream(CRichEditCtrl &ctrl_) : ctrl(ctrl_) { }
    
        void add_text(char const *txt) {
            ctrl.SetSel(-1,-1);
            ctrl.ReplaceSel(txt);
        }
    
        void add_int(int val) {
            CString temp;
            temp.Format("%d", val);
            add_text(temp);
        }
    
        void set_char_format(CHARFORMAT &fmt) {
            ctrl.SetSelectionCharFormat(fmt);
        }    
    };
    
    inline rich_stream &operator<<(rich_stream &s, char const *t) {
        s.add_text(t);
        return s;
    }
    
    inline rich_stream &operator<<(rich_stream &s, CHARFORMAT &fmt) {
        s.set_char_format(fmt);
        return s;
    }
    
    inline CString nl() {
        return CString("\n\n");
    }
    
    inline rich_stream &operator<<(rich_stream &s, CString (*f)()) {
        s.add_text(f());
        return s;
    }
    
    inline rich_stream &operator<<(rich_stream &s, int val) {
        s.add_int(val);
        return s;
    }
    #endif
    

    Then, I'd use this something like:

    CHARFORMAT bold;
    
    memset(&bold, 0, sizeof(bold));
    bold.cbSize = sizeof(bold);
    bold.dwMask = CFM_BOLD | CFM_FACE | CFM_SIZE;
    bold.dwEffects = CFE_BOLD;
    strcpy(bold.szFaceName, "Times");
    bold.yHeight = 14 * 20;
    
    CHARFORMAT normal;
    memset(&normal, 0, sizeof(normal));
    normal.cbSize = sizeof(normal);
    normal.dwMask = CFM_BOLD | CFM_FACE | CFM_SIZE;
    normal.dwEffects = 0;
    strcpy(normal.szFaceName, "Times");
    normal.yHeight = 14 * 20;
    
    // ...    
    
    rich_stream txt(GetRichEditCtrl());
    
    txt << bold << "Heading 1: " << normal << info1 << nl
        << bold << "Heading 2: " << normal << info2 << nl
        << bold << "Heading 3: " << normal << info3;
    

    If I were doing this today, I'd almost certainly create a small class as a wrapper for a CHARFORMAT so I could construct the formatting objects a little more cleanly. I'd probably also at least think hard about implementing it as a normal iostream with a stream buffer that inserted data into the rich edit control (but at the time I didn't know streams well enough to know I should do that).

    Glancing at it, there are a few other things that aren't really exactly right either -- add_text uses SetSel(-1, -1);. This should really retrieve the current length of the text (e.g., with GetWindowTextLength, and set the selection to just after the end.