Как правильно снять UnHook?

Я сделал очень простые коды Hook (я новичок).

Я открыл Блокнот и проверил.

Если я нажимаю ЛЮБУЮ клавишу, он издает звуковой сигнал и печатает сам.

За исключением ключа "x", это ключ-терминатор.

Вопрос:

Я не хочу видеть ключ "х" напечатанным. Я просто вышел из программы. Что мне нужно сделать?

namespace HookingStudy
{
    class HookingClass          
    {
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = hookCallBack;
        private static IntPtr _hookID = IntPtr.Zero;                    
        public static void Main()
        {
            Beep(1111, 222);
            _hookID = SetHook(_proc);
            Application.Run();
        }
        private static IntPtr hookCallBack(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if( nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN )
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if( vkCode.ToString() == "88" )                 //   88 ("x" key)
                {
                    Beep(7777, 222);
                    UnhookWindowsHookEx(_hookID);     
                    Process.GetCurrentProcess().Kill(); 
                }
                Beep(2222, 55);
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);  
        }
        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using( Process curProcess = Process.GetCurrentProcess() )
            using( ProcessModule curModule = curProcess.MainModule )
            {
                return SetWindowsHookEx(13, proc, GetModuleHandle(curModule.ModuleName), 0);
            }                   
        }
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("KERNEL32.DLL")]                             
        extern public static void Beep(int freq, int dur);      
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }  
}

1 ответ

Я не хочу видеть терминатор x напечатано в блокноте

Тогда не вызывайте следующий хук в цепочке:

return CallNextHookEx(_hookID, nCode, wParam, lParam);

Идея зацепить его, чтобы установить собственный обработчик ранее существующих обработчиков (прямо из winapi). Перехватывая (как вы уже это делаете), вы не только слушаете, но и вызываете предыдущие обработчики с этим вызовом.

Попробуйте что-то вроде (не проверено):

if( vkCode == 88)
{
    ...
    return 0;
}
Другие вопросы по тегам