3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(.NET)TextBoxで表示される文字をアンチエイリアスにしたい。

実はWndowsの設定でフォントの縁を滑らかにするとかいうのがあるみたいですが、顧客すべてがその設定にしてくれるわけでもなく、納品SEもめんどくさくてやってくれそうにないので既存のTexBoxクラスを継承し、描画だけ自前でやろうと思ってました。

まあOnPaintメソッドにGraphicsオブジェクトでテキトーすればできるだろうと思ってましたが、、、、

実はTextBoxはOnPaintが発生しないらしいのです。

そして、どうやら描画まわりはOS依存の部分を使ってるらしいです。

http://dobon.net/vb/bbs/log3-14/8067.html

調べたところ自作TexBoxクラスのコンストラクタにて

Me.SetStyle(ControlStyles.UserPaint, True)

とするとOnPaintが使えるようなるみたいなので、やってみました。

するとコントロール自体の再描画(手前の別のウィンドウをのけたときなど)時はOnPaintで指定した描画されていますが、TextBox内の文字を変えたときは元のフォントに戻ってしまいます。

それでまた調べた結果、TextBox内の文字を変えたとき(TextChangedイベント)に

MyBase.RecreateHandle()

とすることで、この問題を回避しました。

しかし、TextBox内の文字を選択しとき(というかフォーカスが移った時)に表示されるフォントが変わってしまいます(たぶんシステム既定のフォント?)。

しかも、自分で書いたフォントの上にかぶさるような形で描画されるので見たくれもありません。

こんな感じになります↓

しかし他の所にフォーカスが行くとまともに描画されます。

これを何とかしようとしようとしたのですが、結局こちらを参考にさせてもらい、ウィンドウプロシージャからOSのメッセージを横取りする方法で実装しました。

(この場合、上記でやっていたSetStyleの方法は不要です。)

---------------------------------------------

Public Class TksTextBox

Inherits System.Windows.Forms.TextBox

Private Const WM_PAINT As Integer = &HF

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

MyBase.WndProc(m)

Select Case m.Msg

Case WM_PAINT

'フォーカスがないとき手動描画

If Not Focused Then

DrawText()

End If

End Select

End Sub

Private Sub DrawText()

Dim Gr As Graphics = Me.CreateGraphics()

Gr.FillRectangle(New SolidBrush(Me.BackColor), Me.ClientRectangle)

Gr.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit

Gr.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), 0, 0)

End Sub

End Class

----------------------------------------

とりあえずこれにAlignなどの実装をしてなんとか完成です。

ただ、これでも文字列選択時、もしくは文字入力中はシステムが勝手に描画するらしく、Graphicsオブジェクトで書いた影やアンチエイリアスがかかりません。

文字入力中↓

入力後(フォーカスがテキストボックスを離れている状態)↓

結局、あきらめて、OSの設定をSEに周知徹底することにしたいと思います。