OK, so it was a little more complicated than my quicky note. Here's some more details and a sample project.
In the textbox callback, you need to check EVENT_VAL_CHANGED, not EVENT_KEYPRESS. KEYPRESS occurs before the value is updated.
Then, with a textbox, call ResetTextBox to update the text, not SetCtrlVal (which appends to a textbox).
If you want to catch a keystroke anywhere in the textbox, you need to call GetCtrlAttribute to find the cursor position (ATTR_TEXT_SELECTION_START), and SetCtrlAttribute when you're done to restore the original cursor position (lost on a call to ResetTextBox).
Is that better?
Look at the attached sample project which lets you choose upper case, lower case, or mixed.