Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Customized Onscreen Keyboard in C#

5.00/5 (6 votes)
11 Aug 2021CPOL4 min read 28.8K   2.3K  
Customized onscreen keyboard in C# for Windows
I had built onscreen keyboards for several software applications, but I had never made one full-fledged keyboard with 101+ keys. So, I decided to tackle this project and build my onscreen keyboard in C#. In this article, I have shared my approach and the source code, so you will have a starting point if you wish to continue.

Introduction

If you have ever built software for touchscreen devices, you know that having an onscreen keyboard is an essential component. Windows comes with an Onscreen keyboard as one of its built-in Ease of Access tools.
Windows OSK is a solution, but you don’t have much control over its functions and behavior, let alone building new tasks to it!

In this article, I show what are the basic methods to build an onscreen keyboard for Windows and customize it.

Background

I had built onscreen keyboards for several software applications, but I had never made one full-fledged keyboard with 101+ keys. In a recent project, we needed a complete onscreen keyboard to be included and we can control it.

So, I ended working on this project and what you see here is the results of my work. You can expand it and build it to suit your needs.

The Key Method

The “key” to build your Onscreen Keyboard, is to use SendKeys.Send method:

C#
SendKeys.Send(string)

This method sends keystrokes to the active application. For example, if you want to click a button and send the TAB keystroke, you use the following method:

C#
SendKeys.Send("{TAB}");

If your request does not represent valid keystrokes, you will get an ArgumentException in your code.

Notes

  1. Sometimes, you need to send more than one character to get a specific key.

    For example, to specify the open parentheses sign, use “{{}”.

    C#
    SendKeys.Send("{}}");
  2. The plus sign (+), caret (^), percent sign (%), tilde (~), and parentheses () have special meanings to SendKeys. To specify one of these characters, enclose it within braces ({}).
  3. To specify characters that aren’t displayed when you press a key, such as ENTER or TAB, and keys that represent actions rather than characters, you must use specific codes.

For example:

C#
SendKeys.Send("{MULTIPLY}"); //The Multiply key on the number keypad
C#
SendKeys.Send("{ADD}");      //The Add key on the number keypad

Handling SHIFT, CTRL, and ALT

Combination keys, such as CTRL + Key, SHIFT + Key, and ALT + Key, are possible by using caret (^), plus(+), and percent sign (%).

To specify to hold down CTRL while S is pressed, followed by D without SHIFT, use “^SD”.

To specify to hold down SHIFT and press A and B, use “+(AB)”.

C#
SendKeys.Send("^({F10})"); //CTRL + F10
C#
SendKeys.Send("+({F10})"); //Shift + F10
C#
SendKeys.Send("%({F10})"); //ALT + F10

Planning the Keyboard Layout

I decided to go by the layout of my physical keyboard:

Physical Keyboard

I opened a new C# Winforms with the .NET Framework project in Visual Studio.
I added my keys, according to the physical keyboard layout:

Onscreen Keyboard layout

For the majority of the keys, you can use a button control, except for these special keys, which need to be CheckBox controls:

CAPSLOCK
SHIFT
CTRL
ALT
NUM LOCK

So, when the CAPSLOCK key is in the on mode, you have a checked CheckBox that identifies capital letters. CAPSLOCK off creates keystrokes for lowercase letters.

For keys with two characters, such as 2 (@) or 7 (&), we have to check the status of the SHIFT button and generate the proper keystroke accordingly.

SHIFT + 2 should send @ sign.

Similar situations apply to the combination keys such as CTRL + C (Copy), CTRL + P (Paste), and so on.

Image 3

C#
if (capslock.Checked || lshift.Checked || rshift.Checked)
 { 
SendKeys.Send("B"); lshift.Checked = false; rshift.Checked = false; 
} 
else { 
SendKeys.Send("b"); 
}

To identify when any of the checkboxes are in a checked state, I use background color:

C#
if (capslock.Checked == true) 
{ 
   capslock.BackColor = System.Drawing.ColorTranslator.FromHtml("#0076D7"); 
} 
else 
   capslock.BackColor = System.Drawing.ColorTranslator.FromHtml("#333333");

Custom Keys

Now that I have complete control of my onscreen keyboard, I want to add custom keys. Imagine Custom keys as a shortcut to send two or more characters in one keystroke.

Image 4

Some more cosmetic details include adding a row with CAPS, Insert, and NUM LOCK key status. I change the visibility of the labels for CAPS and NUM depends on the On or Off status of the corresponding keys. I also added the code to change the background color of the keys as you hover the mouse over them.

Image 5

Border Style Issue

If you select the None option from your form properties for the FormBorderStyle, you will not be able to move your keyboard around the screen and change its position.

If you don’t mind the standard Windows border, you can choose an option that best fits your taste and usage of your keyboard.

I wanted to get rid of the border and have my border style. So this is what I have done:

  1. I set the FormBorderStyle to None
  2. Placed all my keys to a panel, which is sitting on the main form
  3. Changed the form’s background color to create a contrast with the panel’s background color

Now I have my colors and make-shift border, but how can I move my onscreen keyboard?

The trick here requires a Win32 API:

C#
[DllImportAttribute("user32.dll")] public static extern int SendMessage
                                   (IntPtr hWnd, int Msg, int wParam, int lParam); 
[DllImportAttribute("user32.dll")] public static extern bool ReleaseCapture();
C#
private void Form1_MouseDown(object sender, MouseEventArgs e)
{ 
 if (e.Button == MouseButtons.Left) 
  { 
    ReleaseCapture(); 
    SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); 
  } 
}

Voila!

I have an onscreen keyboard with customized background and border style, which I can move around the screen and add custom keys to it.

Points of Interest

As I was working on this project, I came up with so many ideas to expand the normal onscreen keyboard to something much more. The Custom keys was one that I implemented in this code.

History

  • 9th August, 2021: First release of this code

I hope to get another chance to work on this project again, and perhaps port it to Xamarin.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)