首页 新闻 搜索 专区 学院

win7下键盘钩子失效

0
悬赏园豆:50 [已关闭问题] 关闭于 2010-03-12 21:03

win7下SetWindowsHookEx ,返回的总是0,钩子失效怎么办?有什么替代方案?

程序如下:高手麻烦修改下,难道只有XP才可以用钩子。。。

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;

namespace HookTest
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        //委托
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        static int hHook = 0;
        public const int WH_KEYBOARD_LL = 13;
        //LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat Reader会在你截取之前获得键盘。
        HookProc KeyBoardHookProcedure;
        //键盘Hook结构函数
        [StructLayout(LayoutKind.Sequential)]
        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        #region DllImport
        //设置钩子
        [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 bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        //调用下一个钩子
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
        #endregion
        #region 自定义事件
        public void Hook_Start()
        {
            // 安装键盘钩子
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);
                IntPtr ss=Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure,ss , 0);
                //如果设置钩子失败.
                //if (hHook == 0)
                //{
                //    Hook_Clear();
                //    MessageBox.Show("ssssss");
                //}
            }
        }

        //取消钩子事件
        public void Hook_Clear()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
            //如果去掉钩子失败.
            if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
        }

        //这里可以添加自己想要的信息处理
        public  int KeyBoardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                if (kbh.vkCode == (int)Keys.S && (int)Control.ModifierKeys == (int)Keys.Control)  // 截获F8
                {
                    MessageBox.Show("快捷键已拦截!不能保存!");
                    return 1;
                }
                //if ((int)Control.ModifierKeys == (int)Keys.Delete && (int)Control.ModifierKeys == (int)Keys.Alt && (int)Control.ModifierKeys == (int)Keys.Control)
                //{
                //    MessageBox.Show("捕捉到Ctrl+Alt+Delete");
                //    return 1;
                //}
                if (kbh.vkCode == (int)Keys.Y
                   && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt)  //截获Ctrl+Alt+Y
                {
                    About msg = new About();
                    msg.Show();
                    //MessageBox.Show("不能全部保存!");
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.A)
                {
                   // MessageBox.Show("A");
                    this.label1.Text += "A";
                }
                if (kbh.vkCode == (int)Keys.B)
                {
                   // MessageBox.Show("B");
                    this.label1.Text += "B";
                }
                if (kbh.vkCode == (int)Keys.Enter)
                {
                    this.label1.Text = "执行成功!";
                }
                if(kbh.vkCode==(int)Keys.Back)
                {
                    this.label1.Text = this.label1.Text.Remove(this.label1.Text.Length-1) ;
                }
                if (kbh.vkCode == (int)Keys.D1)
                {
                    this.label1.Text += "1";
                }
            }
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }
        #endregion
       
        /*
        [STAThread]
        public static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
        */

        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
          
        }

        void Start_BtnClick(object sender, EventArgs e)
        {
            this.Hook_Start();
        }

        void Clear_BtnClick(object sender, EventArgs e)
        {
            this.Hook_Clear();
        }
    }
}

 

piikee的主页 piikee | 初学一级 | 园豆:160
提问于:2010-03-03 16:21
< >
分享
所有回答(3)
0

XP和Vista/Windows7的API有差异哦.貌似都是Session 0惹的祸啊。

博客园有人写过相关文章(不适用Vista/Windows7),链接有

http://www.cnblogs.com/linmilove/archive/2009/06/10/1500782.html

http://www.cnblogs.com/freedom831215/archive/2009/10/03/1577523.html

另有 浅析Visual Studio在Win7下用户界面特权隔离简单叙述钩子实现 一文,文中做了部分的描述,这个问题记得去年10月份Windows7发布后的一次聚会演讲时有人说到过这个问题。疲于当时不搞这个就给放过去了。

西越泽 | 园豆:10713 (专家六级) | 2010-03-03 16:29
0
 

在LoadIcon function 中设置lpszIcon的值为下面列表中的其中一个:
lpszIcon can be one of these value:
IDI_APPLICATION
IDI_ASTERISK
IDI_ERROR
IDI_EXCLAMATION
IDI_HAND
IDI_INFORMATION
IDI_QUESTION
IDI_WARNING
IDI_WINLOGO

so you can use them directly.
msgparam.lpszIcon = IDI_WINLOGO;

参考文章:http://www.codeproject.com/Messages/2660437/Re-Error-specify-the-lpszIcon-in-the-MSGBOXPARAM-u.aspx

风影极光 | 园豆:1573 (小虾三级) | 2010-03-03 16:46
0

注意:  
  1.  
  勾子句柄是一个用户句柄,它属创建的线程所拥有,如果当创建的线程退出,则勾子将变为无效。  
   
  2.  
  目标勾子线程需要消息循环为基础。  
   
  3.  
  夸桌面勾子没有意义。

生鱼片 | 园豆:5757 (大侠五级) | 2010-03-03 21:37
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册