Click here to Skip to main content
13,900,534 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


48 bookmarked
Posted 23 May 2008
Licenced GPL3

Read and Update CAPS or NUM Lock Status from your Application

, 23 May 2008
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


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.


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


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.


internal static extern returnType 
MethodName (argument(s)); 


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.

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.


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.

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.


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)

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

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)
    else if (e.KeyData == Keys.NumLock)
    else if (e.KeyData == Keys.CapsLock)

Utility Methods


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);

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";
         lblNUM.Text = String.Empty;

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


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.


  • 2008/05/24 First release


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


About the Author

Bilal Haider
Technical Lead
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.

My Technical Blog:

You can know about me in detail through my home page:

You may also be interested in...


Comments and Discussions

GeneralThanks Pin
Stepanus David Kurniawan10-Nov-09 14:50
memberStepanus David Kurniawan10-Nov-09 14:50 
AnswerRe: Thanks Pin
Bilal Haider10-Nov-09 23:39
professionalBilal Haider10-Nov-09 23:39 
GeneralRe: Thanks Pin
Stepanus David Kurniawan11-Nov-09 14:17
memberStepanus David Kurniawan11-Nov-09 14:17 
AnswerRe: Thanks Pin
Bilal Haider11-Nov-09 23:59
professionalBilal Haider11-Nov-09 23:59 
GeneralWeb-Form Caps Status Pin
11Developer30-Oct-09 19:49
member11Developer30-Oct-09 19:49 
GeneralRe: Web-Form Caps Status Pin
Bilal Haider30-Oct-09 21:40
professionalBilal Haider30-Oct-09 21:40 
GeneralHI Pin
waqarsani9-Sep-09 20:38
memberwaqarsani9-Sep-09 20:38 
GeneralRe: HI Pin
Bilal Haider30-Oct-09 21:20
professionalBilal Haider30-Oct-09 21:20 
Generalgood article Pin
Donsw18-Jan-09 11:32
memberDonsw18-Jan-09 11:32 
GeneralRe: good article Pin
Bilal Haider18-Jan-09 18:17
professionalBilal Haider18-Jan-09 18:17 
GeneralRe: good article Pin
Donsw19-Jan-09 1:25
memberDonsw19-Jan-09 1:25 
GeneralRe: good article Pin
Bilal Haider19-Jan-09 5:51
professionalBilal Haider19-Jan-09 5:51 
GeneralVery useful. Pin
Member 476443725-Dec-08 7:08
memberMember 476443725-Dec-08 7:08 
GeneralRe: Very useful. Pin
Bilal Haider26-Dec-08 6:34
professionalBilal Haider26-Dec-08 6:34 
GeneralVery good sample Pin
OneSoftware10-Jun-08 18:18
memberOneSoftware10-Jun-08 18:18 
GeneralRe: Very good sample Pin
Bilal Haider11-Jun-08 2:52
professionalBilal Haider11-Jun-08 2:52 
GeneralGood Work Pin
Aamir Mustafa24-May-08 2:54
memberAamir Mustafa24-May-08 2:54 
GeneralRe: Good Work Pin
Bilal Haider25-May-08 22:58
professionalBilal Haider25-May-08 22:58 
General[Message Removed] Pin
Mojtaba Vali23-May-08 21:50
memberMojtaba Vali23-May-08 21:50 
GeneralRe: managed code Pin
Bilal Haider24-May-08 1:32
professionalBilal Haider24-May-08 1:32 
GeneralThe Source code link is broken Pin
knoami23-May-08 19:01
memberknoami23-May-08 19:01 
GeneralRe: The Source code link is broken Pin
Bilal Haider24-May-08 1:28
professionalBilal Haider24-May-08 1:28 
AnswerRe: The Source code link is broken Pin
Bilal Haider24-May-08 1:56
professionalBilal Haider24-May-08 1:56 
GeneralRe: The Source code link is broken Pin
knoami24-May-08 4:13
memberknoami24-May-08 4:13 
GeneralSource code Pin
Tony Bermudez23-May-08 18:31
memberTony Bermudez23-May-08 18:31 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190306.1 | Last Updated 23 May 2008
Article Copyright 2008 by Bilal Haider
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid