Pure C # Hook implementation
To implement system hooks, you can call three Win32 APIs.
SetWindowsHookExUsed to set hooks. (Set up a card to check the required information)
[DllImport ("user32.dll", CallingConvention = CallingConvention. StdCall)]
Public static extern IntPtr SetWindowsHookEx (WH_Codes idHook, HookProc lpfn,
IntPtr pInstance, int threadId );
CallNextHookExIt is used to transmit hooks (messages are important, so where you come from, you should go back, unless you decide to block messages)
[DllImport ("user32.dll", CallingConvention = CallingConvention. StdCall)]
Public static extern int CallNextHookEx (IntPtr pHookHandle, int nCode,
Int32 wParam, IntPtr lParam );
UnhookWindowsHookExUnmount the hook (unmount is very important. Congestion may occur when there are too many sub-accounts)
[DllImport ("user32.dll", CallingConvention = CallingConvention. StdCall)]
Public static extern bool UnhookWindowsHookEx (IntPtr pHookHandle );
The article "how to: Set window hooks in Visual C #. NET" describes the following:
Global hooks are not supported in the. NET Framework.
You cannot implement global hooks in the Microsoft. NET Framework. To install a global Hook, the hook must have a local dynamic link library (DLL) to export itself to another process that needs to call a valid and consistent function. This requires a DLL export, which is not supported by the. NET Framework. Managed code does not give function pointers a uniform value because these functions are dynamically built proxies.
I found a lot of code on the internet, mostly including a C ++ DLL, which is used to identify the DLL containing the Child Program referred to by lpfn. It seems that this statement is also verified.
But this is not the case. You can use the following code to implement global hooks:
IntPtr pInstance = Marshal. GetHINSTANCE (Assembly. GetExecutingAssembly (). ManifestModule );
Win32API. SetWindowsHookEx (WH_MOUSE_LL, m_MouseHookProcedure, pInstance, 0 );
Note: The ManifestModule attribute is. net Framework 2.0 is newly added, so when you still use. net Framework 1. x, you can use the GetModules method to obtain all modules of the current Assembly, and then use one of them as the parameters of the GetHINSTAN method to obtain the appropriate handle pointer.
Hook application DEMO-screen Amplifier
Click to download the executable file (Shift + EscExit the Program)
Click to download the source file
The so-called screen amplifier is similar to a magnifier in a WINDOWS auxiliary tool.
Two days ago, when looking for information, I suddenly found that in 2.0, the Graphics class has a CopyFromScreen method, which can directly capture the screen, so I had the idea of making a screen amplifier.
First, I defined the SKHOOK class to intercept the keyboard and mouse.
You must obtain the global mouse message to determine the screenshot position and create a global shortcut to exit the program. Therefore, you can only use the hook mentioned above.
Then, I click the mouse to set the sampling area and the position of the form.
The sampling area is the 50*50 rectangular area centered on the mouse. The position of the form only follows the mouse and ensures that it does not overlap with the sampling area.
In addition, I used a BackgroundWorker to regularly refresh the update form. It is mainly used to display animated content (GIF, Flash, etc.
When moving, SetWindowPos is used to ensure that the form remains on the top layer. Otherwise, some top windows (such as QQ) will overwrite the current window.
Known issues:
1. Video capturing is not supported.
2. Some ToolTip prompts cannot be displayed
3. The background window may be invalid.
4. In the SKHook class, there are deficiencies in handling Keyboard Events.
Another problem is that when the mouse moves fast, the window border may have a shadow and I don't know why. This problem has always plagued me in the past Fram forms, and no solution has been found so far.