2

MFCプロジェクトにCRichEditCtrlがあり、これをレポートログとして使用しています。特定の状況に応じて、コントロールに異なる色のテキストを追加する必要があります(つまり、標準の通知の場合は青い線、エラーの場合は赤い線など)。私はこれを機能させることにかなり近づきましたが、それでも奇妙な動作をします:

void CMyDlg::InsertText(CString text, COLORREF color, bool bold, bool italic)
{
    CHARFORMAT cf = {0};
    CString txt;
    int txtLen = m_txtLog.GetTextLength();
    m_txtLog.GetTextRange(0, txtLen, txt);

    cf.cbSize = sizeof(cf);
    cf.dwMask = (bold ? CFM_BOLD : 0) | (italic ? CFM_ITALIC : 0) | CFM_COLOR;
    cf.dwEffects = (bold ? CFE_BOLD : 0) | (italic ? CFE_ITALIC : 0) |~CFE_AUTOCOLOR;
    cf.crTextColor = color;

    m_txtLog.SetWindowText(txt + (txt.GetLength() > 0 ? "\n" : "") + text);
    m_txtLog.SetSel(txtLen, m_txtLog.GetTextLength());
    m_txtLog.SetSelectionCharFormat(cf);
}

せいぜい、最終的には、新しく追加された行は適切に色付けされますが、前のテキストはすべて黒になります。その上、追加されたテキスト行ごとに、開始選択が1ずつ増えるようです。次に例を示します。

Call #1:
- [RED]This is the first line[/RED]

Call #2:
- [BLACK]This is the first line[/BLACK]
- [GREEN]This is the second line[/GREEN]

Call #3:
- [BLACK]This is the first line[/BLACK]
- [BLACK]This is the second line[/BLACK]
- [BLUE]This is the third line[/BLUE]

Call #4:
- [BLACK]This is the first line[/BLACK]
- [BLACK]This is the second line[/BLACK]
- [BLACK]This is the third line[/BLACK]
- [BLACK]T[/BLACK][YELLOW]his is the fourth line[/YELLOW]

Call #5:
- [BLACK]This is the first line[/BLACK]
- [BLACK]This is the second line[/BLACK]
- [BLACK]This is the third line[/BLACK]
- [BLACK]This is the fourth line[/BLACK]
- [BLACK]Th[/BLACK][ORANGE]is is the fifth line[/ORANGE]

etc...

では、色付きのテキストの新しい行を追加しながら、これまでのすべてのテキストと書式設定をそのままにしておくにはどうすればよいでしょうか。

4

3 に答える 3

6

サンプルコードは、を呼び出してダイアログから古いテキストを読み取りますGetTextRange()。これにはリッチフォーマットが含まれていないため、テキストを元の場所に戻すときにフォーマットされません。カーソルを選択せず​​に最後に設定してを呼び出すことにより、テキスト領域の最後に「挿入」することで、これを完全に回避できますReplaceSel()

私はあなたの方法がこのように見えるべきだと思います:

void CMFCApplication2Dlg::InsertText(CString text, COLORREF color, bool bold, bool italic)
{
    CHARFORMAT cf = {0};
    int txtLen = m_txtLog.GetTextLength();

    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_COLOR;
    cf.dwEffects = (bold ? CFE_BOLD : 0) | (italic ? CFE_ITALIC : 0);
    cf.crTextColor = color;

    m_txtLog.SetSel(txtLen, -1); // Set the cursor to the end of the text area and deselect everything.
    m_txtLog.ReplaceSel(text); // Inserts when nothing is selected.

    // Apply formating to the just inserted text.
    m_txtLog.SetSel(txtLen, m_txtLog.GetTextLength());
    m_txtLog.SetSelectionCharFormat(cf);
}
于 2012-12-01T03:39:09.440 に答える
0

これを機能させることを試みて私が学んだことは、上記の例のようにフラグを設定することはできないということです。これを行う:

 cf.dwMask = (bold ? CFM_BOLD : 0) | (italic ? CFM_ITALIC : 0) | CFM_COLOR;

半分は機能しますが、CRichEditCtrl(例として)を使用して現在のフォーマットを取得している場合(これは私にとって何があっても起こっていたと思いますが)、多くの時間を無駄にします。問題は、上記のフラグが値を切り替えたいものを設定します。したがって、これは実際にはより有効です。

CHARFORMAT cf;
cf.cbSize = sizeof(CHARFORMAT);
GetSelectionCharFormat(cf);

cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_COLOR; //set these to specify the flags you are changing

if (bold)
{
    cf.dwEffects |= CFE_BOLD; //toggle on
}
else
{
    cf.dwEffects &= ~CFE_BOLD; //toggle off
}

if (italic)
{
    cf.dwEffects |= CFE_ITALIC; //toggle on
}
else
{
    cf.dwEffects &= ~CFE_ITALIC; //toggle off
}

cf.dwEffects &= ~CFE_AUTOCOLOR; //this only seemed to work if I set it this way

そのようにしないと、クリアしてもフォーマットは残ります。それは私にしばらく頭をかいてしまいました、そして私はそれを直すためにたくさんのグーグルをしました。

于 2018-09-20T13:47:58.673 に答える
0

新しいテキストを挿入する前に、フォーマットを割り当てます。挿入後にフォーマットを適用すると、誤ったフォーマットのテキストになってしまいます。

CHARFORMAT cf = { 0 };
int txtLen =  GetTextLength();

cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.dwEffects = ~CFE_AUTOCOLOR;//No auto color
cf.crTextColor = RGB(0, 0, 255);//color of the text

SetSel(txtLen, -1);//Deselect all
SetSelectionCharFormat(cf);//Assign the format to the cursor pos
ReplaceSel(newText);
于 2019-10-18T23:58:28.857 に答える