How to position the On-Screen Keyboard window?

delphi, on-screen-keyboard

Solution

You can use FindWindow using the window class "OSKMainClass" to get the window handle, and then SetWindowPos on that handle to position it to the coordinates you want. (You may need to use the control's ClientToScreen method to convert to the proper coordinates, but I'll let you figure that part out.)

// Off the top of my head - not at a machine that has a Delphi compiler at
// the moment.
var
  OSKWnd: HWnd;
begin
  OSKWnd := FindWindow(PChar('OSKMainClass'), nil);
  if OSKWnd <> 0 then
  begin
    SetWindowPos(OSKWnd, 
                 HWND_BOTTOM, 
                 NewPos.Left, 
                 NewPos.Top, 
                 NewPos.Width,
                 NewPos.Height, 
                 0);
  end;
end;

Code taken in part from a CodeProject article related to the same topic. I got the window class using AutoHotKey's Window Spy utility.

Notes:

Remy Lebeau points out in a comment that you should make sure to use `CreateProcess()` or `ShellExecuteEx()` so that you get back a process handle that can then be passed to `WaitForInputIdle()` before calling `FindWindow()`. Otherwise the call to `FindWindow()` may happen before OSK creates the window.

mghie points out in a comment that the only way he could get this to work was by running the app as Administrator; otherwise the call to `SetWindowPos()` resulted in an "Access Denied (5)".

Problem

After launching osk.exe with ShellExecuteEx() I would like to position the keyboard window relative to the data-entry fields, so that it doesn't cover them. How do I set the window position for the osk before calling it? Also, how can I have the application hide the osk when I am finished?

Original source

Related problems