まず、簡単そうなプロパティから消化します。
プロパティ名 | 説明 |
Font | コントロールでテキストを表示するフォントです。 |
ForeColor | テキストを表示するのに使用される、このコンポーネントの前景色です。 |
まずはフォントプロパティから。
縦書きテキストボックスに送信するためのプロパティやら定数やら
''' <summary>コントロールに送信して、テキスト描画時にコントロールが使用しているフォントを取得します。</summary>
Friend Const WM_GETFONT As Integer = &H31
''' <summary>コントロールに送信して、テキスト描画時にコントロールが使用するフォントを設定します。wParam = hFont;フォントのハンドルを指定します。 0 (NULL) を指定すると、デフォルトのシステムフォントが使用されます。lParam = fRedraw;フォント設定後にコントロールを再描画するかどうかを指定します。 1 (TRUE) を指定すると、設定後直ちに再描画されます。 0 (FALSE) を指定すると、すぐには再描画されません。</summary>
Friend Const WM_SETFONT As Integer = &H30
''' <summary>
''' コントロールのフォントを設定します
''' </summary>
''' <value>指定するフォント</value>
''' <returns></returns>
''' <remarks></remarks>
Property Font As System.Drawing.Font
Get
Dim i As IntPtr = SendMessage(_Handles.TextBox, WM_GETFONT, 0, 0)
Return System.Drawing.Font.FromHdc(i)
End Get
Set(value As System.Drawing.Font)
SendMessage(_Handles.TextBox, WM_SETFONT, value.ToHfont, True)
End Set
End Property
コントロール側の設定
''' <summary>
''' フォントの取得と設定
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Property Font As System.Drawing.Font
Get
Return MyBase.Font
End Get
Set(value As System.Drawing.Font)
MyBase.Font = value
Module_Font.Font = value
End Set
End Property
フォントのデータには書体名情報だけでなくサイズやスタイル、文字飾りのデータも含まれているのですが、これらはまとめて全部送信します。
個別設定する場合はコントロールに渡す「Font」のデータに個別指定してやればできるので、ここでは割愛します。
次は「ForeColor」です。これ、結構難航しました。
当初、「SetTextColor関数」を使用すればよいかな?と思いましたが、どうにもうまくいかなかった背景があります。
「WM_CTRCOLOREDIT」メッセージを拾って処理すればいいのかな?とも思いましたが、どうにも拾えないという状況。
結果、「EM_SETCHARFORMAT」をSendMessag関数で送ってやることで解決を見ました。
''' <summary>
''' 文字列情報格納用クラス
''' </summary>
''' <remarks></remarks>
<System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet:=System.Runtime.InteropServices.CharSet.Unicode)> _
Friend Class CHARFORMAT
''' <summary>構造体のサイズ</summary>
Public cbSize As Integer = System.Runtime.InteropServices.Marshal.SizeOf(GetType(CHARFORMAT))
''' <summary>有効メンバ</summary>
Public dwMask As FontMask
''' <summary>文字の効果</summary>
Public dwEffects As FontEffects
''' <summary>文字の高さ</summary>
Public yHeight As Integer
''' <summary>ベースラインからのオフセット</summary>
Public yOffset As Integer
''' <summary>文字の色</summary>
Public crTextColor As UInteger
''' <summary>キャラクタセット</summary>
Public bCharSet As Byte
''' <summary>フォントファミリとピッチ</summary>
Public bPitchAndFamily As Byte
''' <summary>フォント名</summary>
<System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=32)> _
Public szFaceName As Char() = New Char(31) {}
End Class
#Region "CHARFORMAT用"
''' <summary>
''' 有効な情報を持つメンバは設定する属性を指定します。0又は以下の値の組み合わせになります。
''' </summary>
''' <remarks></remarks>
Friend Enum FontMask As UInteger
''' <summary>dwEffectsメンバのCFE_DOLD値が有効</summary>
BOLD = &H1
''' <summary>dwEffectsメンバのCFE_ITALIC値が有効</summary>
ITALIC = &H2
''' <summary>dwEffectsメンバのCFE_UNDERLINE値が有効</summary>
UNDERLINE = &H4
''' <summary>dwEffectsメンバのCFE_STRIKEOUT値が有効</summary>
STRIKEOUT = &H8
''' <summary>dwEffectsメンバのCFE_PROTECTED値が有効</summary>
[PROTECTED] = &H10
''' <summary>dCharSetメンバが有効</summary>
CHARSET = &H8000000
''' <summary>yOffsetメンバが有効</summary>
OFFSET = &H10000000
''' <summary>szFaceNameメンバが有効</summary>
FACE = &H20000000
''' <summary>crTextColorとdwEffectsメンバのCFE_AUTOCOLOR値が有効</summary>
COLOR = &H40000000
''' <summary>yHeightメンバが有効</summary>
SIZE = &H80000000UI
End Enum
''' <summary>
''' 文字の効果を指定します。0又は以下の組み合わせで指定します。dwMaskメンバで指定されている文字効果のみ有効です。
''' </summary>
''' <remarks></remarks>
Friend Enum FontEffects As UInteger
None = 0
''' <summary>太字で表示されます。</summary>
BOLD = &H1
''' <summary>イタリック体で表示されます。</summary>
ITALIC = &H2
''' <summary>アンダーラインを引きます。</summary>
UNDERLINE = &H4
''' <summary>取り消し線を引きます。</summary>
STRIKEOUT = &H8
''' <summary>文字が保護されます。保護される文字が変更されようとするとき、EN_PROTECTED通知メッセージが送られます。</summary>
[PROTECTED] = &H10
''' <summary>文字色がGETSYSCOLOR関数にCOLOR_WINDOWTEXTを指定したとき取得される色になります。</summary>
AUTOCOLOR = &H40000000
Disabled = &H2000
End Enum
''' <summary>
''' デフォルトの書式と選択されている文字列の書式のどちらを取得するかを指定します。0を指定するとデフォルトが、1を指定すると現在の選択範囲の書式が取得されます。
''' </summary>
''' <remarks></remarks>
Friend Enum fSelection As Integer
''' <summary>デフォルトの文字書式</summary>
[DEFAULT] = 0
''' <summary>選択範囲の文字書式</summary>
SELECTION = 1
''' <summary>EM_SETCHARFORMAT時のみ:選択されている単語に適用。選択されていない状態でもカーソルがある単語の中にあれば、その単語に対して書式が適用</summary>
SELECTWORD = 3
''' <summary>EM_SETCHARFORMAT時のみ:書式をコントロール中のすべての文字列に適用</summary>
ALL = 4
End Enum
#End Region
以上が下準備です。これから実際のコードを記載します。
''' <summary>
''' フォントカラーの設定を行います。
''' </summary>
''' <param name="Range">フォントカラーにする範囲を指定</param>
''' <param name="isForeColor">変更するフォントカラー</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetForeColor(range As fSelection, isForeColor As System.Drawing.Color)
Dim cf As New CHARFORMAT()
cf.dwMask = FontMask.COLOR Or FontMask.CHARSET
cf.dwEffects = Not FontEffects.AUTOCOLOR
cf.crTextColor = RGB(isForeColor.R, isForeColor.G, isForeColor.B)
SendMessage(_Handles.TextBox, EM_SETCHARFORMAT, CType(range, IntPtr), cf)
End Sub
Friend _ForeColor As System.Drawing.Color
''' <summary>
''' コントロールの前景色(文字色)を設定または取得します。
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property ForeColor As System.Drawing.Color
Get
Return _ForeColor
End Get
Set(value As System.Drawing.Color)
Dim Range As fSelection = fSelection.ALL
Dim NewCLR As Color = value
Call SetForeColor(Range, NewCLR)
_ForeColor = value
End Set
End Property
テキストの文字色の方、問題なく変更となりました。
「SetForeColor」プロシを別宣言した理由は、文字色の変更範囲を上のソースでは「Dim Range As fSelection = fSelection.ALL」と全体を指定していますが、部分的に変更する場合のことも考慮したためです。
さて、「WM_SETFONT」でもフォントのデザインやサイズは変更可能ですが、下の例では「WM_SETFONT」ではなく、「EM_SETCHARFORMAT」を使用した例です。
''' <summary>
''' 文字列の太字の設定を行います。
''' </summary>
''' <param name="Range">太字にする範囲を指定</param>
''' <param name="isBold">太字にするか、太字を解除するか</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetBold(Range As fSelection, isBold As Boolean)
Dim cf As New CHARFORMAT()
cf.dwMask = cf.dwMask Or FontMask.BOLD
If isBold Then
cf.dwEffects = cf.dwEffects Or FontEffects.BOLD
Else
cf.dwEffects = cf.dwEffects And Not FontEffects.BOLD
End If
SendMessage(_Handles.TextBox, EM_SETCHARFORMAT, CType(Range, IntPtr), cf)
End Sub
''' <summary>
''' 文字列の太字状態
''' </summary>
''' <remarks></remarks>
Friend _Bold As Boolean = False
''' <summary>
''' 文字列の太字の有効、無効の設定
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Bold As Boolean
Get
Return _Bold
End Get
Set(value As Boolean)
Dim Range As fSelection = fSelection.ALL
_Bold = value
Call SetBold(Range, _Bold)
End Set
End Property
このように、こちらでもフォントの状態を指定できます。リッチテキストボックスとして使用することを考慮すれば、「WM_SETFONT」ではなく、「EM_SETCHARFORMAT」の方で行うことになるかと。
しかし、簡単そうと思ったら思いっきり大変だったという罠(涙)
さて、内容がほとんどAPI関数をどう組み込むか?というAPIの使い方に傾倒してしまってきたので、このシリーズはこれで終わりです。
テキストボックスとしての機能はこれではまだ不十分でしょうが、個人的にやりたいだけの機能はもう十分ありますんで。
縦書きテキストボックスコントロールの作成、興味深く拝見しました。私も同様のコントロールが作りたくて、このサイトへ辿り着きました。このブログを参考にチェレンジしましたがうまくいきませんでした。非常に厚かましいお願いですが、サンプル等頂けないでしょうか? ko_na_yu_a_hi_ti@yahoo.ne.jp
返信削除