Science, Tech, Math › Computer Science Intercepting Keyboard Input With Delphi Share Flipboard Email Print Delphi Keyboard Hook for TImage. About.com Computer Science Delphi Programming Advanced Delphi Tutorials PHP Programming Perl Python Java Programming Javascript Programming C & C++ Programming Ruby Programming Visual Basic View More By Zarko Gajic Zarko Gajic Twitter Computer Science Expert MSCS, Computer Science, University of Osijek Zarko Gajic is experienced in SQL and has working knowledge of DB systems such as MS SQL Server, Firebird, Interbase, and Oracle. He is also proficient in XML, DHTML, and JavaScript. Learn about our Editorial Process Updated on May 14, 2018 Consider for a moment creation of some fast arcade game. All the graphics are displayed, let's say, in a TPainBox. TPaintBox is unable to receive the input focus — no events are fired when the user presses a key; we cannot intercept cursor keys to move our battleship. Delphi help! Intercept Keyboard Input Most Delphi applications typically handle user input through specific event handlers, those that enable us to capture user keystrokes and process mouse movement. We know that focus is the ability to receive user input through the mouse or keyboard. Only the object that has the focus can receive a keyboard event. Some controls, such as TImage, TPaintBox, TPanel, and TLabel cannot receive focus. The primary purpose of most graphic controls is to display text or graphics. If we want to intercept keyboard input for controls that cannot receive the input focus we'll have to deal with Windows API, hooks, callbacks and messages. Windows Hooks Technically, a "hook" function is a callback function that can be inserted in the Windows message system so an application can access the message stream before other processing of the message takes place. Among many types of windows hooks, a keyboard hook is called whenever the application calls the GetMessage() or PeekMessage() function and there is a WM_KEYUP or WM_KEYDOWN keyboard message to process. To create a keyboard hook that intercepts all keyboard input directed to a given thread, we need to call SetWindowsHookEx API function. The routines that receive the keyboard events are application-defined callback functions called hook functions (KeyboardHookProc). Windows calls your hook function for each keystroke message (key up and key down) before the message is placed in the application's message queue. The hook function can process, change or discard keystrokes. Hooks can be local or global. The return value of SetWindowsHookEx is a handle to the hook just installed. Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook. Keyboard Hook Example As a demonstration of keyboard hooks, we'll create a project with graphical control that can receive key presses. TImage is derived from TGraphicControl, it can be used as a drawing surface for our hypothetical battle game. Since TImage is unable to receive keyboard presses through standard keyboard events we'll create a hook function that intercepts all keyboard input directed to our drawing surface. TImage Processing Keyboard Events Start new Delphi Project and place one Image component on a form. Set Image1.Align property to alClient. That's it for the visual part, now we have to do some coding. First, we'll need some global variables: var Form1: TForm1; KBHook: HHook; {this intercepts keyboard input} cx, cy : integer; {track battle ship's position} {callback's declaration} function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall; implementation ... To install a hook, we call SetWindowsHookEx in the OnCreate event of a form. procedure TForm1.FormCreate(Sender: TObject) ; begin {Set the keyboard hook so we can intercept keyboard input} KBHook:=SetWindowsHookEx(WH_KEYBOARD, {callback >} @KeyboardHookProc, HInstance, GetCurrentThreadId()) ; {place the battle ship in the middle of the screen} cx := Image1.ClientWidth div 2; cy := Image1.ClientHeight div 2; Image1.Canvas.PenPos := Point(cx,cy) ; end; To free system resources associated with the hook, we must call the UnhookWindowsHookEx function in the OnDestroy event: procedure TForm1.FormDestroy(Sender: TObject) ; begin {unhook the keyboard interception} UnHookWindowsHookEx(KBHook) ; end; The most important part of this project is the KeyboardHookProc callback procedure used to process keystrokes. function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt; begin case WordParam of vk_Space: {erase battle ship's path} begin with Form1.Image1.Canvas do begin Brush.Color := clWhite; Brush.Style := bsSolid; Fillrect(Form1.Image1.ClientRect) ; end; end; vk_Right: cx := cx+1; vk_Left: cx := cx-1; vk_Up: cy := cy-1; vk_Down: cy := cy+1; end; {case} If cx < 2 then cx := Form1.Image1.ClientWidth-2; If cx > Form1.Image1.ClientWidth -2 then cx := 2; If cy < 2 then cy := Form1.Image1.ClientHeight -2 ; If cy > Form1.Image1.ClientHeight-2 then cy := 2; with Form1.Image1.Canvas do begin Pen.Color := clRed; Brush.Color := clYellow; TextOut(0,0,Format('%d, %d',[cx,cy])) ; Rectangle(cx-2, cy-2, cx+2,cy+2) ; end; Result:=0; {To prevent Windows from passing the keystrokes to the target window, the Result value must be a nonzero value.} end; That's it. We now have the ultimate keyboard processing code. Note just one thing: this code is in no way restricted to be used only with TImage. The KeyboardHookProc function serves as a general KeyPreview & KeyProcess mechanism. Cite this Article Format mla apa chicago Your Citation Gajic, Zarko. "Intercepting Keyboard Input With Delphi." ThoughtCo, Feb. 16, 2021, thoughtco.com/intercepting-keyboard-input-1058465. Gajic, Zarko. (2021, February 16). Intercepting Keyboard Input With Delphi. Retrieved from https://www.thoughtco.com/intercepting-keyboard-input-1058465 Gajic, Zarko. "Intercepting Keyboard Input With Delphi." ThoughtCo. https://www.thoughtco.com/intercepting-keyboard-input-1058465 (accessed May 30, 2023). copy citation