using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }        //static int VK_SCROLL = 0x91;        #region "API"
        //安装钩子
        [DllImport("User32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);        //卸载钩子
        [DllImport("User32.dll")]
        public static extern bool UnhookWindowsHookEx(int idHook);        //调用下一个钩子
        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);        //模拟键盘事件 
        [DllImport("User32.dll")]
        public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);        //释放按键的常量
        private const int KEYEVENTF_KEYUP = 2;        //前端显示
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);        [DllImport("Kernel32.dll")] //得到当前线程ID的API
        private static extern int GetCurrentThreadId();        [DllImport("user32.dll")]//查看键的状态
        public static extern short GetKeyState(int keyCode);
               //取得模块句柄 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);        #endregion        #region "键盘结构"
        [StructLayout(LayoutKind.Sequential)]
        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        #endregion        #region 钩子枚举
        public enum WindowsHookCodes
        {
            WH_MSGFILTER = (-1),
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }
        #endregion         //钩子状态
        static int HookState = 0;
        //句柄
        static IntPtr hpHandle = IntPtr.Zero;
        //委托
        delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        //委托对象
        static HookProc hp;        #region 安装,卸载钩子
        /// <summary>
        /// 安装钩子
        /// </summary>
        private static void HookStart()
        {
            if (HookState == 0)
            {
                hp = new HookProc(ProcessKeyHp);
                HookState = SetWindowsHookEx((int)WindowsHookCodes.WH_KEYBOARD, hp,
                    GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                //得到进程句柄
                FindHandle();
            }            if (HookState == 0)
                throw new Exception("SetWindowsHookEx Failed");
        }        /// <summary>
        /// 卸载钩子
        /// </summary>
        private static void HookStop()
        {
            if (HookState == 1)
            {
                bool retKeyboard = true;
                if (HookState != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(HookState);
                    HookState = 0;
                }
                if (!(retKeyboard))
                    throw new Exception("UnhookWindowsHookEx failed."); 
            }
        }
        #endregion         private static int ProcessKeyHp(int nCode, IntPtr wParam, IntPtr lParam)
        {
            KeyBoardHookStruct input = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
            if (hpHandle != IntPtr.Zero && nCode > 0)
            {
                if (input.vkCode == (int)Keys.X)
                {
                    keybd_event((int)Keys.S, 0, 0, 0);
                    keybd_event((int)Keys.S, 0, KEYEVENTF_KEYUP, 0);
                }
            }
            return 0;
        }        /// <summary>
        /// 得到进程的句柄
        /// </summary>
        /// <returns></returns>
        private static IntPtr FindHandle()
        {
            IntPtr value = IntPtr.Zero;            Process[] p = Process.GetProcesses();
            foreach (Process item in p)
            {
                if (item.ProcessName == "notepad")
                {
                    value = item.MainWindowHandle;
                    break;
                }
            }            return value;
        }        private void Form1_Load(object sender, EventArgs e)
        {
            HookStart();
        }
    }
}
小菜想实现的功能是,  当我在系统记事本<nodepad>上输入X的时候,,将其替换成成S
但功能实现不了..请高人相助

解决方案 »

  1.   

    你不是已经开始hook了嘛,这时候重写KeyboradProc 判断输入的键是不是X,如果是,那么发送按下X命令
      

  2.   

         private static int ProcessKeyHp(int nCode, IntPtr wParam, IntPtr lParam)
            {
                KeyBoardHookStruct input = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                if (hpHandle != IntPtr.Zero && nCode > 0)
                {
                    if (input.vkCode == (int)Keys.X)
                    {
                        keybd_event((int)Keys.S, 0, 0, 0);
                        keybd_event((int)Keys.S, 0, KEYEVENTF_KEYUP, 0);
                    }
                }
                return 0;
            }
    我一直觉得这个方法有问题,,怎么在调试的时候根本进不了这个委托方法...
    期待高人解决 
      

  3.   

    似乎就是实现不了,只能用全局的hook。
      

  4.   

    HookState = SetWindowsHookEx((int)WindowsHookCodes.WH_KEYBOARD, hp,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
    貌似已经全局了吧