Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How to send key events to any control in a process Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi All Versions
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Jonas Bilinkevicius 

I want to create a software keyboard in one form. When I press a key on the sofware 
keyboard, I would like to send the key's char to any form in my application.


The following method will send key events to any control in your own process. It 
will not work reliably for windows in other processes.

1   {
2   Procedure PostKeyEx
4   Parameters:
6   hWindow:
7   Target window to be send the keystroke
8   key:
9   Virtual keycode of the key to send. For printable keys this is simply the ANSI code 
10  (Ord(character)).
11  shift:
12  State of the modifier keys. This is a set, so you can set several of these keys 
13  (shift, control, alt, mouse buttons) in tandem. The TShiftState type is declared in 
14  the Classes Unit.
15  specialkey:
16  Normally this should be False. Set it to True to specify a key on the numeric 
17  keypad, for example.
18  If this parameter is true, bit 24 of the lparam for the posted WM_KEY* messages 
19  will be set.
21  Description:
23  This procedure sets up Windows key state array to correctly reflect the requested 
24  pattern of modifier keys and then posts a WM_KEYDOWN/WM_KEYUP message pair to the 
25  target window. Then Application.ProcessMessages is called to process the messages 
26  before the keyboard state is restored.
28  Error Conditions:
30  May fail due to lack of memory for the two key state buffers. Will raise an 
31  exception in this case.
33  Note:
35  Setting the keyboard state will not work across applications running in different 
36  memory spaces on Win32 unless AttachThreadInput is used to connect to the target 
37  thread first.
39  Created:
41  02/21/96 16:39:00 by Peter Below
42  }
44  procedure PostKeyEx(hWindow: HWnd; key: Word; const shift: TShiftState; specialkey:
45    Boolean);
46  type
47    TBuffers = array[0..1] of TKeyboardState;
48  var
49    pKeyBuffers: ^TBuffers;
50    lparam: LongInt;
51  begin
52    {check if the target window exists}
53    if IsWindow(hWindow) then
54    begin
55      {set local variables to default values}
56      pKeyBuffers := nil;
57      lparam := MakeLong(0, MapVirtualKey(key, 0));
58      {modify lparam if special key requested}
59      if specialkey then
60        lparam := lparam or $1000000;
61      {allocate space for the key state buffers}
62      New(pKeyBuffers);
63      try
64        {Fill buffer 1 with current state so we can later restore it.
65  		 Null out buffer 0 to get a "no key pressed" state.}
66        GetKeyboardState(pKeyBuffers^[1]);
67        FillChar(pKeyBuffers^[0], Sizeof(TKeyboardState), 0);
68        {set the requested modifier keys to "down" state in the buffer}
69        if ssShift in Shift then
70          pKeyBuffers^[0][VK_SHIFT] := $80;
71        if ssAlt in Shift then
72        begin
73          {Alt needs special treatment since a bit in lparam needs also be set}
74          pKeyBuffers^[0][VK_MENU] := $80;
75          lparam := lparam or $20000000;
76        end;
77        if ssCtrl in Shift then
78          pKeyBuffers^[0][VK_CONTROL] := $80;
79        if ssLeft in Shift then
80          pKeyBuffers^[0][VK_LBUTTON] := $80;
81        if ssRight in Shift then
82          pKeyBuffers^[0][VK_RBUTTON] := $80;
83        if ssMiddle in Shift then
84          pKeyBuffers^[0][VK_MBUTTON] := $80;
85        {make out new key state array the active key state map}
86        SetKeyboardState(pKeyBuffers^[0]);
87        {post the key messages}
88        if ssAlt in Shift then
89        begin
90          PostMessage(hWindow, WM_SYSKEYDOWN, key, lparam);
91          PostMessage(hWindow, WM_SYSKEYUP, key, lparam or $C0000000);
92        end
93        else
94        begin
95          PostMessage(hWindow, WM_KEYDOWN, key, lparam);
96          PostMessage(hWindow, WM_KEYUP, key, lparam or $C0000000);
97        end;
98        {process the messages}
99        Application.ProcessMessages;
100       {restore the old key state map}
101       SetKeyboardState(pKeyBuffers^[1]);
102     finally
103       {free the memory for the key state buffers}
104       if pKeyBuffers < > nil then
105         Dispose(pKeyBuffers);
106     end;
107   end;
108 end;
110 procedure TForm1.SpeedButton2Click(Sender: TObject);
111 var
112   W: HWnd;
113 begin
114   W := Memo1.Handle;
115   PostKeyEx(W, VK_END, [ssCtrl, ssShift], False); {select all}
116   PostKeyEx(W, Ord('C'), [ssCtrl], False); {copy to clipboard}
117   PostKeyEx(W, Ord('C'), [ssShift], False); {replace with C}
118   PostKeyEx(W, VK_RETURN, [], False); {new line}
119   PostKeyEx(W, VK_END, [], False); {go to end}
120   PostKeyEx(W, Ord('V'), [ssCtrl], False); {paste from keyboard}
121 end;

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC