Mega Code Archive

 
Categories / Delphi / Examples
 

Map keys with Application OnMessage

Title: Map keys with Application OnMessage Question: This event gives you some possibilities to do mapping to user pressed keys. For example, map Return to Tab, decimal point mapping, numlock mapping. Answer: The following code, that you have to use with Application OnMessage event, has some examples of how to do keyboard mapping. But remember that some samples, like the 'Enter like Tab' have a major flaw. The problem is that because Application OnMessage occurs before all other events, the key will be maped before the control receive the message. This means that if you have for example a TMemo, the enter will be mapped, and you will not have the chance to use the enter to add a new line. If you search D3k for some artcicles about mapping Enter to tab, you'll find some good articles. Anyway here is the code: procedure SetVKeyState(vkey: Byte; down: Boolean); // This is a routine to help doing a key change var keys: TKeyboardState; begin GetKeyboardState(keys); if Down then keys[vkey] := keys[vkey] or $80 else keys[vkey] := keys[vkey] and $7F; SetKeyboardState(keys); end; procedure TForm1.ApplicationEventsMessage(var Msg: tagMSG; var Handled: Boolean); var cCode: Integer; begin case Msg.Message of WM_KEYDOWN, WM_KEYUP: begin // Map Return to Tab if (Msg.wParam = VK_RETURN) {and ((Msg.lParam and $1000000) 0) } then // If you want to map only the numpad return key, uncomment the above condition begin Msg.wParam := VK_TAB; Msg.lParam := MakeLParam(Loword(msg.lparam), MapVirtualkey(VK_TAB, 0) or (HiWord(msg.lparam) and $FE00)); end; // Map the '+' to 'Tab' and '-' to 'Shift-Tab' case msg.wparam of VK_ADD, VK_SUBTRACT: begin if Msg.wparam = VK_SUBTRACT then SetVKeyState(VK_SHIFT, (Msg.Message = WM_KEYDOWN)); Msg.wparam := VK_TAB; Msg.lparam := MakeLong(LoWord(msg.lparam), (HiWord(Msg.lparam) and $FE00) + MapVirtualKey(Msg.wparam, 0)); end; end; // Map NumPad when NumLock not active if (GetKeyState(VK_NUMLOCK) = 0) and ((Msg.lparam and $1000000) = 0) then begin ccode := 0; case Msg.wparam of VK_HOME: ccode := VK_NUMPAD7; VK_UP: ccode := VK_NUMPAD8; VK_PRIOR: ccode := VK_NUMPAD9; VK_LEFT: ccode := VK_NUMPAD4; VK_CLEAR: ccode := VK_NUMPAD5; VK_RIGHT: ccode := VK_NUMPAD6; VK_END: ccode := VK_NUMPAD1; VK_DOWN: ccode := VK_NUMPAD2; VK_NEXT: ccode := VK_NUMPAD3; VK_INSERT: ccode := VK_NUMPAD0; VK_DELETE: ccode := VK_DECIMAL; end; if ccode 0 then Msg.Wparam := ccode; end; // Map decimal point to Windows Decimal Separator if (Msg.wparam = VK_DECIMAL) then begin Msg.wparam := VkKeyScan(DecimalSeparator); Msg.lparam := MakeLParam(LoWord(msg.lparam), (HiWord(Msg.lparam) and $FE00) + MapVirtualKey(Msg.wparam, 0)); end; end; end; end;