テキストボックスの左右に余白を設定するには

テキストボックスの左右に余白を設定してみます。
キーワードは「EM_SETMARGINS」メッセージです。
EM_SETMARGINSメッセージはテキストボックスの左右にピクセル単位で余白を設定することができます。
サンプルではやっていませんが、テキストボックスをサブクラス化して再描画のタイミングで
余白の部分に記号などを書くことができます。

実行時の様子
線が設定した余白の位置

'現在の位置から指定の位置まで直線を描画する
Private Declare Function LineTo Lib "gdi32.dll" _
    (ByVal hdc As Long, ByVal nXEnd As Long, ByVal nYEnd As Long) As Long
'現在の位置を変更する
Private Declare Function MoveToEx Lib "gdi32.dll" _
    (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpCoord As Long) As Long
'デバイスコンテキストのハンドルを取得する
Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
'論理ペンを作成する
Private Declare Function CreatePen Lib "gdi32.dll" _
    (ByVal fnPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
'fnPenStyleの定数
Private Const PS_SOLID = 0              '実線
Private Const PS_DASH = 1               '破線
Private Const PS_DOT = 2                '点線
Private Const PS_DASHDOT = 3            '一点鎖線
Private Const PS_DASHDOTDOT = 4         '二点鎖線
Private Const PS_NULL = 5               '非表示
Private Const PS_INSIDEFRAME = 6        '塗りつぶし
'グラフィックスオブジェクトを削除し、システムリソースを解放する
Private Declare Function DeleteObject Lib "gdi32.dll" _
        (ByVal hObject As Long) As Long
'デバイスコンテキストにオブジェクトを選択する
Private Declare Function SelectObject Lib "gdi32.dll" _
        (ByVal hdc As Long, ByVal hgdiobj As Long) As Long
'デバイスコンテキストを解放する
Private Declare Function ReleaseDC Lib "user32.dll" _
    (ByVal hWnd As Long, ByVal hdc As Long) As Long
'指定のウィンドウにメッセージを送る
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
    (ByVal hWnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'テキストボックスのメッセージ
Private Const EM_SETMARGINS = &HD3         'テキストボックスの左右のマージンを設定する
    'wParamの定数
    Private Const EC_LEFTMARGIN = &H1                    '左マージンを設定
    Private Const EC_RIGHTMARGIN = &H2                   '右マージンを設定
Private Const EM_GETMARGINS = &HD4          '複数行テキストボックスにおいて、左右のマージンを取得する

Private Sub Form_Load() Dim rc As Long, x As Long, y As Long Call SendMessage(Me.Text1.hWnd, EM_SETMARGINS, EC_LEFTMARGIN Or EC_RIGHTMARGIN, MAKELONG(30, 40)) End Sub
Private Sub Text1_Change() Call DrawLine End Sub
Private Sub Text1_Click() Call DrawLine End Sub
Private Sub DrawLine() Dim hdc As Long, hPen As Long, hOldPen As Long Dim LeftMargin, RightMargin, rc As Long 'マージン取得 rc = SendMessage(Me.Text1.hWnd, EM_GETMARGINS, 0, 0) LeftMargin = LWORD(rc) RightMargin = HWORD(rc) hdc = GetDC(Me.Text1.hWnd) hPen = CreatePen(PS_DOT, 1, vbRed) hOldPen = SelectObject(hdc, hPen) Call MoveToEx(hdc, LeftMargin, 1, 0) Call LineTo(hdc, LeftMargin, Me.Text1.Height) Call MoveToEx(hdc, Me.Text1.Width - RightMargin, 1, 0) Call LineTo(hdc, Me.Text1.Width - RightMargin, Me.Text1.Height) Call SelectObject(hdc, hPen) Call ReleaseDC(Me.Text1.hWnd, hdc) Call DeleteObject(hPen) End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer) Call DrawLine End Sub
Private Function MAKELONG(ByVal LowWord As Integer, ByVal HighWord As Integer) As Long '下位・上位ワードを与えて長整数値(32ビット値)を取得する MAKELONG = (LowWord And &HFFFF&) Or (HighWord * &H10000) End Function
Private Function HWORD(ByVal LongValue As Long) As Integer '長整数値から上位ワードを取得する HWORD = (LongValue And &HFFFF0000) \ &H10000 End Function
Private Function LWORD(ByVal LongValue As Long) As Integer '長整数値から下位ワードを取得する If (LongValue And &HFFFF&) > &H7FFF Then LWORD = (LongValue And &HFFFF&) - &H10000 Else LWORD = LongValue And &HFFFF& End If End Function
ダウンロード