Today, when I was planning to write an article on Grid View. I got a message from a very good friend of mine who is asking to disable the special keys(Windows Keys) in his application. When I start researching on it, I was thinking that it can be done using e.KeyChar but unfortunately, it is not showing any information about windows keys.

So in this post I will explain you, how can we disable the special keys (in our case windows keys) in C# Application.

1. Crete a c# windows application project
2. On the code behind of your default form add the following references

   1: using System.Diagnostics;
   2: using System.Runtime.InteropServices;

3. Now before the constructor of your form place the following code.

   1: // Structure contain information about low-level keyboard input event
   2: [StructLayout(LayoutKind.Sequential)]
   3: private struct KBDLLHOOKSTRUCT
   4: {
   5:     public Keys key;
   6:     public int scanCode;
   7:     public int flags;
   8:     public int time;
   9:     public IntPtr extra;
  10: }
  11:  
  12: //System level functions to be used for hook and unhook keyboard input
  13: private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
  14: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  15: private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
  16: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  17: private static extern bool UnhookWindowsHookEx(IntPtr hook);
  18: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  19: private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
  20: [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  21: private static extern IntPtr GetModuleHandle(string name);
  22: [DllImport("user32.dll", CharSet = CharSet.Auto)]
  23: private static extern short GetAsyncKeyState(Keys key);
  24:  
  25:  
  26: //Declaring Global objects
  27: private IntPtr ptrHook;
  28: private LowLevelKeyboardProc objKeyboardProcess; 

4. Now add the following code on your constructor.

   1: public Form1()
   2: {
   3:     ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule; //Get Current Module
   4:     objKeyboardProcess = new LowLevelKeyboardProc(captureKey); //Assign callback function each time keyboard process
   5:     ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0); //Setting Hook of Keyboard Process for current module
   6:  
   7:  
   8:     InitializeComponent();
   9: }

5. Now Implement the callback function

   1: private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
   2: {
   3:     if (nCode >= 0)
   4:     {
   5:         KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
   6:  
   7:         if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin) // Disabling Windows keys
   8:         {
   9:             return (IntPtr)1;
  10:         }
  11:     }
  12:     return CallNextHookEx(ptrHook, nCode, wp, lp);
  13: }

6. Now go to your designer class and replace your dispose method.

   1: /// <summary>
   2: /// Clean up any resources being used.
   3: /// </summary>
   4: /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   5: protected override void Dispose(bool disposing)
   6: {
   7:     if (disposing && (components != null))
   8:     {
   9:  
  10:         components.Dispose();
  11:     }
  12:     if (ptrHook != IntPtr.Zero)
  13:     {
  14:         UnhookWindowsHookEx(ptrHook);
  15:         ptrHook = IntPtr.Zero;
  16:     }
  17:     base.Dispose(disposing);
  18: }

So, in this way we can stop the windows key operation till your application is running.You can find the VS 2008 Source code here.