API版有很多关于callback的函数说明,用这个功能把del的消息全都给拦截掉。例: form:Option ExplicitPrivate Sub Form_Load()
With Me .Caption = "Truly numeric text box" 'Center form on screen .Move (Screen.Width / 2) - (.Width / 2), (Screen.Height / 2) - (.Height / 2) End With
Label1.Caption = "Text box will only accept digits 0 to 9. Try " & _ vbNewLine & "to type or paste " & _ "(ctrl-v or right click/paste) anything " & _ "other than numbers and see if you can."
'Subclass the textbox so we can intercept the WM_PASTE message oldTextBoxProc = SetWindowLong(Text1.hwnd, GWL_WNDPROC, AddressOf NewTextBoxProc) 'Give it a new style that only allows numbers SetWindowLong Text1.hwnd, GWL_STYLE, GetWindowLong(Text1.hwnd, GWL_STYLE) Or ES_NUMBER 'Show the window(text box) ShowWindow Text1.hwnd, 1End Sub Private Sub Form_Unload(Cancel As Integer) 'Unsubclass the textbox SetWindowLong Text1.hwnd, GWL_WNDPROC, oldTextBoxProc End Sub module:Option ExplicitPublic Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _ ByVal hwnd As Long, ByVal nIndex As Long) As LongPublic Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _ ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, _ ByVal Msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _ ByVal hwnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As LongPublic Declare Function ShowWindow Lib "user32" ( _ ByVal hwnd As Long, ByVal nCmdShow As Long) As LongPublic Const GWL_WNDPROC = (-4) Public Const GWL_STYLE = (-16) Public Const ES_NUMBER = &H2000& Public Const WM_PASTE = &H302Public oldTextBoxProc As LongPublic Function NewTextBoxProc(ByVal hwnd As Long, ByVal uMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long
If uMsg = WM_PASTE Then 'We want to trap all pasting to the textbox If CheckClipBoard Then 'Call a function to test the text to be pasted 'The text was all numberic in the clipboard so let the message go to the orig window proc NewTextBoxProc = CallWindowProc(oldTextBoxProc, hwnd, uMsg, wParam, lParam) Else 'Clipboard had non-numeric text in it NewTextBoxProc = -1 'Return a value to call. Do not pass to orig window proc End If Else 'Some message other than WM_PASTE was sent. Send it to the orig window proc NewTextBoxProc = CallWindowProc(oldTextBoxProc, hwnd, uMsg, wParam, lParam) End If
End FunctionPrivate Function CheckClipBoard() As Boolean Dim intIndex As Integer Dim strTemp As String
strTemp = Clipboard.GetText 'Guess what this does CheckClipBoard = True 'Initialize
For intIndex = 1 To Len(strTemp) Step 1 'Loop to check each char in the clipboard about to be pasted Select Case Mid$(strTemp, intIndex, 1) 'Extract the next char to check Case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" Case Else 'If we get here then there is non-numeric text CheckClipBoard = False intIndex = Len(strTemp) 'End loop End Select Next intIndexEnd Function
Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyDelete Then KeyCode = 0 End If End Sub
form:Option ExplicitPrivate Sub Form_Load() Dim ret As Long prevWndProc = GetWindowLong(Me.hWnd, GWL_WNDPROC) ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf WndProc) End Sub Private Sub Form_Unload(Cancel As Integer) Dim ret As Long ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, prevWndProc) End Submodule:Public Const GWL_WNDPROC = (-4) Public Const WM_COMMAND = &H111Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public prevWndProc As LongFunction WndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongIf Not (Msg = WM_COMMAND And wParam = 50331649) Then
Else WndProc = CallWindowProc(prevWndProc, hWnd, Msg, wParam, lParam) End IfEnd Function
form:Option ExplicitPrivate Sub Form_Load()
With Me
.Caption = "Truly numeric text box"
'Center form on screen
.Move (Screen.Width / 2) - (.Width / 2), (Screen.Height / 2) - (.Height / 2)
End With
Label1.Caption = "Text box will only accept digits 0 to 9. Try " & _
vbNewLine & "to type or paste " & _
"(ctrl-v or right click/paste) anything " & _
"other than numbers and see if you can."
'Subclass the textbox so we can intercept the WM_PASTE message
oldTextBoxProc = SetWindowLong(Text1.hwnd, GWL_WNDPROC, AddressOf NewTextBoxProc)
'Give it a new style that only allows numbers
SetWindowLong Text1.hwnd, GWL_STYLE, GetWindowLong(Text1.hwnd, GWL_STYLE) Or ES_NUMBER
'Show the window(text box)
ShowWindow Text1.hwnd, 1End Sub
Private Sub Form_Unload(Cancel As Integer)
'Unsubclass the textbox
SetWindowLong Text1.hwnd, GWL_WNDPROC, oldTextBoxProc
End Sub
module:Option ExplicitPublic Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
ByVal hwnd As Long, ByVal nIndex As Long) As LongPublic Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
ByVal hwnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As LongPublic Declare Function ShowWindow Lib "user32" ( _
ByVal hwnd As Long, ByVal nCmdShow As Long) As LongPublic Const GWL_WNDPROC = (-4)
Public Const GWL_STYLE = (-16)
Public Const ES_NUMBER = &H2000&
Public Const WM_PASTE = &H302Public oldTextBoxProc As LongPublic Function NewTextBoxProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
If uMsg = WM_PASTE Then 'We want to trap all pasting to the textbox
If CheckClipBoard Then 'Call a function to test the text to be pasted
'The text was all numberic in the clipboard so let the message go to the orig window proc
NewTextBoxProc = CallWindowProc(oldTextBoxProc, hwnd, uMsg, wParam, lParam)
Else 'Clipboard had non-numeric text in it
NewTextBoxProc = -1 'Return a value to call. Do not pass to orig window proc
End If
Else
'Some message other than WM_PASTE was sent. Send it to the orig window proc
NewTextBoxProc = CallWindowProc(oldTextBoxProc, hwnd, uMsg, wParam, lParam)
End If
End FunctionPrivate Function CheckClipBoard() As Boolean Dim intIndex As Integer
Dim strTemp As String
strTemp = Clipboard.GetText 'Guess what this does
CheckClipBoard = True 'Initialize
For intIndex = 1 To Len(strTemp) Step 1 'Loop to check each char in the clipboard about to be pasted
Select Case Mid$(strTemp, intIndex, 1) 'Extract the next char to check
Case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
Case Else 'If we get here then there is non-numeric text
CheckClipBoard = False
intIndex = Len(strTemp) 'End loop
End Select
Next intIndexEnd Function
If KeyCode = vbKeyDelete Then
KeyCode = 0
End If
End Sub
Dim ret As Long
prevWndProc = GetWindowLong(Me.hWnd, GWL_WNDPROC)
ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf WndProc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim ret As Long
ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, prevWndProc)
End Submodule:Public Const GWL_WNDPROC = (-4)
Public Const WM_COMMAND = &H111Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public prevWndProc As LongFunction WndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongIf Not (Msg = WM_COMMAND And wParam = 50331649) Then
Else
WndProc = CallWindowProc(prevWndProc, hWnd, Msg, wParam, lParam)
End IfEnd Function