Hiding Windows Form in C# using Global Keyboard Shortcut

Continuing from my previous post, I will explain how to hide your windows form application from Desktop & Taskbar, thus making it completely invisible using a keyboard shortcut. We will use global keyboard hook to achieve this functionality. For those reading the post directly must read my previous post on Easy Way To Achieve Global Keyboard Hook in .NET which explains the design & usage of KeyboardHook class. Below is the code that you would have to add in Program.cs class of your Windows Form Project.

   1: static class Program
   2:     {
   3:         public static bool IsFormHidden;    // For Checking Form is Currently Hidden or Not
   4:         public static IntPtr WindowHandle;  // Handle To Main Window, Registered at First Run of 'HideOrUnhideWindow' Method
   5:         public static bool firstRun;        // To register 'WindowHandle' at first run of method, after that set to false 
   6:  
   7:         [STAThread]
   8:         static void Main()
   9:         {
  10:             firstRun = true;
  11:  
  12:             // Registering Keyboard Hook with Ctrl+Shift+H .
  13:             // HideOrUnhideWindow Method will be called each time when shortcut button is pressed.
  14:  
  15:             KeyboardHook.SetHook(HideOrUnhideWindow, KeyboardHook.BeginKeys.Control_Shift, KeyboardHook.EndKey.H);
  16:  
  17:             Application.EnableVisualStyles();
  18:             Application.SetCompatibleTextRenderingDefault(false);
  19:             Application.Run(new Form1());
  20:  
  21:             KeyboardHook.UnhookWindowsHook();   // Always remember to unhook
  22:         }
  23:  
  24:         // Called Everytime When Keyboard Shortcut is pressed.
  25:         public static void HideOrUnhideWindow()
  26:         {
  27:             // for registering main form window handle at first call to HideOrUnhideWindow Method
  28:             if (firstRun)
  29:                 WindowHandle = Process.GetCurrentProcess().MainWindowHandle;
  30:                 firstRun = false;
  31:  
  32:             if (!IsFormHidden)
  33:             {
  34:                 ShowWindowAsync(WindowHandle, 0);
  35:                 IsFormHidden = true;
  36:             }
  37:             else
  38:             {
  39:                 ShowWindowAsync(WindowHandle, 9);
  40:                 IsFormHidden = false;
  41:             }
  42:         }
  43:  
  44:         [DllImport("user32.dll")]
  45:         private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
  46:     }

To achieve global keyboard shortcut, we make use of KeyboardHook class by simply calling two methods- one for registering and other for unhooking or unregistering keyboard hook as in line no. 15 and 21 above. Note that HideOrUnhideWindow method will be called each time the user presses keyboard shortcut. When this method is called first time, we get the handle to main windows form and then set firstRun boolean variable to false so that in future runs of above method, we don’t need to get handle again. IsFormHidden boolean variable simply tells the form is currently in which state, depending on that we call ShowWindowAsync method which requires first argument as handle to window and second argument to tell what to do with that window. We use P/Invoke to call method as signature is shown in line no. 44 to 45. Rest of code is pretty easy and well commented. You can download the project from Hiding Windows Form Project – Visual Studio 2008.


cheers

kick it on DotNetKicks.com

About these ads
This entry was posted in .NET. Bookmark the permalink.

4 Responses to Hiding Windows Form in C# using Global Keyboard Shortcut

  1. Danny says:

    Hi, I have converted the code from the previous post to managed C++ (for a particular project). However, I have encountered a fault which is also probably the case with this version, if the keypress cna be interpreted in other ways, it will be – that is, the event is nto stopped although your app has handled the key. My example being CTRL-ALT-D – which shows a document outline in visual studio – it is still doing so. What I thinking is that to avoid calling CallNextHookEx when the key has been handled would do it. However, then there is a matter of knowing what to return in that IntPtr return value. According to the MSDN documentation this depends on the handler, and blocking the next call should usually be avoided. However, I suspect if an IntPtr is initialised to 0, and returned instead of calling the original hook if the key was handled by the replacement code, then you wont get multiple effects on the keypress.

  2. Danny says:

    In code: bool bHandled = false; IntPtr nRetval(0); if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN) { int vkCode = Marshal::ReadInt32(lParam); if ((Keys)(_endKey) == (Keys)vkCode && (Keys)_beginKeys == Control::ModifierKeys) { _handler->Invoke(Process::GetCurrentProcess(), gcnew EventArgs()); bHandled = true; } } if(!bHandled) { nRetval = CallNextHookEx(_hookID, nCode, wParam, lParam); } return nRetval;

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s