Here's the code, from a .Net version of Notepad I wrote once. It's in C#,
unfortunately, but converting it to VB.Net shouldn't be too tough. Looks
like it lost its formatting when I pasted it from VS.Net...
Tom Dacon
Dacon Software Consulting
/// <summary>
/// Windows API function to get the key state of various keyboard keys,
/// such as the Caps Lock key and so forth.
/// </summary>
/// <param name="keyCode"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true,
CallingConvention=CallingConvention.Winapi)]
private static extern short GetKeyState(int keyCode);
// Selections from platform SDK WinUser.h
private const int VK_CAPITAL = 0x14;
private const int VK_INSERT = 0x2D;
private const int VK_NUMLOCK = 0x90;
private const int VK_SCROLL = 0x91;
/// <summary>
/// When the user interface goes idle, update the keyboard state
/// annunciators on the status bar.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>This event handler is wired to Application.Idle</remarks>
public void OnIdle(object sender, EventArgs e)
{
// Update the panels when the program is idle.
bool capsLock = (((ushort) GetKeyState(VK_CAPITAL)) & 0xffff) != 0;
bool insKey = (((ushort) GetKeyState(VK_INSERT)) & 0xffff) != 0;
bool numLock = (((ushort) GetKeyState(VK_NUMLOCK)) & 0xffff) != 0;
bool scrLock = (((ushort) GetKeyState(VK_SCROLL)) & 0xffff) != 0;
this.statusBar1.Panels[SbpCapsIndex].Text = ( capsLock ? "CAP" : "");
this.statusBar1.Panels[SbpInsIndex].Text = ( insKey ? "INS" : "OVR");
}