Application of Hook in vb.net (CNET Chinese web)

Source: Internet
Author: User
Tags exit instance method integer relative thread
Application of Hook in Chinese vb.net

In the vb.net version of the moderator for a while, has been thinking how to better help you understand vb.net new concepts and programming methods. Small replies are difficult to understand a lot of problems, so use the document center of this vast world, for more in-depth discussion. My level is limited, unavoidable mistakes and omissions, please friends criticize.

The basic idea is to write a series of articles, explain the difference between VB.net and VB, the new concept in vb.net, the use of vb.net control, vb.net a new way to solve the problem. If time permits, I hope I can carry out the work quickly. More importantly, the support and encouragement of netizens will be the source of my continued power.

Today is the first time to write, do not know where to start, weigh repeatedly, decided to start from the API call problem. VB enthusiasts often write to me or post, ask vb.net the changes in the API, so today we will discuss together. Although the purpose of Microsoft's introduction of Vs.net is to be used across platforms, Windows API is not recommended, but from here, it makes it easier for us to understand the changes made by vb.net, so:

Let's go ... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ....... ...

This article is not an article on the hook principle, just a discussion of how to invoke the hook function in vb.net, and the change in API usage in vb.net.

Due to the variety of hooks, the most commonly used keyboard hooks are analyzed in this paper.

First, a look at the VB is how to achieve. The section is the space bar. The goal of performance is: A form, which has a textbox, regardless of whether the focus falls in the textbox, press the SPACEBAR, will not enter a space in the textbox, but into a textbox to write a sentence: "Hook success!" ”

1. Write the following code in a module:

Declaration of the invoked API:

Declare Function SetWindowsHookEx Lib "user32" Alias "Setwindowshookexa" (ByVal Idhook as Long, ByVal LPFN as Long, ByVal Hmod as Long, ByVal dwThreadID as Long

Function Description: This function is used to start hook settings.

Idhook is the type of hook, the type of message that is processed.

LPFN is the address pointer to the hook Cheng (function or procedure). If the dwThreadID parameter is 0 or an identity of a thread created by another process, LPFN must point to the hook thread in the DLL. In addition, LPFN can point to a section of the Hook subroutine code for the current process (that's what we're using).

Hmod is a handle to an application instance that identifies the DLL that contains the Cheng that LPFN refers to. If dwThreadID identifies a thread created by the current process, and the subroutine code is in the current process, hmod must be null.

dwThreadID is the identifier of the thread associated with the installation of the hook child threads relative, if it is associated with all threads for the 0,hook subroutine. Return value: The function succeeds returning the handle of the Hook subroutine, and the failure returns NULL.

Declare Function UnhookWindowsHookEx Lib "user32" (ByVal Hhook as long) as long

Function Description: This function is the use of lifting hooks. Hhook is the handle to the hook function.

Declare Function CallNextHookEx Lib "user32" (ByVal hhook as Long, ByVal ncode as Long, ByVal WParam as Long, lParam as Y) as Long

Function Description: The function is to pass the hook information in the current hook chain to the next hook.

The Hhook is the handle to the current hook, and an application receives the handle as a result of the previous call to the SetWindowsHookEx function.

Ncode refers to the hook code passed to the current hook process and the next hook process uses this code to determine how to handle the hook information.

WParam refers to the wparam value passed to the current hook process, and its specific meaning is determined by the type of the associated hook in the current hook chain.

LPARAM refers to the LPARAM value passed to the current hook process, and its specific meaning is determined by the type of the associated hook in the current hook chain.

2. The constants defined are:

Public Hnexthookproc as Long
Public Const Wh_keyboard = 2 ' This is to indicate that the type of hook is the keyboard hook
Public Const pm_key_space = &h20 ' SPACEBAR

3. Code Snippets

Public Sub unhookkbd () ' Solve keyboard hook function
If hnexthookproc <> 0 Then
UnhookWindowsHookEx Hnexthookproc
Hnexthookproc = 0
End If
End Sub

Public Function Enablekbdhook () ' Set keyboard hook
If hnexthookproc <> 0 Then
Exit Function
End If
Hnexthookproc = SetWindowsHookEx (Wh_keyboard, AddressOf _
Mykbhfunc, app.hinstance, 0)
If hnexthookproc <> 0 Then
Enablekbdhook = Hnexthookproc
End If
End Function

Public Function Mykbhfunc (ByVal Icode as Long, _
ByVal WParam as Long, ByVal LParam as long) as long
Mykbhfunc = 0
If Icode < 0 Then
Mykbhfunc = CallNextHookEx (Hnexthookproc, Icode, WParam, LParam)
Exit Function
End If
If WParam = Pm_key_space Then ' Scout has not pressed the spacebar
Mykbhfunc = 1
' Add your own code to indicate the response
form1.text1.text= "Hook success!" ”
End If
End Function

4. The code in form is simple:

Private Sub Form_Load ()
Call Enablekbdhook
End Sub
Private Sub form_unload (Cancel as Integer)
Call UNHOOKKBD
End Sub

Finish the call! Now, when you play the SPACEBAR in form form, you will respond to the code you wrote in the Mykbhfunc function.

Secondly, what changes have been made to the API invocation and the implementation of the hook in the vb.net?

We correspond to a problem with a question that looks:

1. Create a new module, first write the API declaration:

Declare Function SetWindowsHookEx Lib "user32" Alias "Setwindowshookexa" (ByVal Idhook as Hooktype, ByVal LPFN as HookProc , ByVal hmod As Integer, ByVal dwthreadid As Integer) As Integer

Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hhook As Integer) As Integer

Declare Function CallNextHookEx Lib "user32" (ByVal hhook As Integer, ByVal ncode As Integer, ByVal wParam as Integer, Byv Al LParam As Integer) As Integer

What do you find in comparison with the statement above VB6? Is the data type changed? The integer replaces long. This is a good understanding, because the integer in vb.net is defined as a 32-bit (4-byte) integer, and the range of values is 231 to 231 (the first is the sign bit), which is consistent with the definition of long in VB6, so we have to do the conversion.

And so on, there is also a change, that is, the SetWindowsHookEx parameter lpfn type becomes hookproc, that ... What does that mean. Oh, wait, I'll make one more statement:

Public Delegate Function HookProc (ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Did you see anything? HookProc is actually a function declaration, but what does it mean to have a delegate (delegate) in front of it? Why can't I use integer to represent the type of LPFN in vb.net? Let's look back at the sentence in VB6 that invokes the API:

Hnexthookproc = SetWindowsHookEx (Wh_keyboard, AddressOf _
Mykbhfunc, app.hinstance, 0)

LPFN is represented here as a AddressOf Mykbhfunc, which means that the Cheng of the call is Mykbhfunc when the hook takes effect. This means that LPFN represents the address of a function or procedure. A long type can be used to record the address of a function or procedure in VB6.

In vb.net, a little bit of change, the AddressOf operator creates a delegate that points to the specified child Cheng. When the specified Cheng is an instance method, the Cheng delegate references both the instance and the method so that when the subroutine delegate is invoked, the specified method of the specified instance is invoked. The AddressOf operator can be used as the operand of a delegate constructor, or it can be used in a context in which the compiler can determine the delegate type.

So, it is because AddressOf created is no longer just a simple function pointer, but a subroutine delegate! Wait, what is a delegate? (^?^)

Explanation: An event is a message sent by an object to signal notification of the occurrence of an operation. The action may be caused by user interaction, such as a mouse click, or by some other program logic. The object that raises (triggers) the event is called the sender of the event. The object that captures the event and responds to it is called the event receiver. In event communication, the event sender class does not know which object or method will receive (handle) the event it raises. What is needed is a medium (or a mechanism similar to a pointer) between the source and the receiver. The. NET framework defines a special type (Delegate) that provides functionality for function pointers. Look, the. NET Framework is mentioned here, so languages in vs.net such as C # can have this type.

A delegate is an object that can be used to invoke other object methods. Unlike other classes, a delegate class has a signature, and it can only refer to methods that match its signature. In this way, the delegate is equivalent to a type-safe function pointer or a callback. Because they are similar to the function pointers used in other programming languages. Unlike a function pointer, however, the Visual Basic.NET delegate is a reference type based on the System.Delegate class, which can refer to shared methods-no specific callable method-and instance methods. (For details, please check out MSDN or wait for my later article to explain)

To summarize, that is to say, AddressOf creates Delegatetype (delegate type). Instead of a simple subroutine pointer, the notation is not a long address type, but a delegate type representation that is consistent with the calling subroutine. Therefore, I have defined a delegate function HookProc with Mykbhfunc declaration of the same shape to represent the LPFN type.

(Exhale, a sweat, do not know to say clearly yet.) I hope it is clear that ... )

Go on, I went on to declare an API:

Declare Function getcurrentthreadid Lib "kernel32" Alias "GetCurrentThreadID" () as Integer

Function Description: This function is used to get a unique thread identifier for the current thread. Return value: The current thread identifier. What's the use of this, a little later, anyway is a simple question, better sell a case, haha ... (Don't hit Me)

2. The constants defined are:

Public Hnexthookproc as Long
Public Const Wh_keyboard = 2 ' This is to indicate that the type of hook is the keyboard hook
Public Const pm_key_space = &h20 ' SPACEBAR

Or, in fact, I am in the process of the second sentence of the above change, also nothing, is more to explain something to friends:

Public Enum Hooktype
Wh_keyboard = 2
End Enum

is defined as an enumeration. In fact, there are many kinds of hooks, such as: Wh_callwndproc, Wh_callwndprocret, WH_CBT, Wh_debug, Wh_getmessage and so on. So you might as well write an enumeration to achieve the purpose once and for all.

3. Code Snippets

Module Module1

Public Frm1 as New Form1 () ' The role of the last to say

Declare Function getcurrentthreadid Lib "kernel32" Alias "GetCurrentThreadID" () as Integer

Declare Function SetWindowsHookEx Lib "User32" Alias _

"Setwindowshookexa" (ByVal Idhook as Integer, ByVal Lpfn as HookProc, _

ByVal hmod As Integer, ByVal dwthreadid As Integer) As Integer

Declare Function UnhookWindowsHookEx Lib "User32" _

(ByVal Hhook as Integer) As Integer

Declare Function CallNextHookEx Lib "user32" (ByVal Hhook as Integer, _

ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Public Delegate Function HookProc (ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Public Hnexthookproc as Integer

Public Const pm_key_space = &h20

Public Enum Hooktype

Wh_keyboard = 2

End Enum


Public Sub unhook () ' Hook

If hnexthookproc <> 0 Then

UnhookWindowsHookEx (Hnexthookproc)

Hnexthookproc = 0

End If

End Sub

Public Function sethook () ' Set hook

If hnexthookproc <> 0 Then

Exit Function

End If

Hnexthookproc = SetWindowsHookEx (Hooktype.wh_keyboard, AddressOf mykeyboardproc, 0, GetCurrentThreadID ())

I set the third argument to 0 (that is, null), which means that the code for this hook is in this process. The fourth parameter uses an API to pick up the identifier of the thread associated with the hook child threads relative. (See the previous API declaration)

End Function


Public Function Mykeyboardproc (ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Mykeyboardproc = 0

If ncode < 0 Then

Mykeyboardproc = CallNextHookEx (Hnexthookproc, Ncode, WParam, LParam)

Exit Function

End If

If WParam = Pm_key_space Then

Mykeyboardproc = 1

' Write your own code.

frm1.textbox1.text= "Hook success!" ”

End If

End Function

Sub Main ()

Application.Run (FRM1)

End Sub

End Module

At the same time, please:

Solution Manager-〉windowsapplication1.sln-〉-〉 Properties-〉 Common Properties-> General-> startup object-〉 to Module1

4. Code in FORM1:

Private Sub Form1_Load (ByVal sender as System.Object, ByVal e as System.EventArgs) Handles MyBase.Load

Call Sethook ()

End Sub

' There was no form_unload incident in vb.net, but with closing

Private Sub form1_closing (ByVal sender as Object, ByVal e as System.ComponentModel.CancelEventArgs) Handles Mybase.closing

Call Unhook ()

End Sub


Finally, briefly explain why I used the public frm1 as New Form1 () in Module1, and the starting object-〉 changed to Module1 practice. This is because vb.net is already oo, and if you're a regular on the vb.net version of CSDN, you'll be familiar with the problem, which we've talked about n times. I have not known how many posts to illustrate this issue. If you do not understand the subject and length of this article, please take a look at:

Http://www.csdn.net/expert/topic/965/965919.xml

Get some ideas. I will make a more detailed and systematic introduction to the following articles (in fact, it is one of the questions I would like to write first).


Conclusion: about the API call, this article only involves one of the tip of the iceberg, on the specific call changes, I will be based on the vb.net version of the specific situation and then write the relevant article to explain.

Yes, add that vb.net no longer recognize any type, so declare it as the type you want to use.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.