Click here to Skip to main content
15,901,122 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
A Simple C# Global Low Level Keyboard Hook[^]

This is what I use for hook keys. And it has a method e.Handled to prevent a key completing a particular task such as showing the help window for F1 key.

and here is the code I have used..

C#
globalKeyboardHook myhook = new globalKeyboardHook();
            
            myhook.HookedKeys.Add(Keys.F1);
            myhook.HookedKeys.Add(Keys.F2);
            myhook.HookedKeys.Add(Keys.F3);
            myhook.HookedKeys.Add(Keys.F4);
            myhook.HookedKeys.Add(Keys.F5);
            myhook.HookedKeys.Add(Keys.F6);
            myhook.HookedKeys.Add(Keys.F7);
            myhook.HookedKeys.Add(Keys.F8);
            myhook.HookedKeys.Add(Keys.F9);
            myhook.HookedKeys.Add(Keys.F10);
            myhook.HookedKeys.Add(Keys.F11);
            myhook.HookedKeys.Add(Keys.F12);
            
            myhook.KeyDown += new KeyEventHandler(myhook_KeyDown);
            myhook.KeyUp +=new KeyEventHandler(myhook_KeyUp);


C#
void myhook_KeyDown(object sender, KeyEventArgs e)
        {

            if (e.KeyCode == Keys.F1)
            {
                if (checkBox1.Checked)
                {
                    e.Handled = true;
                }
            }
         }


If checkBox1 is checked and user press the F1 key all I wanted is preventing F1 key using from windows. (Prevent showing the help window)

It works for the first time. If checkBox1 is checked and user pressed the F1 key this program would prevent showing the help window.
But if I uncheck the checkBox1 and check it again, this program doesnot do anything. The help window would popup.

Whats the wrong with my code ?
Is there some other way to accomplish what I want ?

And please no advanced methods please.
Im a newbie to C#
Posted
Comments
agent_kruger 19-Jan-14 0:34am    
please post the code of "Key Up" i think so the problem is there.
M­­ar­­­­k 19-Jan-14 0:41am    
Key_Up event is empty..

begin edit #2 ...

Here's a possible solution that does use the code from the 2007 CP article by StormySpike you used:

I modified the Form1 design-time view like this:

1. set the Dock Property of the lstLog ListBox to "None."

2. re-sized the lstLog Control to open-up room at the top of the Form.

3. added a CheckBox, checkBox1, with the Text: "Key Handle On/Off" at the top of the Form.

Here's the modified code for that articles's Form1.cs file:
C#
using System;
using System.Windows.Forms;
using Utilities;

// code from: CP article "A Simple C# Global Low Level Keyboard Hook"
// by StormySpike, 31 May 2007
// http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook

// modified Jan. 2014 by bw

namespace key_preview
{
    public partial class Form1 : Form
    {
        globalKeyboardHook myHook = new globalKeyboardHook();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            checkBox1.Checked = true;

            myHook.HookedKeys.Add(Keys.F1);
            myHook.HookedKeys.Add(Keys.F2);
            myHook.HookedKeys.Add(Keys.F3);
            myHook.HookedKeys.Add(Keys.F4);
            myHook.HookedKeys.Add(Keys.F5);
            myHook.HookedKeys.Add(Keys.F6);
            myHook.HookedKeys.Add(Keys.F7);
            myHook.HookedKeys.Add(Keys.F8);
            myHook.HookedKeys.Add(Keys.F9);
            myHook.HookedKeys.Add(Keys.F10);
            myHook.HookedKeys.Add(Keys.F11);
            myHook.HookedKeys.Add(Keys.F12);

            myHook.KeyDown += myHook_KeyDown;
            myHook.KeyUp += myHook_KeyUp;
        }

        // note no reporting done here if KeyUp is handled
        private void myHook_KeyUp(object sender, KeyEventArgs e)
        {
            if (checkBox1.Checked && myHook.HookedKeys.Contains(e.KeyCode))
            {
                e.Handled = true;
                return;
            }

            lstLog.Items.Add("Up\t" + e.KeyCode.ToString());
        }

        private void myHook_KeyDown(object sender, KeyEventArgs e)
        {
            if (checkBox1.Checked && myHook.HookedKeys.Contains(e.KeyCode))
            {
                switch(e.KeyCode)
                {
                    case Keys.F1:
                        lstLog.Items.Add("handled F1\t" + e.KeyCode.ToString());
                        break;

                    // .... add case statements for all other F# keys here

                    case Keys.F12:
                        lstLog.Items.Add("handled F12\t" + e.KeyCode.ToString());
                        break;
                }

                e.Handled = true;
                return;
            }

            lstLog.Items.Add("Key Down passed through\t" + e.KeyCode.ToString());
        }
    }
}
I tested this code in VS 2013 compiling with FrameWork 4.5. No problems in Win 8/64 checking, and un-checking, the CheckBox several times and testing the F1 and F12 keys.

end edit #2 ...

begin edit #1 ...

I took George Mamaladze's latest HookManager source + demo app [^], opened it in VS 2013, let VS convert it to use FrameWork 4.5.

fyi: downloading and running George's latest demo (v. 2) of his hook manager: consistently fails in Win 8, but his original demo works fine. I'll report the error details to George.

I verified that I could modify his KeyDown behavior, by altering one method, to stop handling the F1 key-down only, passing through all other key-downs:
C#
private void HookManager_KeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode == Keys.F1)
    {
        e.Handled = true;
        return;
    }

    textBoxLog.AppendText(string.Format("KeyDown - {0}\n", e.KeyCode));
    textBoxLog.ScrollToCaret();
}
I verified that checking and un-checking the CheckBox for 'KeyDown several times resulted in the F1 key being handled, or passed on to Windows as expected, worked properly.

This solution suggests that it is not necessary to install and un-install the hook EventHandlers for the hook to work as expected.

end edit #2 ...

begin edit #1 ...

George's code removes the EventHandler when the KeyDown intercept CheckBox is unchecked, and installs/re-installs it when it is checked.

Hypothesis: you need to write an EventHandler for the CheckedChanged Event of the ComboBox, and un-install or install the EventHandler based on whether the CheckBox is checked, or not.

Whether you can modify the code you were working with originally (not George's solution) is something I haven't looked at.

end edit #1 ...

I suggest you switch to using George Mamaladze's Global Hook code here on CP which has been updated more recently than the code you are using now: [^].

The nature of using global hook calls from C# is inherently complex, involving use of WinApi and Platform Invoke facilities. The functionality you require may not be simple, and if you are a beginner in C# this may be a problem.
 
Share this answer
 
v3
Comments
M­­ar­­­­k 19-Jan-14 4:12am    
After u said about that, I tried it. But its very complicated and I cant even understand how to use it like the code above. And it does not provide any tutorial in that link. I searched for tutorials and I couldn't find one too. Do you have any link that explain about that hook simply ?
BillWoodruff 19-Jan-14 5:55am    
See edit to the solution for code that may assist you.

I have used George's hook code successfully, years ago, but I was not attempting to do what you are doing.

I have one hypothesis that I can investigate, if you answer these questions ... but no guarantee I can help ...

1. is the F1 key the only key where you want the user of your application to switch whether the key is handled by the hook code, or not ?

2. your application is Windows Forms ? it shows up in the TaskBar ? it's not a Service ?

3. the way the end-user interacts with your application ... to change its behavior for the F1 key ... is to switch to the application and check the CheckBox ?
M­­ar­­­­k 19-Jan-14 11:29am    
1. no. I want to handle all the Function keys (F1 - F12) by hook..

2. Yes its a windows form..

3. I dont get it o_O
BillWoodruff 19-Jan-14 12:44pm    
Question #3 was meant just to confirm that the user of your app has to switch to the app and "manually" check the CheckBox ... i.e., it's not being set by something you are doing your code, or by a Timer, etc.

I am curious to see if my second revision of my response, and the code sample enables you to achieve what you want.
M­­ar­­­­k 20-Jan-14 0:17am    
Ah never mind.. :)
"https://www.nuget.org/packages/MouseKeyboardActivityMonitor/"
this solved my problem.. By the way thanks for your help.. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900