I am surprised at how often I still see this question asked, and the answer almost always involves using the KeyUp, or KeyDown event and programmatically canceling the keystroke if the key pressed was not numeric. I don’t like doing it that way because
- It takes several lines of code to accomplish
- It has to be done for every textbox you want to limit
So if I don’t like using the Keyup / Keydown events to limit a TextBox to numeric input, how do I choose to do it. I use the Windows API. It’s something I learned early when I started programming in Visual Basic. Many things that are hard to do with VB are much easier to do with the Windows API. In this case I use the SetWindowLong function. I have a .bas module that contains all of my common routines. This particular method is implemented as a function that takes a handle to an edit control as a parameter and returns the result of the SetWindowLong function. I can call this function for any number of TextBoxes I need to.
Option Explicit
Private Const ES_NUMBER = &H2000&
Private Const GWL_STYLE = (-16)
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
'set an editbox to numeric only - return the previous
'style on success or zero on error
Public Function ForceNumeric(ByVal EditControlhWnd As Long) As Long
Dim lngCurStyle As Long
Dim lngReturn As Long
lngCurStyle = GetWindowLong(EditControlhWnd, GWL_STYLE)
If lngCurStyle <> 0 Then
lngReturn = SetWindowLong(EditControlhWnd, GWL_STYLE, lngCurStyle Or ES_NUMBER)
End If
ForceNumeric = lngReturn
End Function
To use this function:
Private Sub Form_Load()
Dim lngResult As Long
lngResult = ForceNumeric(Text1.hwnd)
End Sub
The limit of this approach is that it doesn’t allow for decimals. It also doesn’t allow for characters such as currency, or negative (-) signs.