電子書籍の厳選無料作品が豊富!

いつもお世話になっております。
構築環境VC++2003MFCにて、リッチエディットを利用した、
2つの文章を比較するプログラムを作成しています。

リッチエディットに表示された2つの文章に対し、比較した結果間違いが発見された場合には、間違いが発見された行の背景色を別の色(自分のソースでは赤)にしたいと考えています。

現在、背景色は変わるのですが、うまく行単位に指定することができません。
自分が考えた方法は2種類あり、ひとつは1行1行の総文字数を固定し、固定した文字数に背景色変更箇所を指定する方法setSel(総文字数,1行分(固定)足した総文字数))数を図り、もうひとつは1行ごとに文字数を加算、間違いが見つかった段階で、setSel(それまでの総文字数,1行分(可変)足した総文字数)を行うというものです。

1つ目の案に関しては、文字数が可変であるため、2つのテキストで背景色の指定位置がずれてしまう、さらに行単位にはなっていないという問題が発生しました。
2つめの案に関しても、ほぼ同じ問題が発生しました。
どちらの案を利用しても、行単位での背景色変更はできませんでした。

もし、この問題に対し代替案、解決案をお持ちの方いらっしゃいましたら、ご助力をよろしくお願い致します。

また、コード中の//で表したものは、1つめの案を実行した際のものです。

以下に、私がコーディングしたものを記載します。
______________________________________________________________
char LineText[200];/*ライン毎の文字列取得*/
char LineText2[200];
//size_t LineTextSize;/*ライン毎の文字数取得*/
//size_t LineTextSize2;
int LineTextSize =200;
int LineTextSize2 =200;
int ALLText = 0;/*総文字数*/
int ALLText2 = 0;
int LineCount = m_richEditCtrl.GetLineCount();/*総行数の取得*/
int LineCount2 = m_richEditCtrl2.GetLineCount();



CHARFORMAT2 cf[1];
UpdateData(FALSE);

cf[0].cbSize = sizeof(cf[0]);
cf[0].dwMask = CFM_COLOR | CFM_BACKCOLOR ;
cf[0].dwEffects = 0;
cf[0].crBackColor = RGB(150, 0, 0);

if(!LineCount==LineCount2){
AfxMessageBox("行数が違います\n確認を行ってください");
}

for(int i = 0; i < LineCount; i++){
m_richEditCtrl.GetLine(i,LineText);
m_richEditCtrl2.GetLine(i,LineText2);
//LineTextSize = strlen(LineText);
//LineTextSize2 = strlen(LineText2);


if(strcmp(LineText,LineText2)){
m_richEditCtrl.SetSel(ALLText,ALLText+LineTextSize);
m_richEditCtrl2.SetSel(ALLText2,ALLText2+LineTextSize2);
m_richEditCtrl.SetSelectionCharFormat(cf[0]);
m_richEditCtrl2.SetSelectionCharFormat(cf[0]);

}
ALLText = ALLText + LineTextSize;
ALLText2 = ALLText2 + LineTextSize2;
}

A 回答 (1件)

GetLineIndexでその行頭のインデックスと次行インデックスを取得して


SetSelを掛け、GetSelTextで取得して比較

または richEdit1などのテキスト内容をTokenizeで切り出して比較
GetLineIndexでその行頭、次行のインデックスを取得してSetSel
といった具合のほうがいいようです

リッチエディットコントロールが内部で保持しているの文字はUnicodeではないかと思います
App側がANSIだとこの辺りで文字インデックスの差が出てきてしまうような気がします
# AppをUnicodeにしても変な動作がありましたが …

以下にサンプルを掲示します
文字列の区切りが "\r\n" だとして
// コントロール変数の更新
UpdateData( TRUE );

int nPos[2] = {0};
CString sLine[2];
int nS, nE;
nS = nE = 0;
for( int n = 0; n < LineCount; n++ ) {
  // LFの位置を見つける
  sLine[0] = m_ritchEdit.Tokenize( _T("\n"), nPos[0] );
  sLine[1] = m_ritchEdit2.Tokenize( _T("\n"), nPos[1] );
  // 切り出した文字列の比較
  if ( sLIne[0] != sLIne[1] ) {
    // 行頭を取得
    nS = m_ritchEditCtrl.LineIndex( n );
    // 行末を取得
    nE = m_ritchEditCtrl.LineIndex( n + 1 ) - 1;
    m_ritchEditCtrl.SetSel( nS, nE );
    m_ritchEditCtrl.SetSelectionCharFormat( cf[0] );
    nS = m_ritchEditCtrl2.LineIndex( n );
    nE = m_ritchEditCtrl2.LineIndex( n + 1 ) - 1;
    m_ritchEditCtrl2.SetSel( nS, nE );
    m_ritchEditCtrl2.SetSelectionCharFormat( cf[0] );
  }
}
といった具合でうまくいくと思います …
    • good
    • 0
この回答へのお礼

ご助力ありがとうございました。

おかげさまで、バッチリできました。
こういう方法があることも初めて知って、とても勉強になりました。

お礼日時:2008/10/17 08:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!