It seems that silly Adam was storing a UINT scan code because MapVirtualKey wanted a UINT. However, WM_CHAR only has a BYTE scan code in its lParam. Therefore, we got garbage on repeated key events, which bungled up the key binding parser.