Online Help

Introducing Comfort Keys Pro
How to buy Comfort Keys Pro
How to use Comfort Keys Pro
Keyboard shortcuts settings
Working with template manager
Working with clipboard manager
Using the on-screen keyboard
Controlling the input language
Customizing the keyboard type
Editing templates
Text tags
Editing shortcut icons
Action types
Run a program; open a document or folder
Open one or several Internet resources
Paste text
Play a keystroke macro
Connect/Disconnect from a network
Comfort Keys Pro actions
Audio control
Monitor control
Window control
Perform a system action
Change the language or case
Lock/Restart/Shutdown
Block key or shortcut
Replace key or shortcut
Settings
System
Appearance Theme
Keyboard Shortcuts
On-Screen Keyboard
Show/Hide
Position
Keys
Gestures
Zoom
Typing Aid
Floating Window
Clipboard Manager
Template Manager
Text Suggestions
Language Switcher
Language Bar
Shortcut Icons
Task Switching Window
Process History Window
Sounds
Dependencies
Security
Advanced
Development
How to show, close, fade, or move the on-screen keyboard
How to lock all settings
How to activate different keyboards
FAQ for developers
Command line parameters
Other issues
FAQ - Frequently asked questions
License Agreement

How to show, close, fade, or move the on-screen keyboard

You can use Windows Messages to manipulate the on-screen keyboard.


Like this:


WM_CSKEYBOARD = WM_USER + 192;

WM_CSKEYBOARDMOVE = WM_USER + 193;

WM_CSKEYBOARDRESIZE = WM_USER + 197;

 

// to show keyboard

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 1, 0);

 

// to close keyboard

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 2, 0);

 

// to fade keyboard

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 3, 0);

 

// to toggle (show/hide) keyboard

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 4, 0);

 

// to move keyboard (Left, Top - new position)

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARDMOVE, Left, Top);


// to resize keyboard

PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARDRESIZE, Width, Height);




Private Const WM_CSKEYBOARD = WM_USER + 192

Private Const WM_CSKEYBOARDMOVE = WM_USER + 193

Private Const WM_CSKEYBOARDRESIZE = WM_USER + 197

 

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As StringAs Long

 

'Code to show keyboard

Dim hWnd As Long

hWnd = FindWindow("TFirstForm", "CKeysFirstForm")

PostMessage hWnd, WM_CSKEYBOARD, 1, 0

 

'Code to close keyboard

Dim hWnd As Long

hWnd = FindWindow("TFirstForm", "CKeysFirstForm")

PostMessage hWnd, WM_CSKEYBOARD, 2, 0

 

'Code to move keyboard

Dim hWnd As Long

hWnd = FindWindow("TFirstForm", "CKeysFirstForm")

PostMessage hWnd, WM_CSKEYBOARDMOVE, 0, 0

 

'Code to resize keyboard

Dim hWnd As Long

hWnd = FindWindow("TFirstForm", "CKeysFirstForm")

PostMessage hWnd, WM_CSKEYBOARDMOVE, Width, Height


using System;

using System.Windows.Forms;

using System.Runtime.InteropServices;

 

public const Int32 WM_USER = 1024;

public const Int32 WM_CSKEYBOARD = WM_USER + 192;

public const Int32 WM_CSKEYBOARDMOVE = WM_USER + 193;

public const Int32 WM_CSKEYBOARDRESIZE = WM_USER + 197;

 

[DllImport("user32.dll", EntryPoint = "FindWindow")]

private static extern Int32 FindWindow(string _ClassName, string _WindowName);

 

[DllImport("User32.DLL")]

public static extern Boolean PostMessage(Int32 hWnd, Int32 Msg, Int32 wParam, Int32 lParam);

 

 

Int32 hWnd = FindWindow("TFirstForm", "CKeysFirstForm");

PostMessage(hWnd, WM_CSKEYBOARD, 1, 0 ); // Show

PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); // Hide

PostMessage(hWnd, WM_CSKEYBOARDMOVE, 0, 0); // Move to 0, 0

PostMessage(hWnd, WM_CSKEYBOARDRESIZE, 600, 300); // Resize to 600, 300


Const WM_CSKEYBOARD = &H400 + 192

Const WM_CSKEYBOARDMOVE = &H400 + 193

Const WM_CSKEYBOARDRESIZE = &H400 + 197

 

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As StringAs Integer 

Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntegerAs Integer 

 

'Open/show the Comfort Onscreen Keyboard 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) 

End Sub 

 

'Close the Comfort Onscreen Keyboard 

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 2, 0) 

End Sub 

 

'Move the Comfort Onscreen Keyboard; Move it first then show it 

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200) 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) 

End Sub 

 

'Toggle the Comfort Onscreen Keyboard 

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 4, 0) 

End Sub 

 

'Fade the Comfort Onscreen Keyboard 

Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 3, 0) 

End Sub 

 

'Change the keyboard type and show it 

Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click 

    'Change the Registry entry for the required keyboard 

    My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeys", "KeyboardName", "Name of your chosen keyboard") 

    'Open the keyboard 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) 

End Sub 

 

'Change to another keyboard type and show it 

Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click 

    'Change the Registry entry for the required keyboard 

    My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeys", "KeyboardName", "Name of another chosen keyboard") 

    'Open the keyboard 

    Dim hWnd As Integer 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm") 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) 

End Sub 


using namespace System::Runtime::InteropServices; 

using namespace System::Security::Permissions; 

using namespace Microsoft::Win32; 

 

const System::UInt32 WM_USER = 1024; 

const System::UInt32 WM_CSKEYBOARD = WM_USER + 192; 

const System::UInt32 WM_CSKEYBOARDMOVE = WM_USER + 193;  

 

[DllImport("user32.dll")] 

extern IntPtr FindWindow(String^ lpClassName, String^ lpWindowName); 

[DllImport("user32.dll")] 

extern IntPtr PostMessage(System::IntPtr hWnd, System::UInt32 Msg, int wParam, int lParam); 

[assembly:RegistryPermissionAttribute(SecurityAction::RequestMinimum, All = "HKEY_CURRENT_USER")]; 

 

 

....blah blah blah you normal code...

 

 

void button1_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

    // Open/show the Comfort Onscreen Keyboard 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); 

} 

void button2_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

        // close the Comfort Onscreen Keyboard 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); 

} 

void button3_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

    //Move the Comfort Onscreen Keyboard; Move it first then show it 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200); 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); 

} 

void button4_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

    //Toggle the Comfort Onscreen Keyboard 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARD, 4, 0); 

} 

void button5_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

    //Fade the Comfort Onscreen Keyboard 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARD, 3, 0); 

} 

void button6_Click(System::Object^  sender, System::EventArgs^  e) 

{ 

    //Change the keyboard type and show it 

    System::Object ^kname="NumPad"; 

 

    //Change the Registry entry for the required keyboard 

 

    RegistryKey ^key= Registry::CurrentUser->OpenSubKey ( "Software\\ComfortSoftware\\CKeys",true); 

    key->SetValue("KeyboardName",kname); 

 

    //Open the keyboard 

    IntPtr hWnd; 

    hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); 

    PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); 

}


/* 

 * This file is heavily based on Jawin: <a href="http://jawinproject.sourceforge.net/" rel="external">http://jawinproject.sourceforge.net/</a> 

 * 

 * assumes ComfortSoftware keyboard is loaded... 

 *  

 */ 

 

package client.keyboard; 

 

import java.io.ByteArrayInputStream; 

import java.io.IOException; 

 

import org.jawin.COMException; 

import org.jawin.FuncPtr; 

import org.jawin.ReturnFlags; 

import org.jawin.io.LittleEndianInputStream; 

import org.jawin.io.LittleEndianOutputStream; 

import org.jawin.io.NakedByteStream; 

 

public class ComfortSoftwareKeyboard { 

 

    protected static final String COMFORT_SOFTWARE_WINDOW_NAME = "CKeysFirstForm"; 

    protected static final String COMFORT_SOFTWARE_CLASS_NAME = "TFirstForm"; 

     

    protected static final int WM_USER = 1024; 

    protected static final int WM_CSKEYBOARD = WM_USER + 192; 

    protected static final int WM_CSKEYBOARDMOVE = WM_USER + 193; 

 

    protected static final Call FIND_WINDOW = new Call("USER32.DLL", "FindWindowW", "GG:I:", 8); 

    protected static final Call POST_MESSAGE = new Call("USER32.DLL", "PostMessageW", "IIII:I:", 16); 

     

    private static ComfortSoftwareKeyboard INSTANCE = new ComfortSoftwareKeyboard(); 

 

    public static ComfortSoftwareKeyboard getInstance() { 

        return INSTANCE; 

    } 

 

    protected int getWindowHandle() throws COMException, IOException { 

        FuncPtr findWindow = null; 

        findWindow = new FuncPtr(FIND_WINDOW.getDllName(), FIND_WINDOW.getFunctionName()); 

        NakedByteStream bs = new NakedByteStream(); 

        LittleEndianOutputStream leo = new LittleEndianOutputStream(bs); 

        leo.writeStringUnicode(COMFORT_SOFTWARE_CLASS_NAME); 

        leo.writeStringUnicode(COMFORT_SOFTWARE_WINDOW_NAME); 

        byte[] b = findWindow.invoke(FIND_WINDOW.getParameterDescription(), FIND_WINDOW.getStackSize(), bs, null, 

                ReturnFlags.CHECK_FALSE); 

        LittleEndianInputStream leis = new LittleEndianInputStream( 

                new ByteArrayInputStream(b)); 

        int l = leis.readInt(); 

        findWindow.close(); 

        return l; 

    } 

 

    public int move(int x, int y) throws COMException, IOException { 

        int hWnd = getWindowHandle(); 

 

        FuncPtr postMessage = null; 

        postMessage = new FuncPtr(POST_MESSAGE.getDllName(), POST_MESSAGE.getFunctionName()); 

        NakedByteStream bs = new NakedByteStream(); 

        LittleEndianOutputStream leo = new LittleEndianOutputStream(bs); 

 

        leo.writeInt(hWnd); 

        leo.writeInt(WM_CSKEYBOARDMOVE); 

        leo.writeInt(x); 

        leo.writeInt(y); 

 

        byte[] b = postMessage.invoke(POST_MESSAGE.getParameterDescription(), POST_MESSAGE.getStackSize(), bs, null, 

                ReturnFlags.CHECK_FALSE); 

        LittleEndianInputStream leis = new LittleEndianInputStream( 

                new ByteArrayInputStream(b)); 

        int l = leis.readInt(); 

        postMessage.close(); 

        return l; 

    } 

     

    public int setVisible(boolean visible) throws COMException, IOException { 

        int hWnd = getWindowHandle(); 

 

        FuncPtr postMessage = null; 

        postMessage = new FuncPtr(POST_MESSAGE.getDllName(), POST_MESSAGE.getFunctionName()); 

        NakedByteStream bs = new NakedByteStream(); 

        LittleEndianOutputStream leo = new LittleEndianOutputStream(bs); 

 

        leo.writeInt(hWnd); 

        leo.writeInt(WM_CSKEYBOARD); 

        leo.writeInt(visible ? 1 : 2); 

        leo.writeInt(0); 

 

        byte[] b = postMessage.invoke(POST_MESSAGE.getParameterDescription(), POST_MESSAGE.getStackSize(), bs, null, 

                ReturnFlags.CHECK_FALSE); 

        LittleEndianInputStream leis = new LittleEndianInputStream( 

                new ByteArrayInputStream(b)); 

        int l = leis.readInt(); 

        postMessage.close(); 

        return l; 

    } 

 

    public static void main(String[] args) throws Exception { 

        try { 

            ComfortSoftwareKeyboard keyboard = ComfortSoftwareKeyboard.getInstance(); 

            keyboard.setVisible(true); 

            Thread.sleep(1000); 

            keyboard.setVisible(false); 

            Thread.sleep(1000); 

            keyboard.setVisible(true); 

            for (int i = 0; i < 100;i++) { 

                keyboard.move(i, i); 

            } 

        } catch (COMException e) { 

        } finally { 

        } 

    } 

} 

 

class Call { 

    private int stackSize; 

    private String functionName; 

    private String parameterDescription; 

    private String dllName; 

     

    public Call(String dllName, String functionName, String parameterDescription, int stackSize) { 

        this.stackSize = stackSize; 

        this.functionName = functionName; 

        this.parameterDescription = parameterDescription; 

        this.dllName = dllName; 

    } 

    public int getStackSize() {return stackSize;} 

    public String getFunctionName() {return functionName;} 

    public String getParameterDescription() {return parameterDescription;} 

    public String getDllName() {return dllName;} 

}


If you can't use Windows Messages then download and try these files:

https://www.comfortsoftware.com/download/ShowKB.exe

https://www.comfortsoftware.com/download/HideKB.exe

https://www.comfortsoftware.com/download/ToggleKB.exe

https://www.comfortsoftware.com/download/MoveTopKB.exe

https://www.comfortsoftware.com/download/MoveBottomKB.exe

https://www.comfortsoftware.com/download/MoveLeftKB.exe

https://www.comfortsoftware.com/download/MoveRightKB.exe

https://www.comfortsoftware.com/download/MoveKB.exe (Command line format: MoveKB.exe Left Top)

https://www.comfortsoftware.com/download/SetNameKB.exe (Command line format: SetNameKB.exe KeyboardName)



If you are writing kiosk software using HTML, you can use the special JavaScript functions to control the on-screen keyboard.


With JavaScript, you can show, hide, or move the keyboard. Just use the special JavaScript functions to add keyboard-related information to the browser caption, and the application will monitor the caption for changes.


Download the file with JavaScript functions and examples from here: https://www.comfortsoftware.com/commander.html



WM_CSKEYBOARDMOVE: Solving the issue with moving the keyboard when using multiple screens with different DPI.


For example, Screen 1 has a resolution of 2560x1440 and is set to "125% scale" in Windows display settings. Screen 2 is 1920x1080 and is set to "100% scale".


Open the Windows 10 app compatibility settings of the CKeys.exe file and set the DPI behavior to "Application", which means that the application manages all DPI-related calculations. With this setting activated, you can pass physical pixel values to the move function of your API, and the keyboard window is then moved to exactly that position.


If you want to activate this compatibility mode programmatically (e.g., with your own installer), you have to set the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers:

"C:\Program Files\ComfortKeys\CKeys.exe"="~ HIGHDPIAWARE"


This will then apply to all users. Alternatively, you can place this key in the registry for the current user (HKCU).