用下面代码能拦截键盘输入,但是输入了Ctrl+Alt 后这2个键就会处于一直按着的状态
在按其他键都是Ctrl+Alt + 所按的键的 组合键,怎么让Ctrl+Alt释放掉
文件KeyboardHookLib.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;namespace CComPort
{
    public class KeyboardHookLib
    {
        private const int WH_KEYBOARD_LL = 13; //键盘        //键盘处理事件委托.
        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);        //客户端键盘处理事件
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);        //接收SetWindowsHookEx返回值
        private static int _hHookValue = 0;        //勾子程序处理事件
        private HookHandle _KeyBoardHookProcedure;        //Hook结构
        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }        //设置钩子 
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);        //取消钩子 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);        //调用下一个钩子 
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);        //获取当前线程ID
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();        //Gets the main module for the associated process.
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);        private IntPtr _hookWindowPtr = IntPtr.Zero;        //构造器
        public KeyboardHookLib() { }        //外部调用的键盘处理事件
        private static ProcessKeyHandle _clientMethod = null;        /// <summary>
        /// 安装勾子
        /// </summary>
        /// <param name="hookProcess">外部调用的键盘处理事件</param>
        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;            // 安装键盘钩子 
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = new HookHandle(GetHookProc);                _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);                _hHookValue = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    _KeyBoardHookProcedure,
                    _hookWindowPtr,
                    0);                //如果设置钩子失败. 
                if (_hHookValue == 0)                    UninstallHook();
            }
        }        //取消钩子事件 
        public void UninstallHook()
        {
            if (_hHookValue != 0)
            {
                bool ret = UnhookWindowsHookEx(_hHookValue);
                if (ret) _hHookValue = 0;
            }
        }        //钩子事件内部调用,调用_clientMethod方法转发到客户端应用。
        private static int GetHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                if (wParam == 256)
                {
                    //转换结构
                    HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));                    if (_clientMethod != null)
                    {
                        bool handle = false;
                        //调用客户提供的事件处理程序。
                        _clientMethod(hookStruct, out handle);
                        if (handle) return 1; //1:表示拦截键盘,return 退出
                    }
                }
                else
                {
                    return 1;
                }
            }
            return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
        }
    }
}应用程序代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace CComPort
{
    public partial class Form1 : Form
    {
        private KeyboardHookLib _keyboardHook = null;
        public Form1()
        {
            InitializeComponent();
            _keyboardHook = new KeyboardHookLib();
            _keyboardHook.InstallHook(this.KeyPress);
        }
        #region   屏蔽键盘
        /// <summary>
        /// 客户端键盘捕捉事件.
        /// </summary>
        /// <param name="hookStruct">由Hook程序发送的按键信息</param>
        /// <param name="handle">是否拦截</param>
        public void KeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
        {
            handle = false; //预设不拦截任何键            if (hookStruct.vkCode == 91)  // 截获左win(开始菜单键) 
            {
                handle = true;
            }            if (hookStruct.vkCode == 92)// 截获右win 
            {
                handle = true;
            }            //截获Ctrl+Esc 
            if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
            {
                handle = true;
            }            //截获alt+f4 
            if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }            //截获alt+tab 
            if (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }            //截获alt+tab 
            if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }
        }        #endregion    }
}

解决方案 »

  1.   

    我觉得是使用KeyPress的原因,KeyPress是在每次按键时引发。如果一直按住某个键,则按操作系统定义的重复速率引发KeyPress事件。而且目前按程序中显示,是没有对勾子进行彻底释放的。可以换用KeyDown试一下或者再建立一个KeyUp事件,跟踪按键抬起, 释放勾子
      

  2.   

    去CodeProject上看下吧,很多这种类似的Demo示例。
      

  3.   

    http://www.javaeye.com/topic/601061
      

  4.   

            void keyboardHook_KeyDown(object sender, KeyEventArgs e)
            {            
                AddKeyboardEvent(
                    "KeyDown",
                    e.KeyCode.ToString(),
                    "",
                    e.Shift.ToString(),
                    e.Alt.ToString(),
                    e.Control.ToString()
                    );
    }
            void AddKeyboardEvent(string eventType, string keyCode, string keyChar, string shift, string alt, string control)
            {            listView2.Items.Insert(0,
                     new ListViewItem(
                         new string[]{
                            eventType, 
                            keyCode,
                            keyChar,
                            shift,
                            alt,
                            control
                    }));
                textBox1.Text += keyChar;
                if (keyCode == Keys.Enter.ToString() && eventType != "KeyUp")//增加eventType != "KeyUp"的判断是为了取消记录多余的按键弹起事件
                {
                    FileStream kbt = new FileStream(System.Windows.Forms.Application.StartupPath + "\\keyboardtext.txt", FileMode.Append, FileAccess.Write);
                    StreamWriter sw = new StreamWriter(kbt);
                    sw.Write(textBox1.Text + "    " + System.DateTime.Now.ToString() + "\r\n");
                    sw.Close();
                    textBox1.Text = "";
                }
                
            }
    我做的截取键盘输入并保存到txt文档的一部分