Myslím, že se to stačí podvrhnout dřív VK_NUMLOCK, než dorazí téměř současně stisklá klávesa. Z popisu keybd_event to celkem vyplývá: The keyboard driver's interrupt handler calls the keybd_event function. Dle mého stačí hook poslat dřív VK_NUMLOCK, než vyšle ovladač klávesnice další znak taktéž přes API keybd_event. Bafrování kláves se koná až uvnitř volání keybd_event.
Ad PS: Vím, už jsem na to narazil, když jsem dělal kdysi dávno global hook na překlad z čtečky čárového kódu která se cpe mezi klávesnici. Ta nedávala čísla při české klávesnici, ale psala ěščřžýáíé. Protože bylo potřeba ovlivnit víc aplikací (a cizích), řešil jsem to global hook a překladem na vlastní triko v té dll .
Nevím, jestli ten MS keyboard layout editor pomůže. Jestli ten NumLock chytaj Widle někde v hlubinách svých střev, jestli se ten layout nebude dělat až potom. Vyměnit Keyboard Layout by mělo jít přímo API funkcí LoadKeyboardLayout. Možná by mohlo stačit i API MapVirtualKey - už bohužel nemám čas to vyzkoušet.
//Edit: Ještě mě napadlo, jestli by nešlo rychlejc nahazovat NumLock API funkcí SetKeyboardState - kterou to sice nejde v normálním programu (resp jde, ale nezmění stav LEDek), protože nemá přístupný "global input state of the system" ale v global hoocku by mít mohla . Tím by se totiž daly vymazat i současně zmáčknuté klávesy.