実は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に周知徹底することにしたいと思います。