DOSEIの日記

技術メモ+日常ログ

方位記号さんから、

RichTextBox は使ったことがないのでできるかは知りませんが、単純にそのイベント内で処理(文字列挿入)すればよいのではないでしょうか?あーBeepがなりがまずいのかな?Form.WndProc をオーバーライドすれば EN_PROTECTED を拾えるので後は Win32 と同じ手法をとればおそらく。

というメッセージをいただく。
そうかー、オーバーライドかぁ。そういうのやったことないんでトライしてみようかな。というわけで、参考にさせてもらいます。

さて、今日はRichTextBoxのSelection**プロパティについて研究。なぜかカーサ(カーソル)位置を取得するプロパティなりメソッドなりが存在しないので、このプロパティ一族を操作するわけです。というか、.NET Framework SDKのヘルプ、読みづらいです。アルファベット順の一覧だけではなく、機能別の一覧がほしい。あと、概要がぜんぜん役立たない。

Selection一族でカーソル位置と関係あるのは次の2つです。

  • SelectionStart
  • SelectionLength

前者は選択の開始位置ですが、カーサ位置と同一ではないです。つまり、右から左に選択を引っ張っても、この値は常に左端(テキストの流れの向きで、もっとも先頭)。後者はそこからの選択範囲の文字数です。
さて、この2つのプロパティを操作した場合、それぞれどう影響するのかは、ヘルプにかかれてません。というわけで実験したところ…

  • 選択状態(SelectionLength>0)でSelectionStartを変更するとSelectionLengthの値そのままで、選択範囲が移動する。
  • 選択状態でSelectionLengthを変更するとSelectionStartの値が変わらずに、選択範囲が伸び縮みする。

ま、予想通りといえばそうですが。しかし、次の場合のみちょっと違う動作をします。

  • 選択状態でSelectionStartを変更し、選択範囲が行末を越える場合、改行文字(見えないが)も選択され、1文字としてカウントされる。
  • 同様に選択範囲が文末を越える場合、最後の見えない文字も選択されるが1文字としてカウントされない。
  • 最後の見えない文字だけを選択しても、もちろんSelectionLengthは0なので、判別できない。

で、これが問題かというと、問題で、選択無しでSelectionColorを変更した場合、その後にAppendTextで追加されるテキストはその色になる。しかし、見えない1文字が選択された状態でSelectionColorを変更した場合、その後に追加されるテキストは色が変更されない。(ただし、SelectionLengthに0をいれると無条件に解除されるようだ。変な処理)
うーんなんだろう…、RTFの仕組みが良くわかってないしなぁ。制御コードとかはUndocumentedだしなぁ…。RTFの仕様は公開されているみたい。
Word 2003: Rich Text Format (RTF) Specification, version 1.8