トップ回答者
RichTextBoxの中身の印刷での文字列の背景色の設定

質問
-
どうぞよろしくお願いいたします。
C#(VisualStudio2015)
Windows フォームで開発中です。
教えていただきたいことは、
「RichTextBoxの内容の印刷で、API関数SetBkColor(...)の使用方法」です。
RichTextBoxの内容を印刷するコードを作成しております。
マイクロソフトの以下のヘルプページを参照しました。
https://support.microsoft.com/ja-jp/help/812425/how-to-print-the-content-of-a-richtextbox-control-by-using-visual-c-.net-or-visual-c-2005
RichTextBoxクラスのサブクラスを定義しました。
このクラスのメソッドとして
public int Print( int charFrom, int charTo, PrintPageEventArgs e)
を定義するよう記載されておりました。
これをほぼそのまま参考にして印刷を実行しました。
RichTextBoxのBackColorを黄色にした場合、
文字の背景色が(たぶんデフォルトの)白色となり、BackColorは上書きされてしまうので、
文字部分が白色となってしまいます。SetBkMode(...)の使用も検討しましたが、
SetBkColor API関数を使用して、文字背景色を変更しようとしまして
デバイスコンテキストを取得している場所の直下に以下のコードを追加しました。
IntPtr hdc = e.Graphics.GetHdc(); //これは元からあるコード、
//eはこのメソッドのPrintPageEventArgs 型引数
//以下は追加したコード
if (this.BackColor == Color.Yellow)
{
SetBkColor(hdc, ColorTranslator.ToWin32(Color.Yellow));
}この結果、なんら変化が起きません。文字の背景色は元のままでした。
RichTextBoxの内容印刷での文字背景の指定の仕方を教えていただきますよう、よろしくお願いいたします。
追伸:
RichTextBoxの内容の印刷についてググってもあまり参考になるサイトが無いようdす。
皆さん、RichTextBoxはあまり使用されないのでしょうか?
私は、お客様の「エクセルみたいにセル内の文字色を自由に設定し、これを印刷できるよう」
という要件のために瀕死の重傷でした。
よろしくお願いいたします。
回答
-
ご指摘の問題ですが、EM_FORMATRANGE を使う限りにおいて、簡易的な解決方法はないようです。
もし RichTextBox に設定される文字フォーマットが簡易なもの(例えば、文字色及び背景色はそれぞれ一色で、文字のフォントやサイズも一定のもの)であれば、印刷する絵を FillRectangle や DrawString などを使って自分で描画したほうが実装が早いかと思います。
EM_FORMATRANGE の中の描画処理では、背景色は SetBkColor や BackColor ( EM_SETBKGNDCOLOR ) によって設定された値を無視し、COLOR_WINDOW (ウィンドウズの背景色の設定)で塗りつぶされるようです。
考えられる方法として(できるかどうかは試してはいませんが)、EM_FORMATRANGE の描画情報を CreateEnhMetaFile、CloseEnhMetaFile、DeleteEnhMetaFileなどの関数を使って記録し、EnumEnhMetaFile 関数で、描画情報を分解し、背景の塗りつぶし部分が実行されないように(あるいは指定された色で塗りつぶしを行うように)書き換えることで実現が可能かもしれませんが、ハードルが高く実現ができるか、分かりません。
参考サイト: https://social.msdn.microsoft.com/Forums/en-US/f1e8f372-9e9f-4479-82b2-58bcc2da0baa
- 編集済み kenjinoteMVP 2017年6月2日 13:01
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月5日 0:13
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年6月5日 7:49
すべての返信
-
ご指摘の問題ですが、EM_FORMATRANGE を使う限りにおいて、簡易的な解決方法はないようです。
もし RichTextBox に設定される文字フォーマットが簡易なもの(例えば、文字色及び背景色はそれぞれ一色で、文字のフォントやサイズも一定のもの)であれば、印刷する絵を FillRectangle や DrawString などを使って自分で描画したほうが実装が早いかと思います。
EM_FORMATRANGE の中の描画処理では、背景色は SetBkColor や BackColor ( EM_SETBKGNDCOLOR ) によって設定された値を無視し、COLOR_WINDOW (ウィンドウズの背景色の設定)で塗りつぶされるようです。
考えられる方法として(できるかどうかは試してはいませんが)、EM_FORMATRANGE の描画情報を CreateEnhMetaFile、CloseEnhMetaFile、DeleteEnhMetaFileなどの関数を使って記録し、EnumEnhMetaFile 関数で、描画情報を分解し、背景の塗りつぶし部分が実行されないように(あるいは指定された色で塗りつぶしを行うように)書き換えることで実現が可能かもしれませんが、ハードルが高く実現ができるか、分かりません。
参考サイト: https://social.msdn.microsoft.com/Forums/en-US/f1e8f372-9e9f-4479-82b2-58bcc2da0baa
- 編集済み kenjinoteMVP 2017年6月2日 13:01
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月5日 0:13
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年6月5日 7:49
-
ご回答いただきありがとうございます。
EM_FORMATRANGEですね。ご指摘いただいた、
"背景色は SetBkColor や BackColor ( EM_SETBKGNDCOLOR ) によって設定された値を無視し"
であれば、別の方法を考えるべきと思いました。
また、
"FillRectangle や DrawString などを使って自分で描画したほうが実装が早いかと思います"
と、
"CreateEnhMetaFile、CloseEnhMetaFile、DeleteEnhMetaFileなど"
でご助言いただいたことの実装を検討してみます。
RichTextBoxのRtfプロパティに文字フォーマット情報が入っているのでこれとの関連もあると思います。
極めて有用なヒント、大変ありがとうございます。