Prevent TouchKeyboard from grabbing the focus
I've written a little app in Delphi for a Tablet PC. So there's no keyboard. And there's a small form in the application where the user can enter driver names. I wanted to put a TouchKeyboard on the form but as the form itself is small it's not possible to accommodate the virtual keyboard. I can make the keyboard's size small but in that case it'll be very difficult to type. So I've decided to write another app that is composed of just a keyboard. When开发者_StackOverflow社区 a DBEdit in the main application is focused I want to execute the Touchkeyboard application and when DBEdit loses focus shut down the Touchkeyboard app. One of my questions is how to prevent Touchkeyboard from grabbing focus on launch. And the other one is how I can display the Touchkeyboard just under the main application. Thanks in advance.
You don't need another app. Just create another form, that way you can work with focuses and hiding better. I am not sure what you mean by "just under" your app, but I suppose you mean the position of the window should be below the application window. See this snippet:
There are 2 forms: MainForm and KeyboardForm.
unit MainFormUnit;
uses (...),KeyboardForm;
(...)
var KeybdShown: boolean = false;
procedure TMainForm.InputEditEnter(Sender: TObject); // OnEnter event
begin
if not KeybdShown then begin
KeybdShown:=true;
KeyboardForm.Top:=Top+ClientHeight;
KeyboardForm.Left:=Left;
KeyboardForm.ShowKeyboard(InputEdit); //Shows the keyboard form and sends our edit as parameter
end;
end;
procedure TMainForm.InputEditExit(Sender: TObject); // OnExit event
begin
KeyboardForm.Hide;
KeybdShown:=false;
end;
...
unit KeyboardFormUnit;
var FocusedControl: TObject;
implementation
uses MainFormUnit;
procedure TKeyboardForm.FormKeyPress(Sender: TObject; var Key: Char);
var VKRes: SmallInt;
VK: byte;
State: byte;
begin
VKRes:=VkKeyScanEx(Key, GetKeyboardLayout(0)); // Gets Virtual key-code for the Key
vk:=vkres; // The virtualkey is the lower-byte
State:=VKRes shr 8; // The state is the upper-byte
(FocusedControl as TEdit).SetFocus; // Sets focus to our edit
if (State and 1)=1 then keybd_event(VK_SHIFT,0,0,0); // These three procedures
if (State and 2)=2 then keybd_event(VK_CONTROL,0,0,0); // send special keys(Ctrl,alt,shift)
if (State and 4)=4 then keybd_event(VK_MENU,0,0,0); // if pressed
keybd_event(VK,0,0,0); // sending of the actual keyboard button
keybd_event(VK,0,2,0);
if (State and 1)=1 then keybd_event(VK_SHIFT,0,2,0);
if (State and 2)=2 then keybd_event(VK_CONTROL,0,2,0);
if (State and 4)=4 then keybd_event(VK_MENU,0,2,0);
Key:=#0;
end;
procedure TKeyboardForm.ShowKeybd(Focused: TObject);
begin
FocusedControl:=Focused;
Show;
end;
And this is basically all you need to handle showing/hiding the form. Since the KeyboardForm is not shown on-start, it doesn't take focus, (unless the Edit has TabOrder set to 0 with TabStop true - then the OnEnter event fires with the start of the application).
How it works
- When you select an Edit, the ShowKeyboard function is called, passing the edit as a parameter
- The touch keyboard is shown and with each click it fires the OnKeyPress event of TKeyboardForm (!!! set KeyPreview to true)
- The character is decoded to actual keyboard buttons (combination of Shift, Alt, Control and other buttons)
- These decoded keystrokes are sent to the edit
Note: SendInput() can be used instead of keybd_event.
for very interesting articles and discussion around virtual keyboard design, see http://www.virtual-keyboard-design.com
Responses to my successful attempt to provide a Delphi keyboard may be of interest.
精彩评论