谁能跟我具体讲一讲这个、。。在网上看了不少例子,也看了不少源码,但就是看不懂我想做的就是在指定窗口实现类似改建功能,例如:当程序运行后,可以在另外的指定程序上按下A,输出B谁能讲讲钩子呢?hookC#

解决方案 »

  1.   

    @icdbow  
    多谢了,这几天我试着参考网上的资料写了一个魔兽dota改建的程序
    但是碰到了一个问题,一般情况下改建都成功,但是当把其它的键(比如物品栏)改成F1的时候,由于dota游戏的F1默认是选取自己的英雄,因此,按了F1游戏的焦点就到了英雄的身上,改建的效果就没了。
    有没有知道如果解决这个问题的?
      

  2.   

      SetWindowHooEx,钩子类型,子程,模块,以及挂钩线程。  键盘钩子,线程wh_keyboard,C#中需要DLL的支持,子程写在DLL中进行动态封装,在c# 中通过动态寻址方式获取到自称,进行参数传递的执行。msdn 明确表示不支持线程钩子。  键盘全局钩子,wh_keyboardLL,子程放在当前模块就行了,全局threadid为零。要执行的话回调函数nocode 必须为HC_ACCTION.wparam,lparam分别为虚拟键和扫描键消息。   全局的则为KBDLLHOOKSTRUCT 结构体,KBDLLHOOKSTRUCT结构体包含所有键盘操作,c#中的定义为   int vkCode;            //键盘消息的虚拟键信息,值的范围从1至254   int scanCode;            //键盘的扫描码信息 DWORD flags;            //键盘的扩展信息 DWORD time;                //消息的产生时间,可以用    GetMessageTime 函数取得 ULONG_PTR dwExtraInfo;    //消息的扩展信息   包括所谓的QQ盗号哦。
      

  3.   


    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;namespace 钩子练习1
    {
        public class myHook
        {
            private const int WM_KEYDOWN = 0x100;//按下消息
            private const int WM_KEYUP = 0x101;//松开消息
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;        //全局事件
            public event KeyEventHandler OnKeyDownEvent;
            public event KeyEventHandler OnKeyUpEvent;
            public event KeyPressEventHandler OnKeyPressEvent;        static int hKeyboardHook = 0;        //鼠标常量
            public const int WH_KEYBOARD_LL = 13;        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);        //声明键盘钩子事件类型
            HookProc KeyboardHookProcedure;        /// <summary>
            /// 声明键盘钩子的封送结构类型
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode;//表示一个1到254间的虚拟键盘码
                public int scanCode;//表示硬件扫描码
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
            //安装钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
            //下一个钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
            //卸载钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
            
            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKBHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));                //引发OnKeyDownEvent
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKBHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(keyData);
                        OnKeyDownEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }        public void Start()
            {
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                    using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess())
                    using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule)
                        hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);                if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("Set GlobalKeyboardHook failed!");
                    }
                }
            }
            public void Stop()
            {
                bool retKeyboard = true;
                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                if (!retKeyboard)
                    try
                    {
                        throw new Exception("Unload GlobalKeyboardHook failed!");
                    }
                    catch { }
            }        //构造函数中安装钩子
            public myHook()
            {
                Start();
            }
            //析构函数中卸载钩子
            ~myHook()
            {
                Stop();
            }
        }
    }
      

  4.   

    return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    这句应该是传递钩子用的。如果发现特定的按键,执行完自己的事件,就直接return 1;
    试试这样行不?