TRichEditでリッチなテキストをプログラムする
TRichEditを使って、メモ帳もどきを作る場合は、編集ボタンなどでモードを切り替えするなどすれば、任意の修飾を行える。
一方、プログラムで文字列を修飾しようとすると気をつける必要がある。
修飾を前提とした場合やってはいけないこと
TRichEdit::Text、TRichEdit::Linesにアクセスして文字列を操作しない。操作するとその時点までの全ての修飾情報は消える。
次のようなコードを書くと、1つ目の修飾(1を上付き文字にする)が消える。
RichEdit1->Lines->Add( u"012" ); // 1を上付き文字にする RichEdit1->SelStart = 1; RichEdit1->SelLength = 1; RichEdit1->SelAttributes->Offset = 4; RichEdit1->Text = RichEdit1->Text + u"345"; // ここで修飾情報がリセット // 4を下付き文字にする RichEdit1->SelStart = 5; // 改行が1文字としてカウントされている RichEdit1->SelLength = 1; RichEdit1->SelAttributes->Offset = -3;
TRichEdit::Textは修飾情報を持たないので、今回の目的では使ってはならない。
なお、TRichEdit::Lines::Add、TRichEdit::Lines::Insert、TRichEdit::Lines::Deleteは使っても他の行の修飾情報を消さない。
修飾を行うプログラム
プログラム上では、TRichEdit::SelStart・TRichEdit::SelTextを使って文字列を追加・挿入し、修飾はTRichEdit::SelAttributesプロパティを用いる。
TRichEdit::SelStart・TRichEdit::SelTextを用いると、現在のキャレット位置に文字を挿入してくれ、入力後は入力した文字の直後に移動してくれるので便利だ。
RichEdit1->SelStart = RichEdit1->GetTextLen(); // 現在のテキストの末尾にキャレットを移動であればこれでも良い TTextAttributes* pAttr = RichEdit1->SelAttributes; pAttr->Italic = true; RichEdit1->SelText = u"k"; pAttr->Italic = false; pAttr->Size = 7; pAttr->Offset = -3; RichEdit1->SelText = u"t="; RichEdit1->SelText = u"15"; pAttr->Size = 10; pAttr->Offset = 0; RichEdit1->SelText = u" = 2.6×10"; pAttr->Size = 7; pAttr->Offset = 4; RichEdit1->SelText = u"-3"; pAttr->Size = 10; pAttr->Offset = 0; RichEdit1->SelText = u" (cm/sec)\r\n次行";
TRichEdit::SelAttribultesは1つのステートしか保持できないが、追加される文字列の修飾はTRichEdit::SelAttribultesを参照してセットされる。
ここで気づかれると思うが、文字列を細切れでSelTextで追加すると、それぞれに修飾タグがひっつくので、リッチテキストのサイズが大きくなることになる。
注意事項
改行の取り扱い
TRichEdit中での文字の位置は改行コードを含む。
ただし、やっかいなのはTRichEdit::Text系(TRichEdit::GetTextLen()、TRichEdit::Text::Length()など)とTRichEdit::Sel~(TRichEdit::SelStart、TRichEdit::SelLengthなど)では改行コードの取り扱いが異なることだ。
TRichEdit::Text系は改行コードを2文字として計算する。一方TRichEdit::SelStartは改行コードを1文字で計算して指定する。
任意の位置の文字列を選択する場合で、TRichEdit::TextをPosで検索した場合は、上記を考慮して、改行コードをスキャンして改行コード分調整する必要がある。
コード中にも記載したが、単純に末尾にキャレットを移したいのであれば、TRichEdit::GetTextLen()の値をセットするだけで済む。
なお、プログラム中で、文字列に改行コード"\n"のみを埋め込んだ場合でも、自動で"\r\n"に変更される。
TRichEdit::SelAttributes
TRichEdit::SelAttributesはステートデータなので、自動で元には戻らない。
文字列を追加するときにはTRichEdit::SelAttributesを必ず自分の意図する値にセットしておく。