Click here to Skip to main content
Click here to Skip to main content

Read and Update CAPS or NUM Lock Status from your Application

, 23 May 2008 GPL3
Rate this:
Please Sign up or sign in to vote.
It describes how to read and update the toggle keys (NUM lock, CAPS lock, etc.) using WIN32 API in a C# application

Introduction

A few months ago, I was developing a desktop application for a client. After completing the requirements, I was enhancing the UI specially the main form. In the previous versions of Microsoft Word (before version 2007), there are some labels which are clickable and reflect the changes to the keyboard (details below) and I wanted to add these features to my applications.

HTML documentation of the code has also been included along the source in the zip file. Select the index.html in the HTML folder to view it.

Toggle Keys

There are three LEDs on almost every keyboard, i.e. NUM lock, CAPS lock and SCROLL lock. These LEDS shows the status of the respective keys. As these keys are either in ON state or OFF state, their value is toggled between 1 and 0, so these are called Toggle Keys. The INSERT key is also included in toggle keys, although there is no LED for it but its value is either ON (insert mode) or OFF (overwrite mode), so it is also included in this category.

In my application, I wanted to add the status of NUM lock and CAPS lock. I Googled it and got a solution using Microsoft.VisualBasic.Devices. It was a pretty simple solution but with some limitation. You can only read the status of the keys, no method to set the status of the keys. (I am not going to discuss this here, I might write a separate post for it). The application deadline was very close and I was not able to implement this extra feature as I had planned. Since this feature was not requested by the client, it was delivered with read only options.

Objective

The objective of the post is to get and set the CAPS lock and NUM lock, etc. from the application.

Background

WIN32 API provides a lot of low level functions to access the system hardware. Due to high level of security, these features are not directly available in .NET Framework. To perform low level interaction with hardware, we have to call the WIN32 API methods in .NET using some special syntax.

For this purpose, System.Runtime.InteropServices namespace must be included.

Following the C language style, we have to declare the function so that we could use the method in the code.

Declaration

[DllImport("APIname.dll")]
internal static extern returnType 
MethodName (argument(s)); 

Usage

You can use this method as any other local method:

 int nvar = Win32APIMethodName();

WIN32 API Methods Used

Two methods of WIN32 API have been used to achieve the desired results.

[DllImport("user32.dll")] 
internal static extern short GetKeyState(int keyCode);

The GetKeyState method returns the status of the key specified through the key code argument. Return value will be 0 if off and 1 if on.

Parameter

keyCode: Specifies a virtual-key code for the key to be checked. The code must be a value in the range 1 to 254. For a complete list, see Virtual-Key Codes.

Please check MSDN for a complete description.

[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

This function is useful to simulate Key presses to the window with focus.

Parameters

bVk: Specifies a virtual-key code. The code must be a value in the range 1 to 254. For a complete list, see Virtual-Key Codes.

bScan: Specifies a hardware scan code for the key.

dwFlags: Specifies various aspects of function operation. Normally KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP are used. If specified, the key is being released. If not specified, the key is being depressed.

dwExtraInfo: Specifies an additional value associated with the key stroke.

Please check MSDN for complete description.

Note: In the test application, instead of the Virtual key Codes, we will be using System.Keys enumeration where required.

Creating a Test Application

Create a new Windows Application Project in C#. From Menus & Toolbar section of the control box, add a Status Strip on your form. Add three labels to the status strip. Name them as lblINS, lblNUM and lblCAPS respectively. It is better to set their width to 40.

Set the DoubleClickEnabled property of these labels to true.

Set the AutoSize property of these labels to false.

Generate the DoubleClick event for these labels to handle the double click action, e.g.

private void lblNUM_DoubleClick(object sender, EventArgs e)
{
    PressKeyboardButton(Keys.NumLock);
UpdateNUMLock();
}

Form Events

Set the KeyPreview property of the form to true. This will help to pass the keys pressed on the child controls to the parent control (form) (for better understanding of the property, build the attached test application with this property set to false).

In the design view, double click the form to generate its Form_Load event and call the method UpdateKeys. It will read the current status of the keys and update the form accordingly.

private void Form1_Load(object sender, EventArgs e)
{
    // read the current status of the specified keys
    UpdateKeys();
}

Generate the Form1_KeyUp event of the form to handle the key press event (this event is raised when a key is pressed and then released).

private void Form1_KeyUp(object sender, KeyEventArgs e)
{            
    if (e.KeyData == Keys.Insert)
    {
        UpdateInsert();
    }
    else if (e.KeyData == Keys.NumLock)
    {
        UpdateNUMLock();
    }
    else if (e.KeyData == Keys.CapsLock)
    {
        UpdateCAPSLock();
    }            
}

Utility Methods

PressKeyboardButton

This method takes the key code as parameter and simulates a key press event by sending a Key-Down message to the operating system followed by a Key-Up message.

private void PressKeyboardButton(Keys keyCode)
{
    const int KEYEVENTF_EXTENDEDKEY = 0x1;
    const int KEYEVENTF_KEYUP = 0x2;
 
    keybd_event((byte)keyCode, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event((byte)keyCode, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}   
UpdateNUMLock

It reads the status of the NUM lock using GetKeyState and updates the form accordingly.

this.Refresh() has been called at the end to ensure the form update by sending a Redraw request.

private void UpdateNUMLock()
{
    bool NumLock = (GetKeyState((int)Keys.NumLock)) != 0;
  
    if (NumLock)
    {
         lblNUM.Text = "NUM";
    }
    else
    {
         lblNUM.Text = String.Empty;
    }
 
    this.Refresh();
}      

Similarly, the other methods for CAPS lock and INSERT can also be implemented.

Conclusion

Your application will be able to reflect the status of the toggle keys. Also you can update the status of these keys from your application by double clicking the labels in the status strip.

Although I have been reading the articles and blogs for a long time, now I decided to make my contribution by sharing my knowledge and experience. I would love to get your feedback on this and do not forget to rate the post if you like it.

History

  • 2008/05/24 1.0.0.0 First release

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Bilal Haider
Technical Lead http://www.visionem.net
Saudi Arabia Saudi Arabia
I have done my BS in Computer Engineering from University of Engineering & Technology Lahore, Pakistan. Currently I am working as System Programmer and Administrator. I have worked in C, C++, C#, Assembly, Java, HTML and ASP.NET (Web Forms and MVC).
I Love to Create Visual Programs.
 
In my free time (if luckily, I got some,) I play Badminton and read books.
 
You can know about me in detail through my home page:
http://www.bilalhaider.com
Follow on   Twitter   LinkedIn

Comments and Discussions

 
GeneralVery useful. PinmemberMember 476443725-Dec-08 8:08 
GeneralRe: Very useful. PinmemberBilal Haider26-Dec-08 7:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411022.1 | Last Updated 23 May 2008
Article Copyright 2008 by Bilal Haider
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid