方法一:
一个字符一个字符的进行判断
缺点:费时
// 统计删除线位置
std::vector <Node> delPositionVector; CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); int nStart=0; int nEnd=-1; BOOL bContinue=FALSE; //删除线或红字体是否处于连续中 //-----------------------------------------删除线位置 for (int i=0;i<GetRichEditCtrl().GetTextLength();i++) { GetRichEditCtrl().SetSel(i,i+1); GetRichEditCtrl().GetSelectionCharFormat(cf); if ((cf.dwEffects&CFE_STRIKEOUT)==CFE_STRIKEOUT) { if (!bContinue)// 前一个字符 没有删除线 { bContinue=TRUE; nStart=i; nEnd=i+1; }else{ //前一个字符 也有删除线 nEnd=i+1; } }else{ if (bContinue)//前一个字符有删除线,但是本次字符无删除线 这是需要将删除线位置记录到容器中 { Node node; node.nStart=nStart; node.nEnd=nEnd; delPositionVector.push_back(node); } bContinue=FALSE; } } if (nEnd==GetRichEditCtrl().GetTextLength())// 考虑最后一个字符也带删除线时 { Node node; node.nStart=nStart; node.nEnd=nEnd; delPositionVector.push_back(node); }
// 统计红色字体位置
nStart=0; nEnd=-1;// 初始化 std::vector <Node> addPositonVector; bContinue=FALSE; for (int i=0;i<GetRichEditCtrl().GetTextLength();i++) { GetRichEditCtrl().SetSel(i,i+1); GetRichEditCtrl().GetSelectionCharFormat(cf); if (GetRValue(cf.crTextColor)==255&&GetGValue(cf.crTextColor)==0&&GetBValue(cf.crTextColor)==0) { if (!bContinue)// 前一个字符 不是红色 { bContinue=TRUE; nStart=i; nEnd=i+1; }else{ //前一个字符 也是红色 nEnd=i+1; } }else{ if (bContinue)//前一个字符红色,但是本字符不是红色 这是需要将红色位置记录到容器中 { Node node; node.nStart=nStart; node.nEnd=nEnd; addPositonVector.push_back(node); } bContinue=FALSE; } } if (nEnd==GetRichEditCtrl().GetTextLength())// 考虑最后一个字符也是红色 { Node node; node.nStart=nStart; node.nEnd=nEnd; addPositonVector.push_back(node); }
方法二: 折半递归
// 删除线
DelPosition(int nStart,int nEnd) { if ((nEnd-nStart)<=0) return; int len=nEnd-nStart; GetRichEditCtrl().SetSel(nStart,nEnd); CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); DWORD consistentProperty; consistentProperty=GetRichEditCtrl().GetSelectionCharFormat(cf); Node node; if ((nEnd-nStart)==1) { if ((cf.dwEffects&CFE_STRIKEOUT)!=CFE_STRIKEOUT) return; node.nStart=nStart; node.nEnd=nEnd; if (m_delPosition.empty()) { m_delPosition.push_back(node); }else{ if(m_delPosition.back().nEnd==nStart) { m_delPosition.back().nEnd=nEnd; }else{ m_delPosition.push_back(node); } } return; } if ((consistentProperty&CFM_STRIKEOUT)==CFM_STRIKEOUT)// 都有删除线 或 都无删除线 { if ((cf.dwEffects&CFE_STRIKEOUT)!=CFE_STRIKEOUT) // 都无删除线 return; node.nStart=nStart; node.nEnd=nEnd; if (m_delPosition.empty()) { m_delPosition.push_back(node); }else{ if(m_delPosition.back().nEnd==nStart) { m_delPosition.back().nEnd=nEnd; }else{ m_delPosition.push_back(node); } } return; } DelPosition(nStart,nStart+len/2); DelPosition(nStart+len/2,nEnd); }
// 下划线
UnderLinePosition(int nStart,int nEnd) { if ((nEnd-nStart)<=0) return; int len=nEnd-nStart; GetRichEditCtrl().SetSel(nStart,nEnd); CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); DWORD consistentProperty; consistentProperty=GetRichEditCtrl().GetSelectionCharFormat(cf); Node node; if ((nEnd-nStart)==1) { if ((cf.dwEffects&CFE_UNDERLINE)!=CFE_UNDERLINE) return; node.nStart=nStart; node.nEnd=nEnd; if (m_underLinePosition.empty()) { m_underLinePosition.push_back(node); }else{ if(m_underLinePosition.back().nEnd==nStart) { m_underLinePosition.back().nEnd=nEnd; }else{ m_underLinePosition.push_back(node); } } return; } if ((consistentProperty&CFM_UNDERLINE)==CFM_UNDERLINE)// 都有删除线 或 都无删除线 { if ((cf.dwEffects&CFE_UNDERLINE)!=CFE_UNDERLINE) return; node.nStart=nStart; node.nEnd=nEnd; if (m_underLinePosition.empty()) { m_underLinePosition.push_back(node); }else{ if(m_underLinePosition.back().nEnd==nStart) { m_underLinePosition.back().nEnd=nEnd; }else{ m_underLinePosition.push_back(node); } } return; } UnderLinePosition(nStart,nStart+len/2); UnderLinePosition(nStart+len/2,nEnd); }
// 红色线
RedCharPosition(int nStart,int nEnd) { if ((nEnd-nStart)<=0) return; int len=nEnd-nStart; GetRichEditCtrl().SetSel(nStart,nEnd); CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); DWORD consistentProperty; consistentProperty=GetRichEditCtrl().GetSelectionCharFormat(cf); Node node; if ((nEnd-nStart)==1) { if (!(GetRValue(cf.crTextColor)==255&&GetGValue(cf.crTextColor)==0&&GetBValue(cf.crTextColor)==0)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_red_addPostion.empty()) { m_red_addPostion.push_back(node); }else{ if(m_red_addPostion.back().nEnd==nStart) { m_red_addPostion.back().nEnd=nEnd; }else{ m_red_addPostion.push_back(node); } } return; } if ((consistentProperty&CFM_COLOR)==CFM_COLOR)// 都有相同的颜色 { if (!(GetRValue(cf.crTextColor)==255&&GetGValue(cf.crTextColor)==0&&GetBValue(cf.crTextColor)==0)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_red_addPostion.empty()) { m_red_addPostion.push_back(node); }else{ if(m_red_addPostion.back().nEnd==nStart) { m_red_addPostion.back().nEnd=nEnd; }else{ m_red_addPostion.push_back(node); } } return; } RedCharPosition(nStart,nStart+len/2); RedCharPosition(nStart+len/2,nEnd); }
//蓝色文字
BlueCharPosition(int nStart,int nEnd) { if ((nEnd-nStart)<=0) return; int len=nEnd-nStart; GetRichEditCtrl().SetSel(nStart,nEnd); CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); DWORD consistentProperty; consistentProperty=GetRichEditCtrl().GetSelectionCharFormat(cf); Node node; if ((nEnd-nStart)==1) { if (!(GetRValue(cf.crTextColor)==0&&GetGValue(cf.crTextColor)==0&&GetBValue(cf.crTextColor)==255)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_blue_addPosition.empty()) { m_blue_addPosition.push_back(node); }else{ if(m_blue_addPosition.back().nEnd==nStart) { m_blue_addPosition.back().nEnd=nEnd; }else{ m_blue_addPosition.push_back(node); } } return; } if ((consistentProperty&CFM_COLOR)==CFM_COLOR)// 都有相同的颜色 { if (!(GetRValue(cf.crTextColor)==0&&GetGValue(cf.crTextColor)==0&&GetBValue(cf.crTextColor)==255)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_blue_addPosition.empty()) { m_blue_addPosition.push_back(node); }else{ if(m_blue_addPosition.back().nEnd==nStart) { m_blue_addPosition.back().nEnd=nEnd; }else{ m_blue_addPosition.push_back(node); } } return; } BlueCharPosition(nStart,nStart+len/2); BlueCharPosition(nStart+len/2,nEnd); }
// 背景色 rgb(200,200,200)
ReCoverPosition(int nStart,int nEnd) { if ((nEnd-nStart)<=0) return; int len=nEnd-nStart; GetRichEditCtrl().SetSel(nStart,nEnd); CHARFORMAT2 cf; memset(&cf,0,sizeof(CHARFORMAT2)); DWORD consistentProperty; consistentProperty=GetRichEditCtrl().GetSelectionCharFormat(cf); Node node; if ((nEnd-nStart)==1) { if (!(GetRValue(cf.crBackColor)==200&&GetGValue(cf.crBackColor)==200&&GetBValue(cf.crBackColor)==200)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_ReCoverPosition.empty()) { m_ReCoverPosition.push_back(node); }else{ if(m_ReCoverPosition.back().nEnd==nStart) { m_ReCoverPosition.back().nEnd=nEnd; }else{ m_ReCoverPosition.push_back(node); } } return; } if ((consistentProperty&CFM_BACKCOLOR)==CFM_BACKCOLOR)// 都有相同的颜色 { if (!(GetRValue(cf.crBackColor)==200&&GetGValue(cf.crBackColor)==200&&GetBValue(cf.crBackColor)==200)) return; node.nStart=nStart; node.nEnd=nEnd; if (m_ReCoverPosition.empty()) { m_ReCoverPosition.push_back(node); }else{ if(m_ReCoverPosition.back().nEnd==nStart) { m_ReCoverPosition.back().nEnd=nEnd; }else{ m_ReCoverPosition.push_back(node); } } return; } ReCoverPosition(nStart,nStart+len/2); ReCoverPosition(nStart+len/2,nEnd); }
递归算法关键是判断: 当递归进行到底,不能继续递归时,是何种情况 然后,对这种情况进行单独处理
最初的递归想法:
初始思路: DelPosition(int len) { if (len==1) { if(无删除线) return; else{ 保存在容器中 } return; } DelPosition(len/2 ,前一段); DelPosition(len/2 ,后一段); } 扩展思路后: DelPosition(int len) { if (len==1) { if(无删除线) return; else{ 保存在容器中 } return; } if(整体无删除线) return; if (整体有删除线) { 保存在容器中; return; } // 有的字体有删除线 有的字体没有删除线 DelPosition(len/2 ,前一段); DelPosition(len/2 ,后一段); }