>Microsoft appears to remain silent on this matter
Well, the VB documentation explicitly states that the KeyAscii value can be modified in the KeyPress event, and explicitly does not say any such thing about the KeyCode for the KeyUp and KeyDown events, so that's pretty clear to me ..
Anyway, time for the longer explanation (this simplifies a few things BTW)
What we need to understand is that VB hides away much of the complexity of Windows by wrapping large chunks of the API in friendly commands and objects; for example the textbox is a VB wrapper for the edit control
But that has drawbacks to the VB programmer because on occassions it is difficult to see what is going on.
For this particular scenario we need to understand several factors:
Firstly, the whole process of converting a key press into a character is driven by three Windows messages: WM_KEYDOWN, WM_CHAR, and WM_KEYUP
WM_CHAR always follows WM_KEYDOWN, being a translation of the data provided by by the WM_KEYDOWN messages.
These three messages are are received by your VB application (well, a control in the app) and in turn raise the KeyDown, KeyPress, and KeyUp events which is what we get to see (and, as already stated, the MS people clearly decided that being able to modify KeyCode was not something they wanted to be available in VB, whilst altering KeyAscii was). But it is vitally important to realise that the Windows messages that drive the show - if a VB application/control doesn't receive a WM_CHAR for some reason event then you won't get a corresponding KeyPress event.
So, we know that modifying the KeyCode has no real effect. Why then does it appear to do so when we set a break point. More to the point why does it now appear to eat every keystroke?
Well becaue the moment you press a key you generate WM_KEYDOWN. This in turn raises the KeyDown event which, because of the break point, switches focus to the IDE's window. Now the WM_CHAR and WM_KEYUP messages are delivered to that window instead of to the VB application/control originally intended. Without the WM_CHAR event the edit control never gets told what ASCII character to enter at the insertion point, so the effect is that the key press is eaten - not by the KeyPress event, but by the IDE
You can see this for yourself with a simple bit of code, and a form with a textbox:
Option Explicit
Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
Debug.Print "key down"
End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer)
Debug.Print "key press"
End Sub
Private Sub Text1_KeyUp(KeyCode As Integer, Shift As Integer)
Debug.Print "key up"
End Sub
Run this without a breakpoint, and you will see "key down", "key press", and "key up" printed in the immediate window.
Now put a breakpoint on
Debug.Print "key down"
And run the code again. Now you'll only see "key down" in the immediate window