1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 7 StdCtrls; 8 9 type 10 TForm1 = class(TForm) 11 Edit1: TEdit; 12 Edit2: TEdit; 13 Edit3: TEdit; 14 Edit4: TEdit; 15 Edit5: TEdit; 16 Edit6: TEdit; 17 Label1: TLabel; 18 procedure FormCreate(Sender: TObject); 19 procedure FormDestroy(Sender: TObject); 20 private 21 { Private declarations } 22 public 23 { Public declarations } 24 end; 25 26 {the prototype for the new keyboard hook function} 27 function KeyboardHook(nCode: Integer; wParam: WPARAM; 28 lParam: LPARAM): LResult; stdcall; 29 30 var 31 Form1: TForm1; 32 WinHook: HHOOK; // a handle to the keyboard hook function 33 34 implementation 35 36 {$R *.DFM} 37 38 procedure TForm1.FormCreate(Sender: TObject); 39 begin 40 {install the keyboard hook function into the keyboard hook chain} 41 WinHook:=SetWindowsHookEx(WH_KEYBOARD, @KeyboardHook, 0, GetCurrentThreadID); 42 end; 43 44 procedure TForm1.FormDestroy(Sender: TObject); 45 begin 46 {remove the keyboard hook function from the keyboard hook chain} 47 UnhookWindowsHookEx(WinHook); 48 end; 49 50 function KeyboardHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LResult; 51 begin 52 {if we can process the hook information...} 53 if (nCode>-1) then 54 {...was the TAB key pressed?} 55 if (wParam=VK_TAB) then 56 begin 57 {if so, output a beep sound} 58 MessageBeep(0); 59 60 {indicate that the message was processed} 61 Result := 1; 62 end 63 else 64 {...was the RETURN key pressed?} 65 if (wParam=VK_RETURN) then 66 begin 67 {if so, and if the key is on the up stroke, cause 68 the focus to move to the next control} 69 if ((lParam shr 31)=1) then 70 Form1.Perform(WM_NEXTDLGCTL, 0, 0); 71 72 {indicate that the message was processed} 73 Result := 1; 74 end 75 else 76 {otherwise, indicate that the message was not processed.} 77 Result := 0 78 else 79 {we must pass the hook information to the next hook in the chain} 80 Result := CallNextHookEx(WinHook, nCode, wParam, lParam); 81 end; 82 83 end.