我在一个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...那么,我如何才能在添加新的一行彩色文本时,使所有以前的文本和格式保持原样呢?
发布于 2012-12-01 11:39:09
您的示例代码通过调用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);
}发布于 2018-09-20 21:47:59
我从尝试让它工作的过程中学到的东西是,你不能像上面的例子那样简单地设置标志。执行此操作:
cf.dwMask = (bold ? CFM_BOLD : 0) | (italic ? CFM_ITALIC : 0) | CFM_COLOR;Half可以工作,但如果您使用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如果您不这样做,格式将保持不变-即使您清除了它。它让我挠头了一段时间,我做了很多谷歌来解决它。
发布于 2019-10-19 07:58:29
在插入新文本之前指定格式。如果在插入后应用该格式,则最终将得到格式不正确的文本。
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);https://stackoverflow.com/questions/13655838
复制相似问题