Như trong bài Giới thiệu kĩ thuật Hook và các khái niệm cơ bản đã trình bày, bạn có thể thấy rằng việc gọi CallNextHookEx() là việc cần thiết để tiếp tục gọi các hook procedure khác trong hook chain. Trường hợp bạn muốn chặn một thông điệp hay sự kiện nào đó, chỉ đơn giản là không gọi hàm CallNextHookEx() và trả về giá trị 1 trong hook procedure.
Trong ví dụ sau tôi sẽ chặn các phím Left Windows trên bàn phím, đồng thời cho Sendkey tên của phím đó để thay thế. Khi test bạn hãy mở một cửa sổ soạn thảo văn bản ra (như notepad) và focus nó. Sau đó hãy nhấn Left Windows, bạn sẽ không thấy Start Menu hiện ra và cửa sổ notepad sẽ được chèn vào dòng chữ LWin.
Tôi lấy lại ví dụ trong bài trước và sửa lại Hook procedure:
01 | private IntPtr KeyboardHookProc( int nCode, IntPtr wParam, IntPtr lParam) |
05 | KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof (KeyboardHookStruct)); |
07 | if (wParam == (IntPtr)WM_KEYDOWN) |
09 | Keys k= (Keys)kbStruct.VirtualKeyCode; |
14 | SendKeys.Send(k.ToString()); |
16 | } else if (k==Keys.Escape) |
21 | return CallNextHookEx(_hookHandle, nCode, wParam, lParam); |
Để làm ví dụ trên bạn tạo một WindowsFormsApplication mới, xóa Form1 và thêm lớp Y2KeyboardHook sau:
002 | using System.Runtime.InteropServices; |
003 | using System.Diagnostics; |
004 | using System.Windows.Forms; |
005 | using System.Reflection; |
006 | using System.ComponentModel; |
014 | #region Win32 API Functions and Constants |
016 | [DllImport( "user32.dll" , SetLastError = true )] |
017 | private static extern IntPtr SetWindowsHookEx( int idHook, |
018 | KeyboardHookDelegate lpfn, IntPtr hMod, int dwThreadId); |
020 | [DllImport( "user32.dll" , SetLastError = true )] |
021 | private static extern bool UnhookWindowsHookEx(IntPtr hhk); |
023 | [DllImport( "user32.dll" , SetLastError = true )] |
024 | private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, |
025 | IntPtr wParam, IntPtr lParam); |
027 | [DllImport( "kernel32.dll" )] |
028 | private static extern IntPtr GetModuleHandle( string lpModuleName); |
030 | private const int WH_KEYBOARD_LL = 13; |
032 | private const int WM_KEYDOWN = 0x0100; |
033 | private const int WM_KEYUP = 0x101; |
037 | private KeyboardHookDelegate _hookProc; |
038 | private IntPtr _hookHandle = IntPtr.Zero; |
040 | public delegate IntPtr KeyboardHookDelegate( int nCode, IntPtr wParam, IntPtr lParam); |
042 | [StructLayout(LayoutKind.Sequential)] |
043 | public struct KeyboardHookStruct |
045 | public int VirtualKeyCode; |
049 | public int ExtraInfo; |
058 | public void Install() |
060 | _hookProc = KeyboardHookProc; |
061 | _hookHandle = SetupHook(_hookProc); |
063 | if (_hookHandle == IntPtr.Zero) |
064 | throw new Win32Exception(Marshal.GetLastWin32Error()); |
066 | private IntPtr SetupHook(KeyboardHookDelegate hookProc) |
068 | IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]); |
070 | return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0); |
073 | private IntPtr KeyboardHookProc( int nCode, IntPtr wParam, IntPtr lParam) |
077 | KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof (KeyboardHookStruct)); |
079 | if (wParam == (IntPtr)WM_KEYDOWN) |
081 | Keys k= (Keys)kbStruct.VirtualKeyCode; |
086 | SendKeys.Send(k.ToString()); |
088 | } else if (k==(Keys.Escape)) |
093 | return CallNextHookEx(_hookHandle, nCode, wParam, lParam); |
096 | public void Uninstall() |
098 | UnhookWindowsHookEx(_hookHandle); |
Lớp Program:
02 | using System.Windows.Forms; |
05 | namespace WindowsFormsApplication1 |
07 | internal sealed class Program |
11 | private static void Main( string [] args) |
13 | Y2KeyboardHook keyboardHook = new Y2KeyboardHook(); |
14 | keyboardHook.Install(); |
Muốn thoát ứng dụng bạn hãy nhấn Escape.
Không có nhận xét nào:
Đăng nhận xét