Two days ago, I accidentally moved from the source code of golorspy (I turned back to my Google Reader and never found that article, if the author sees this article, he can contact me and I will post the original address reference.) He found a library named windowshooks that encapsulates windows global hooks and read the source code in detail, it is quite easy to use and expand. Therefore, this article introduces the usage and extension methods of the library separately. The source code of the library is provided at the end of this article (if the source code is not open, please inform me that I will take the initiative to remove it) and the weak sample we write.
1. Concept of global hooks
(The following definitions are from msdn)
A global hook monitors messages for all threads in the same desktop as the calling thread.
A global hook monitors messages received by all threads on the same desktop as the threads that call the hook.
Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. You should install a hook only when necessary, and remove it as soon as possible.
Hooks often reduce the system running speed, because this increases the number of times the system processes each message. You should install a hook only when needed and clear it in time
In short, when the system generates a message, the global Hook intercepts the message before it is sent to another thread that subscribes to the message. That is to say, even if the process that created the Global hook is not activated on the desktop, it can still intercept the messages it follows and make some processing in advance.
In fact, we use the hook technology when using screen word retrieval functions such as Kingsoft word overlord and youdao dictionary.
2. Basic Structure of the windowshooks Library
The generated class diagram is as follows:
The following describes the functions of each class:
Globalhook: Indicates a global hook class, which is an abstract class. All hook classes implemented by users must inherit from this class. Most of the methods and attributes have been defined in the globalhook class. You only need to override the hookcallbackprocedure method to define the work to be done when processing intercepted messages.
Windowsapis:Here we declare the Win32 APIs that will be used in the library, so you don't need to pay attention to it during expansion.
Windowsmessages:This class contains binary codes for various types of Windows messages that can be processed. To expand a hook class, you need to select the event type you want to intercept first.
Windowsstruct:This class contains some struct types that may be used, mainly to be compatible with the relevant structure types used in the original Win32 APIs. Note that the attribute Declaration must be added to deploy the memory model of the defined structure according to the user-defined field order. Otherwise. NET may re-arrange the order of fields in the memory model for optimization during compilation, which may cause errors.
Keyhooks:This class defines a hook used to intercept the keyboard key message and inherit from globalhook. It can be seen as an example of a user-defined hook or can be directly used in your own program. Start the hook using the start method of the parent class globalhooks, and end the hook using the stop method of the parent class globalhooks. Once a message is intercepted, the overwritten hookcallbackprocedure method is executed, the keyup event will be triggered in this method. Note that the event processing mechanism is applied to the keyhooks implementation and the event keyup is defined, this means that we can directly write the event processing function during use and then let the keyup subscribe to the processing process, which is very convenient to use.
3. Use keyhooks to intercept keyboard key messages
The following example uses the keyhooks class to capture keyboard messages and show which key is pressed.
First, go to the interface
After creating the solution, do not forget to reference the windowshooks project and reference it in the sample project.
Next we will add a private member of the keyhooks type to the frm_mainform class _ keyhooks
/// <Summary>
/// Keyboard hook object
/// </Summary>
Private keyhooks _ keyhooks;
Then we define the load event of the form to initialize the _ keyhooks object at the beginning and subscribe to the keyup event of the _ keyhooks object in advance.
/// <Summary>
/// Frm_mainform's load event processing function
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "E"> </param>
Private void frm_mainform_load (Object sender, eventargs E)
{
_ Keyhooks = new keyhooks ();
_ Keyhooks. keyup + = new keyeventhandler (_ keyhooks_keyup );
}
Next we will define the click event to be responded to by the button control in the form.
/// <Summary>
/// Click event processing function of btn_begin
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "E"> </param>
Private void btn_begin_click (Object sender, eventargs E)
{
If (! _ Keyhooks. isstarted)
{
Try
{
_ Keyhooks. Start ();
This. btn_begin.text = "Stop capturing keyboard messages ";
}
Catch (exception ex)
{
MessageBox. Show (ex. Message );
}
}
Else
{
Try
{
_ Keyhooks. Stop ();
This. btn_begin.text = "start to capture keyboard messages ";
}
Catch (exception ex)
{
MessageBox. Show (ex. Message );
}
}
}
/// <Summary>
/// Click event processing function of btn_quit
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "E"> </param>
Private void btn_quit_click (Object sender, eventargs E)
{
Application. Exit ();
}
Our requirement is that the hook is started after you click the "start to capture Keyboard Message" button, then, no matter when the user presses the key on the keyboard (even if the process is not activated to the foreground on the desktop), The ListBox displays the key that the user presses.
To this end, we need to subscribe to the _ keyhooks keyup event (the method body has been subscribed to in the form load event) and describe the message (windowsmessages. wh_keyboard_ll.
The Code is as follows:
/// <Summary>
/// _ Keyhooks's keyup event processing function
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "E"> </param>
Private void _ keyhooks_keyup (Object sender, keyeventargs E)
{
This. lst_displaymessage.items.add ("just now" + E. keydata. tostring () + "pressed ");
}
Of course, this method is very short. To save space and code, you can also write it like this (using lambda expressions ):
/// <Summary>
/// Frm_mainform's load event processing function
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "E"> </param>
Private void frm_mainform_load (Object sender, eventargs E)
{
_ Keyhooks = new keyhooks ();
// _ Keyhooks. keyup + = new keyeventhandler (_ keyhooks_keyup );
_ Keyhooks. keyup + =
New keyeventhandler (S, EA) =>{ this. lst_displaymessage.items.add ("just" + EA. keydata. tostring () + "pressed ");});
}
Now this simple sample is complete, and the following shows the running effect (note that the process of the Global Hook Test on the right is not in the activated state ):
4. Conclusion
This article will be written here for the time being. When windowshooks is used in the future, I will add an article to expand my own hook method.
The following is the windowshooks Library and the sample in this article (Run Through Visual Studio 2008 ):
Download the windowshooks Library
Download Sample
Over
Weatherpop
2010/2/11