在win32 richedit中更改文本颜色

时间:2014-07-16 16:52:18

标签: c++ winapi richedit

我想在win32 rich edit控件中显示不同的文本颜色,这里是'my test

#include <windows.h>
#include <richedit.h>
#include <commctrl.h>

HWND console;

// util function for rich edit
namespace rich_edit {
    CHARFORMAT get_char_fmt(HWND hwnd, DWORD range = SCF_DEFAULT) {
        CHARFORMAT cf;
        SendMessage(hwnd, EM_GETCHARFORMAT, range, (LPARAM)&cf);
        return cf;
    }
    void set_char_fmt(HWND hwnd, const CHARFORMAT& cf, DWORD range = SCF_DEFAULT) {
        SendMessage(hwnd, EM_SETCHARFORMAT, range, (LPARAM)&cf);
    }
    void replace_sel(HWND hwnd, const char* str) {
        SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)str);
    }
    void cursor_to_bottom(HWND hwnd) {
        SendMessage(hwnd, EM_SETSEL, -2, -1);
    }
    void scroll_to(HWND hwnd, DWORD pos) {
        SendMessage(hwnd, WM_VSCROLL, pos, 0);
    }
    void scroll_to_bottom(HWND hwnd) {
        scroll_to(hwnd, SB_BOTTOM);
    }
    // this function is used to output text in different color
    void append(HWND hwnd, COLORREF clr, const char* str) {
        cursor_to_bottom(hwnd); // move cursor to bottom

        CHARFORMAT cf = get_char_fmt(hwnd); // get default char format
        cf.cbSize = sizeof(cf);
        cf.dwMask = CFM_COLOR; // change color
        cf.crTextColor = clr; 

        set_char_fmt(hwnd, cf); // set default char format

        replace_sel(hwnd, str); // code from google
        scroll_to_bottom(hwnd); // scroll to bottom
    }
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int main() {

    LoadLibrary("riched20.dll"); // for using rich edit


    static char szAppName[] = "winhello";
    HWND        hwnd;
    MSG         msg;
    WNDCLASSEX  wndclass;

    wndclass.cbSize         = sizeof(wndclass);
    wndclass.style          = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = GetModuleHandle(0);
    wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszClassName  = szAppName;
    wndclass.lpszMenuName   = NULL;

    RegisterClassEx(&wndclass);

    hwnd = CreateWindow(szAppName, "Hello, world!",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            400, 300,
            NULL, NULL, GetModuleHandle(0), NULL);

    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);

    while ( GetMessage(&msg, NULL, 0, 0) ) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } 
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
    switch ( iMsg ) {
    case WM_CREATE:
        console = CreateWindow(RICHEDIT_CLASS, "",
                               WS_CHILD | ES_SAVESEL | ES_NOHIDESEL | WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL | WS_EX_STATICEDGE,
                               0, 0, 300, 200, hwnd, 0, GetModuleHandle(0), 0);

        // output a red string
        rich_edit::append(console, RGB(255, 0, 0), "aaaa\n");

        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}

该行:

rich_edit :: append(控制台,RGB(255,0,0),“aaaa \ n”);

应该输出一个红色字符串,但实际上它是黑色的,为什么会这样?

感谢。

3 个答案:

答案 0 :(得分:5)

通过将dwEffects设置为0来解决问题:

    void append(HWND hwnd, COLORREF clr, const char* str) {
        CHARFORMAT cf = get_char_fmt(hwnd);
        cf.cbSize = sizeof(cf);
        cf.dwMask = CFM_COLOR;
        cf.dwEffects = 0; // add this line

并将SCF_DEFAULT更改为 SCF_SELECTION

答案 1 :(得分:2)

http://win32assembly.programminghorizon.com/tut33.html

有关设置默认文本和背景颜色的信息,这应该会有所帮助。

编辑:

好的,对不起,我是这个网站的新手,所以我没有意识到我也应该给出解释。

基本上,你在下面所做的将使它再次起作用。您需要SCF_SELECTION,因为这将告诉RichEdit使用CHARFORMAT对象格式化文本,包括您想要输入的任何内容或使用SetSel选择的任何内容(这意味着您也可以通过以下方式重绘RichEdit中已有的文本)使用SetSel成员)。 dwEffect用于粗体,斜体等等。这也需要设置 - 通过将其设置为0,您只需获得常规文本。如果您希望使用dwEffect,请确保正确设置dwMask。如果您需要更详细地解释的内容,请使用以下链接:http://msdn.microsoft.com/en-us/library/windows/desktop/bb787881(v=vs.85).aspx

答案 2 :(得分:0)

试试这个:

HWND hRicheditControl;

void txtBold(HWND hWindow) {
    CHARFORMAT boldfont;
    boldfont.cbSize = sizeof(CHARFORMAT);
    boldfont.dwMask = CFM_BOLD;
    boldfont.dwEffects = CFE_BOLD;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&boldfont);
}
void txtUnderlined(HWND hWindow) {
    CHARFORMAT2 underlinedfont;
    underlinedfont.cbSize = sizeof(CHARFORMAT);
    underlinedfont.dwMask = CFM_UNDERLINE;
    underlinedfont.dwEffects = CFM_UNDERLINE;

    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&underlinedfont);
}
void txtItalic(HWND hWindow) {
    CHARFORMAT Kursivfont;
    Kursivfont.cbSize = sizeof(CHARFORMAT);
    Kursivfont.dwMask = CFM_ITALIC;
    Kursivfont.dwEffects = CFM_ITALIC;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&Kursivfont);
}
void txtStrikeout(HWND hWindow) {
    CHARFORMAT underlinedfont;
    underlinedfont.cbSize = sizeof(CHARFORMAT);
    underlinedfont.dwMask = CFM_STRIKEOUT;
    underlinedfont.dwEffects = CFM_STRIKEOUT;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&underlinedfont);
}
void Subscript(HWND hWindow) {
    CHARFORMAT2 cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFE_SUBSCRIPT;
    cf.dwEffects = CFE_SUBSCRIPT;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}

void Superscript(HWND hWindow) {
    CHARFORMAT2 cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_SUPERSCRIPT;
    cf.dwEffects = CFM_SUPERSCRIPT;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}
void SetFont(HWND hWindow, const char * Font) {
    CHARFORMAT2 cf;
    memset(&cf, 0, sizeof cf);
    cf.cbSize = sizeof cf;
    cf.dwMask = CFM_FACE;
    wsprintf(cf.szFaceName, Font);
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}

void FontSize(HWND hWindow, int size) {
    CHARFORMAT2 cf;
    memset(&cf, 0, sizeof cf);
    cf.cbSize = sizeof cf;
    cf.dwMask = CFM_SIZE;
    cf.yHeight = size * 20;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}
void txtColor(HWND hWindow, COLORREF clr) {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_COLOR;
    cf.crTextColor = clr;
    cf.dwEffects = 0;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}

void txtBackColor(HWND hWindow, COLORREF clr) {
    CHARFORMAT2 cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_BACKCOLOR;
    cf.crBackColor = clr;
    cf.dwEffects = 0;
    SendMessage(hWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
}

使用:

txtBold(hRicheditControl); //for bold-text
txtUnderlined(hRicheditControl); //for underlined-text
txtItalic(hRicheditControl); //for itaic-text
txtSrikeout(hRicheditControl); //for strikeout-text
Subscript(hRicheditControl); //for Sub-text
Superscript(hRicheditControl); //for Super-text
SetFont(hRicheditControl, "Arial"); //define the fontname in the ""
FontSize(hRicheditControl, 32); //set the fontsize as int
txtColor(hRicheditControl, RGB(255,0,0)); //set the text to red
txtBackColor(hRicheditControl, RGB(0,255,0)); //Set the textbackgroundcolor to green