テキストボックスコントロールに関する様々なテクニックを紹介しています。
Visual Basic 6(SP6) + Windows 2000/XP + Internet Explorer 6で動作確認をしています。
[ 戻る ]
SendMessage APIのwMsgに以下の値を設定することで、テキストボックスへメッセージを送信できます。
メッセージ | 値 | 意味 |
---|---|---|
EM_CANUNDO | &HC6 | EM_UNDOメッセージを処理可能か判定 |
EM_EMPTYUNDOBUFFER | &HCD | EM_UNDOメッセージ処理用バッファをクリア |
EM_FMTLINES | &HC8 | 各行の終わりに CR-CR-LFを追加・削除(複数行テキストボックス) |
EM_GETFIRSTVISIBLELINE | &HCE | 先頭に表示されている行の番号を取得 |
EM_GETHANDLE | &HBD | メモリバッファのハンドルを取得(複数行テキストボックス) |
EM_GETLINE | &HC4 | バッファに指定の1行をコピー(複数行テキストボックス) |
EM_GETLINECOUNT | &HBA | 行数の取得(複数行テキストボックス) |
EM_GETMARGINS | &HD4 | 左マージン、右マージンの取得 |
EM_GETMODIFY | &HB8 | テキストを変更したかどうかの判定 |
EM_GETPASSWORDCHAR | &HD2 | 現在のパスワード文字を取得 |
EM_GETRECT | &HB2 | フォーマット領域の矩形の取得 |
EM_GETSEL | &HB0 | 選択された最初と最後の文字位置の取得 |
EM_GETTHUMB | &HBE | スクロールバーの位置の取得 |
EM_GETWORDBREAKPROC | &HD1 | アプリケーション定義のワードラップ関数のアドレスを取得 |
EM_LIMITTEXT | &HC5 | 入力可能な文字数の設定 |
EM_LINEFROMCHAR | &HC9 | 指定の文字位置の行番号 |
EM_LINEINDEX | &HBB | 指定の行の先頭の文字位置の取得(複数行テキストボックス) |
EM_LINELENGTH | &HC1 | 指定の文字を含む行の文字数の取得(複数行テキストボックス) |
EM_LINESCROLL | &HB6 | 任意の方向にスクロール(複数行テキストボックス) |
EM_REPLACESEL | &HC2 | 現在選択されているテキストを指定の文字列で置換 |
EM_SCROLL | &HB5 | 垂直方向のスクロール(複数行テキストボックス) |
EM_SCROLLCARET | &HB7 | 現在のカーソル位置を表示するようにスクロール |
EM_SETHANDLE | &HBC | メモリバッファのハンドルを設定(複数行テキストボックス) |
EM_SETMARGINS | &HD3 | 左マージン、右マージンの設定 |
EM_SETMODIFY | &HB9 | 更新状態の設定 |
EM_SETPASSWORDCHAR | &HCC | パスワード文字の設定 |
EM_SETREADONLY | &HCF | 編集不可に設定、解除 |
EM_SETRECT | &HB3 | フォーマット矩形の設定 |
EM_SETRECTNP | &HB4 | フォーマット矩形の設定 |
EM_SETSEL | &HB1 | 指定した範囲を選択状態に設定 |
EM_SETTABSTOPS | &HCB | タブストップ位置の設定(複数行テキストボックス) |
EM_SETWORDBREAKPROC | &HD0 | アプリケーション定義のワードラップ関数のアドレスを設定 |
EM_UNDO | &HC7 | テキストを元に戻す |
[ 戻る ]
MultiLineプロパティがTrueである複数行テキストボックスに、EM_SETTABSTOPSを送信することで設定できます。テキストが代入される前に設定しておく必要があります。タブストップ位置は、Pixel単位で表わしたフォントの平均文字幅の1/4を1とするダイアログ単位で設定します。
意味 | タブストップ位置の設定(複数行テキストボックス) |
---|---|
値 | &HCB |
wParam |
|
lParam | タブストップ位置の長整数型配列のアドレス。wParam=1のときはタブストップの間隔 |
戻り値 |
|
Text1オブジェクトに任意の個数のタブストップ位置を設定する関数Tabsです。送信メッセージをLB_SETTABSTOPS(値:&H192)にするとリストボックスにタブストップを設定することができます。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_SETTABSTOPS = &HCB
Public Sub Tabs(ParamArray TabPos())
'TextBoxに任意の個数のタブストップを設定する
Dim n As Integer, i As Integer
n = UBound(TabPos) 'パラメータの数 - 1
ReDim TabStop(0 To n) As Long 'タブストップの配列
For i = 0 To n
TabStop(i) = CLng(TabPos(i) * 4) 'ダイアログ単位(平均文字幅の1/4)に変換
Next i
SendMessage Text1.hWnd, EM_SETTABSTOPS, n + 1, TabStop(0)
End Sub
Tabs関数の使用例です。ここでは6、30、35文字目にタブストップを設定しています。
Tabs 6, 30, 35 '6、30、35文字目にタブストップを設定
Text1.Text = "番号" & vbTab & "氏名" & vbTab & "得点" & vbTab & "備考" & vbCrLf
[ 戻る ]
テキストボックスに、以下のメッセージを送信することで、テキストのスクロールを行なうことができます。このうち、EM_SCROLLとEM_LINESCROLLは、MultiLineプロパティがTrueのテキストボックスで有効です。
意味 | 垂直方向のスクロール(複数行テキストボックス) |
---|---|
値 | &HB5 |
wParam | 以下の値を設定します。
|
lParam | 0 |
戻り値 |
|
意味 | 任意の方向にスクロール(複数行テキストボックス) |
---|---|
値 | &HB6 |
wParam | 水平方向のスクロールの文字数(右方向:正) |
lParam | 垂直方向のスクロールの行数(下方向:正) |
戻り値 |
|
意味 | 現在のカーソル位置を表示するようにスクロール |
---|---|
値 | &HB7 |
wParam | 0 |
lParam | 0 |
戻り値 |
|
EM_SCROLLメッセージを使って下に1行スクロールします。SendMessageの第4引数にByvalキーワードが必要です。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_SCROLL = &HB5
Public Const SB_LINEUP = 0
Public Const SB_LINEDOWN = 1
Public Const SB_PAGEUP = 2
Public Const SB_PAGEDOWN = 3
Public Sub TextScroll()
SendMessage Text1.hWnd, EM_SCROLL, SB_LINEDOWN, ByVal 0 '下に1行スクロール
End Sub
EM_LINESCROLLメッセージを使うと、水平、垂直両方向にスクロールが可能になります。ここでは右方向にx文字分、下方向にy行分のスクロールを行ないます。これもSendMessageの第4引数にByvalキーワードが必要です。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_LINESCROLL = &HB6
Public Sub TextScroll(x As Long, y As Long)
SendMessage Text1.hWnd, EM_LINESCROLL, x, ByVal y '右方向にx文字、下方向にy行のスクロール
End Sub
EM_SCROLLCARETメッセージを送信すると、カーソルのある位置が表示されるようにスクロールします。これは1行テキストボックスでも有効です。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_SCROLLCARET = &HB7
Public Sub TextScrollCaret()
SendMessage Text1.hWnd, EM_SCROLLCARET, 0, ByVal 0
End Sub
[ 戻る ]
[編集]メニューの[切り取り]、[コピー]、[貼り付け]、[クリア]、[元に戻す]を実装するには、以下のクリップボードメッセージをWindowsに送ります。これらのメッセージはCombo Boxコントロールでも使用できます。
意味 | 選択範囲をクリップボードへコピーし消去 |
---|---|
値 | &H300 |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
意味 | 選択範囲をクリップボードへコピー |
---|---|
値 | &H301 |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
意味 | クリップボードから現在位置へコピー |
---|---|
値 | &H302 |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
意味 | 選択範囲を消去 |
---|---|
値 | &H303 |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
意味 | テキストを元に戻す |
---|---|
値 | &H304 |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
[元に戻す]関連のメッセージには以下のものがあります。このうちEM_UNDOは上記のWM_UNDOと同じ動作をします。
意味 | EM_UNDOメッセージを処理可能か判定 |
---|---|
値 | &HC6 |
wParam | 0 |
lParam | 0 |
戻り値 |
|
意味 | テキストを元に戻す |
---|---|
値 | &HC7 |
wParam | 0 |
lParam | 0 |
戻り値 | 複数行テキストボックスでは成功したときは1、失敗したときは0。1行入力テキストボックスでは常に1 |
意味 | EM_UNDOメッセージ処理用バッファをクリア |
---|---|
値 | &HCD |
wParam | 0 |
lParam | 0 |
戻り値 | なし |
メニューエディタで、以下のメニューを作成します。
キャプション | ショートカット | 名前 |
---|---|---|
編集(&E) | mnuEdit | |
....元に戻す(&U) | Ctrl+Z | mnuEditUndo |
....- | mnuEditSeparate1 | |
....切り取り(&T) | Ctrl+X | mnuEditCut |
....コピー(&C) | Ctrl+C | mnuEditCopy |
....貼り付け(&P) | Ctrl+V | mnuEditPaste |
....クリア(&L) | Del | mnuEditClear |
各メニューのClickイベントに以下のコードを記述します。mnuEditのClickイベントは、サブメニューが開かれるときに実行されます。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_CANUNDO = &HC6
Public Const EM_EMPTYUNDOBUFFER = &HCD
Public Const EM_UNDO = &HC7
Public Const WM_CLEAR = &H303
Public Const WM_COPY = &H301
Public Const WM_CUT = &H300
Public Const WM_PASTE = &H302
Public Const WM_UNDO = &H304
Private Sub mnuEdit_Click()
'クリップボードにテキストデータが存在するとき、[貼り付け]を有効にする。
mnuEditPaste.Enabled = Clipboard.GetFormat(VbCFText)
'[元に戻す]の設定
With mnuEditUndo
If SendMessage(Text1.hWnd, EM_CANUNDO, 0, Byval 0) Then
.Enabled = True
.Caption = "元に戻す(&Z)"
Else
.Enabled = False
.Caption = "元に戻せません"
End If
End With
End Sub
Private Sub mnuEditClear_Click()
'クリア
SendMessage Text1.hWnd, WM_CLEAR, 0, Byval 0
End Sub
Private Sub mnuEditCopy_Click()
'コピー
SendMessage Text1.hWnd, WM_COPY, 0, Byval 0
End Sub
Private Sub mnuEditCut_Click()
'切り取り
SendMessage Text1.hWnd, WM_CUT, 0, Byval 0
End Sub
Private Sub mnuEditPaste_Click()
'貼り付け
SendMessage Text1.hWnd, WM_PASTE, 0, Byval 0
End Sub
Private Sub mnuEditUndo_Click()
'元に戻す
SendMessage Text1.hWnd, WM_UNDO, 0, Byval 0 'WM_UNDOをEM_UNDOに換えても可
SendMessage Text1.hWnd, EM_EMPTYUNDOBUFFER, 0, Byval 0 'Undoバッファを消去するときは必要
End Sub
[ 戻る ]
テキストボックスのMaxLengthプロパティは、全角、半角関係なく文字数で設定しますが、EM_LIMITTEXTを送信することで入力可能な最大バイト数を設定することができます。入力可能なバイト数の既定値は30000バイトです。既に文字列があるとき、EM_LIMITTEXTを送信しても無視されます。
意味 | 入力可能な文字数の設定 |
---|---|
値 | &HC5 |
wParam | 文字数(バイト単位) |
lParam | 0 |
戻り値 | なし |
次のMaxByte関数は、引数Lengで与えられた入力可能な最大バイト数をText1オブジェクトに設定します。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_LIMITTEXT = &HC5
Public Sub MaxByte(Leng As Long)
SendMesaage Text1.hWnd, EM_LIMITTEXT, Leng, Byval 0
End Sub
[ 戻る ]
テキストボックスにEM_SETMARGINSを送信することでマージンを設定できます。マージンはpixel単位で与えます。またEM_GETMARGINSを送信すると現在のマージンを取得できます。
意味 | 左マージン、右マージンの設定 |
---|---|
値 | &HD3 |
wParam | 以下の値を設定します。
|
lParam |
|
戻り値 | なし |
意味 | 左マージン、右マージンの取得 |
---|---|
値 | &HD4 |
wParam | 0 |
lParam | 0 |
戻り値 |
|
次のSetMargin関数はTwips単位で引数LeftMargin、RightMarginに与えた左右マージンをText1オブジェクトに設定します。このように左右両方を設定するときはEC_LEFTMARGINとEC_RIGHTMARGINをOr演算子で結合します。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_SETMARGINS = &HD3
Public Const EC_LEFTMARGIN = &H1
Public Const EC_RIGHTMARGIN = &H2
Public Sub SetMargin(LeftMargin As Long, RightMargin As Long)
Dim n As Long
n = (RightMargin / Screen.TwipsPerPixelX * &H10000) Or (LeftMargin / Screen.TwipsPerPixelX)
SendMesaage Text1.hWnd, EM_SETMARGINS, EC_LEFTMARGIN Or EC_RIGHTMARGIN, Byval n
End Sub
次のGetMargin関数は引数flagにEC_LEFTMARGINを与えると左マージン、EC_RIGHTMARGINを与えると右マージンをTwips単位で返します。
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const EM_GETMARGINS = &HD4
Public Const EC_LEFTMARGIN = &H1
Public Const EC_RIGHTMARGIN = &H2
Public Function GetMargin(flag As Long) As Long
Dim n As Long
n = SendMesaage(Text1.hWnd, EM_GETMARGINS, 0, Byval 0)
If flag = EC_LEFTMARGIN Then
n = n And &HFFFF&
Else
n = n \ &H10000
End If
GetMargin = n * Screen.TwipsPerPixelX
End Sub
[ 戻る ]
GetWindowLong APIとSetWindowLong APIを使うことで、テキストボックスのスタイルを変更することができます。
機能 | 指定されたウィンドウに関する情報を取得します。 | |
---|---|---|
宣言 |
|
|
引数 | hWnd | ウィンドウハンドル |
nIndex | 取得するデータの種類を以下の定数で指定
|
|
戻り値 |
|
機能 | 指定されたウィンドウの属性を変更します。 | |
---|---|---|
宣言 |
|
|
引数 | hWnd | ウィンドウハンドル |
nIndex | 変更するデータの種類を以下の定数で指定
|
|
dwNewLong | 新しく設定するデータ | |
戻り値 |
|
テキストボックスに関するウィンドウ属性(GetWindowLongの戻り値、SetWindowLongの引数dwNewLong)は次の通りです。
定数名 | 値 | 説明 |
---|---|---|
ES_AUTOHSCROLL | &H80 | 行末に文字を入力したとき、10文字分右にスクロール |
ES_AUTOVSCROLL | &H40 | 最終行でEnterキーを押したとき、1ページ分上にスクロール |
ES_CENTER | &H1 | 中央揃え |
ES_LEFT | &H0 | 左揃え |
ES_LOWERCASE | &H10 | 入力された文字をすべて小文字に変換 |
ES_MULTILINE | &H4 | 複数行のテキストボックス |
ES_NOHIDESEL | &H100 | フォーカスを受け取ったときに強調表示にしない。 |
ES_NUMBER | &H2000 | 数字のみ入力可 |
ES_OEMCONVERT | &H400 | 入力されたテキストをANSI文字セットからOEM文字セットに変換し、その後ANSI文字セットに戻します。 |
ES_PASSWORD | &H20 | 入力されたすべての文字をアスタリスク(*)で表示 |
ES_READONLY | &H800 | 入力・編集不可 |
ES_RIGHT | &H2 | 右揃え |
ES_UPPERCASE | &H8 | 入力された文字をすべて大文字に変換 |
ES_WANTRETURN | &H1000 | 複数行のテキストボックスに入力しているとき、Enterキーによりキャリッジリターンを挿入(1行入力では無効) |
小文字変換、大文字変換、数字のみ入力を設定、解除する関数を示します。設定するときは引数flagにTrue、解除するときはFalseを指定します。単に設定のみの場合は、If...Then...Elseブロック中のThen以下の1行のAnd演算子より前の括弧内だけでも構いません。
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_STYLE = (-16)
Public Const ES_LOWERCASE = &H10&
Public Const ES_NUMBER = &H2000&
Public Const ES_UPPERCASE = &H8&
Public Sub TextLower(flag As Boolean)
'小文字変換の設定、解除
Dim Style As Long
Style = GetWindowLong(Text1.hWnd, GWL_STYLE)
If flag Then
Style = (Style Or ES_LOWERCASE) And (Not (ES_UPPERCASE Or ES_NUMBER))
Else
Style = Style And (Not ES_LOWERCASE)
End If
SetWindowLong Text1.hWnd, GWL_STYLE, Style
End Sub
Public Sub TextUpper(flag As Boolean)
'大文字変換の設定、解除
Dim Style As Long
Style = GetWindowLong(Text1.hWnd, GWL_STYLE)
If flag Then
Style = (Style Or ES_UPPERCASE) And (Not (ES_LOWERCASE Or ES_NUMBER))
Else
Style = Style And (Not ES_UPPERCASE)
End If
SetWindowLong Text1.hWnd, GWL_STYLE, Style
End Sub
Public Sub TextNumberOnly(flag As Boolean)
'数字のみ入力の設定、解除
Dim Style As Long
Style = GetWindowLong(Text1.hWnd, GWL_STYLE)
If flag Then
Style = (Style Or ES_NUMBER) And (Not (ES_LOWERCASE Or ES_UPPERCASE))
Else
Style = Style And (Not ES_NUMBER)
End If
SetWindowLong Text1.hWnd, GWL_STYLE, Style
End Sub
[ 戻る ]
MultiLineプロパティがTrueである複数行テキストボックスに、文字列を1行追加する方法です。この方法は余分なメモリを消費せず高速です。
Public Sub TextAdd(St As String)
'テキストを1行追加
With Text1
.SelStart = Len(.Text) .SelText = St & vbCrLf
End With
End Sub
[ 戻る ]
MultiLineプロパティがFalseである1行入力テキストボックスで、[Enter]キーを押下したときに発生するBeep音を抑制します。 KeyPressイベントの引数KeyAsciiにはANSI文字コードを表す整数値が設定されています。このイベント内でKeyAsciiを0に設定することで、キー操作を取り消すことができます。ここでは[Enter]キーが押下されたときKeyAsciiを0に設定しています。
Private Sub Text1_KeyPress(KeyAscii As Integer)
'[Enter]キーのとき、入力をCancel
If KeyAscii = 13 Then
KeyAscii = 0
End If
End Sub
[ 戻る ]
Windows上のプログラムでは、テキストボックスがフォーカスを得たとき、テキスト全体が選択状態になるのが標準的です。これを実現するには標準モジュールに以下のSelectAllText関数を作成します。
Public Sub SelectAllText(Txt As TextBox)
'TextBoxのテキスト全体を選択
With Txt
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
SelectAllText関数は、各テキストボックスのGotFocusイベントで呼び出します。
Private Sub Text1_GotFocus()
SelectAllText Text1
End Sub
[ 戻る ]