Chủ nhật, ngày 11 tháng 12 năm 2016

C# – Chặn/vô hiệu hóa thông điệp keyboard bằng Hook

Ngày đăng: 19/3/2012, 12:48:32PM | Lượt xem: 2,995
Hot!

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.

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:

private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0)
    {
        KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

        if (wParam == (IntPtr)WM_KEYDOWN)
        {
            Keys k= (Keys)kbStruct.VirtualKeyCode;

            // disable Left Windows
            if(k==Keys.LWin)
            {
                SendKeys.Send(k.ToString());
                return (IntPtr)1;
            }else if(k==Keys.Escape) // exit program
                Application.Exit();
        }
    }

    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:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;

namespace HookApp
{

    class Y2KeyboardHook
    {

        #region Win32 API Functions and Constants

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            KeyboardHookDelegate lpfn, IntPtr hMod, int dwThreadId);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private const int WH_KEYBOARD_LL = 13;

        private const int WM_KEYDOWN = 0x0100;
        private const int WM_KEYUP = 0x101;

        #endregion

        private KeyboardHookDelegate _hookProc;
        private IntPtr _hookHandle = IntPtr.Zero;

        public delegate IntPtr KeyboardHookDelegate(int nCode, IntPtr wParam, IntPtr lParam);

        [StructLayout(LayoutKind.Sequential)]
        public struct KeyboardHookStruct
        {
            public int VirtualKeyCode;
            public int ScanCode;
            public int Flags;
            public int Time;
            public int ExtraInfo;
        }

        // destructor
        ~Y2KeyboardHook()
        {
            Uninstall();
        }

        public void Install()
        {
            _hookProc = KeyboardHookProc;
            _hookHandle = SetupHook(_hookProc);

            if (_hookHandle == IntPtr.Zero)
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        private IntPtr SetupHook(KeyboardHookDelegate hookProc)
        {
            IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);

            return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
        }

        private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

                if (wParam == (IntPtr)WM_KEYDOWN)
                {
                    Keys k= (Keys)kbStruct.VirtualKeyCode;

                    // disable Left Windows, Left Shift and Left Control keys
                    if(k==Keys.LWin)
                    {
                        SendKeys.Send(k.ToString());
                        return (IntPtr)1;
                    }else if(k==(Keys.Escape)) // exit program
                        Application.Exit();
                }
            }

            return CallNextHookEx(_hookHandle, nCode, wParam, lParam);
        }

        public void Uninstall()
        {
            UnhookWindowsHookEx(_hookHandle);
        }

    }
}

Lớp Program:

using System;
using System.Windows.Forms;
using HookApp;

namespace WindowsFormsApplication1
{
    internal sealed class Program
    {

        [STAThread]
        private static void Main(string[] args)
        {
            Y2KeyboardHook keyboardHook = new Y2KeyboardHook();
            keyboardHook.Install();
            Application.Run();
        }

    }
}

Muốn thoát ứng dụng bạn hãy nhấn Escape.

.NET FAQ

 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.