読者です 読者をやめる 読者になる 読者になる

高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

WordPadをつくろう

プログラミング

TMemoを.NET化する際使用できないかと思い、テキストエディタ+ちょっとした常駐機能なソフトを.NET Frameworkで作ってみようとただいま実験中。とりあえずはWordPadと同等の働きが出来るエディタを作ってみようとちょこちょこやってみています。
さて、そこでRichEditBoxなわけですが、結構くせ者ですね、これ。

    /// <summary>書式>強調</summary>
    private void outlineEmphasis_ActionPerformed(object sender, EventArgs e)
    {
      editor.SelectionFont =
        new Font(editor.Font, toggleFontStyle(editor.SelectionFont.Style, FontStyle.Bold));
    }
  ・・・
    /// <summary>フォントスタイルを追加および削除する</summary>
    /// <param name="baseStyle">ベースとなる<see cref="FontStyle"/></param>
    /// <param name="style">追加および削除する<see cref="FontStyle"/></param>
    /// <returns></returns>
    private FontStyle toggleFontStyle(FontStyle baseStyle, FontStyle style)
    {
      return (baseStyle & style) != 0 ? baseStyle ^ style : baseStyle | style;
    }

というコードを書いて、メニューが選択されるごとに文字修飾状態をトグルするようにしてみたのですが、下線や取消線のメニューを同じ要領で作り、下線と取消線が選択文字列の一部にかかってる状態でメニューを選択すると、太字以外の文字修飾がなくなってしまいます。
追跡してみると、editor.SelectionFont.Styleは、選択範囲に文字修飾がかかってる領域とかかってない領域が混ざっている場合、何が何でもFontStyle.Regulerを返してしまうという問題がある様子。つまり、何をやってもFontStyle.RegulerにFontStyle.Boldを掛け合わせてしまうのですね。
WordPadのほうはどうかというと、その辺はちゃんと計算に入れている様子。選択範囲の一部に文字修飾があっても、それをちゃんと考慮してくれてます。
この問題を解決するには、文字一つ一つに対して処理*1を行うしかなさそうですが…。とりあえず今はこれをメインでやってるわけじゃなし、今回はやめておこう。

作成中作品は珍しくProgrammingBackgroundに置いてあります。デバッグリリース ソース付き。

*1:文字の修飾状態を取得して、Boldを付け足し(もしくは除去)して、再度セットする