c# 屏蔽快捷键

前言

有时候开发会遇到这样一个需求,软件需要屏蔽用户的组合快捷键或某些按键,避免强制退出软件,防止勿操作等。

原理

1、要实现组合键,按键拦截,需要用到user32.dll中的SetWindowsHookEx。

2、要拦截ctrl+alt+del,需要使用ntdll.dll的ZwSuspendProcess函数挂起winlogon程序,退出之后使用ZwResumeProcess恢复winlogon程序。

3、软件需要开启topMost,以及全屏,否则离开软件则拦截无效。

4、如果要实现热键监听(非焦点拦截),则需要用到user32.dll的RegisterHotKey以及UnregisterHotKey。

实现

1、Program类

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace LockForm
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            SuspendWinLogon();
            Application.Run(new Form1());
            ResumeWinLogon();
        }

        [DllImport("ntdll.dll")]
        public static extern int ZwSuspendProcess(IntPtr ProcessId);
        [DllImport("ntdll.dll")]
        public static extern int ZwResumeProcess(IntPtr ProcessId);

        private static void SuspendWinLogon()
        {
            Process[] pc = Process.GetProcessesByName("winlogon");
            if (pc.Length > 0)
            {
                ZwSuspendProcess(pc[0].Handle);
            }
        }

        private static void ResumeWinLogon()
        {
            Process[] pc = Process.GetProcessesByName("winlogon");
            if (pc.Length > 0)
            {
                ZwResumeProcess(pc[0].Handle);
            }
        }
    }
}

2、Form1类

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

namespace LockForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "123")
            {
                Application.ExitThread();
            }
            else
            {
                webBrowser1.Navigate(textBox1.Text);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //webBrowser1.Navigate("https://baidu.com");
            HookStart();
            //this.TopMost = false;
            //SuspendWinLogon();
        }

        private void webBrowser1_NewWindow(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
            webBrowser1.Navigate(webBrowser1.Document.ActiveElement.GetAttribute("href"));
        }

        private void button3_Click(object sender, EventArgs e)
        {
            webBrowser1.GoBack();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            webBrowser1.GoForward();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            webBrowser1.GoHome();
        }

        private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            textBox1.Text = webBrowser1.Url.ToString();
        }

        private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {

        }

        #region 键盘钩子

        public delegate int HookProc(int nCode, int wParam, IntPtr lParam);//定义全局钩子过程委托,以防被回收(钩子函数原型)
        HookProc KeyBoardProcedure;

        //定义键盘钩子的相关内容,用于截获键盘消息
        static int hHook = 0;//钩子函数的句柄
        public const int WH_KEYBOARD = 13;
        //钩子结构函数
        public struct KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;

        }
        //安装键盘钩子
        public void HookStart()
        {

            if (hHook == 0)
            {
                //实例化一个HookProc对象
                KeyBoardProcedure = new HookProc(Form1.KeyBoardHookProc);

                //创建线程钩子
                hHook = Win32API.SetWindowsHookEx(WH_KEYBOARD, KeyBoardProcedure, Win32API.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

                //如果设置线程钩子失败
                if (hHook == 0)
                {
                    HookClear();
                }
            }
        }

        //取消钩子
        public void HookClear()
        {
            bool rsetKeyboard = true;
            if (hHook != 0)
            {
                rsetKeyboard = Win32API.UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
            if (!rsetKeyboard)
            {
                throw new Exception("取消钩子失败!");
            }
        }
        //对截获的键盘操作的处理
        public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));

                if (kbh.vkCode == 91)//截获左边WIN键
                {
                    return 1;
                }
                if (kbh.vkCode == 92)//截获右边WIN键
                {
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)//截获Ctrl+ESC键
                {
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt)
                {
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)//截获ALT+F4
                {
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)//截获ALT+TAB
                {
                    return 1;
                }
                if (kbh.vkCode == (int)Keys.Delete&&(int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt)
                {
                    return 1;
                }
                if ( kbh.vkCode == (int) Keys.Escape && (int) Control.ModifierKeys == (int) Keys.Control + (int) Keys.Alt )   /* 截获Ctrl+Shift+Esc */
                {
                    return 1;
                }

            }

            return Win32API.CallNextHookEx(hHook, nCode, wParam, lParam);
        }
        #endregion
    }
}

3、声明windows api

        //设置钩子
        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, LockForm.Form1.HookProc lpfn, IntPtr hInstance, int threadID);

        //卸载钩子
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //调用下一个钩子
        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

PS:

windows api查询

http://www.pinvoke.net/index.aspx

demo下载

链接:http://pan.baidu.com/s/1jGpOvsE 密码:dbj2

时间: 2024-08-22 01:57:17

c# 屏蔽快捷键的相关文章

C# 通过Hook的方法 屏蔽快捷键

#region 屏蔽Windows功能键(快捷键) public delegate int HookProc(int nCode, int wParam, IntPtr lParam); private static int hHook = 0; public const int WH_KEYBOARD_LL = 13; //LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,会在你截取之前获得键盘. private static HookProc KeyBoard

WPF的TreeView执行ExpandSubtree时抛出异常System.NullReferenceException

?? 最近拿到一个dump,有应用崩溃,通过查看dump,异常信息如下: 0:012> !pe Exception object: 0000000005187278 Exception type:   System.NullReferenceException Message:          Object reference not set to an instance of an object. InnerException:   <none> StackTrace (genera

win8/win7屏蔽ctrl+alt+up/down快捷键的方法

win7屏蔽ctrl+alt+up/down快捷键 Eclipse有个非常好用的快捷键(当然Eclipse好用的快捷键有N个)Ctrl+Alt+UP/DOWN,用于复制当前行的内容,用法很简单,将光标置与要复制的行任意位置,然后按快捷键Ctrl+Alt+UP/DOWN(UP.DOWN分别对应与键盘的上下键按键),将分别在当前行的上一行或者下一行复制一行当前的内容,复制后光标位于复制后的行内. 前阵子机器安装了Win7后,突然发现在Eclipse里面按Ctrl+Alt+DOWN后不是预期的效果,而

[C#]回车键实现输入光标的切换及系统快捷键的屏蔽

利用回车键将输入光标切换到下一个输入框以及系统快捷键Ctrl+C.V.X的屏蔽 private void textBox2_KeyDown(object sender, KeyEventArgs e) {     if ( e.KeyValue == (char)Keys.Enter )     {         SendKeys.Send("{TAB}");//将回车键转换为Tab键  也可以让下一个文本输入框获得焦点(txt.Focus())来实现               }

如何屏蔽SkylineGlobe提供的三维地图控件上的快捷键

SkyllineGlobe提供的 <OBJECT ID=" TerraExplorer3DWindow" CLASSID="CLSID:3a4f9192-65a8-11d5-85c1-0001023952c1" width=500 height=400></OBJECT>可以用来加载显示FLY格式的三维地图工程,可以嵌入到HTML页面中. 这个三维地图控件里,封装了在TerraExplorer中的一些快捷键,比如控制方向的"Q/W/

c++屏蔽Win10系统快捷键

很久之前实现的功能,也是参考其他人的实现,时间太久,具体参考哪里已经记不得了. 这里不仅能屏蔽一般的快捷键,还可以屏蔽ctrl+atl+del. int globlePid = 0; HHOOK keyHook = NULL; HHOOK mouseHook = NULL; //键盘钩子过程 LRESULT CALLBACK keyProc(int nCode, WPARAM wParam, LPARAM lParam) { //在WH_KEYBOARD_LL模式下lParam 是指向KBDLL

IAR快捷键

1.显示行号:在代码段点击右键,找到Options->Editor,将右面的Show Line Numbers 勾选上就可以了. 2.注释的快捷键:Ctrl+K;取消注释:Ctrl+Shfit+K 3.Ctrl+Shfit+空格,可以使用IAR提供的内部代码的编写,如if语句. 4.格式化源码 CTRL + T 5.程序{}花括号的配对内容查找.CTRL + B 则自动的把这段内容 反色的选中. 6.自动缩进 选中某些行,然后 使用 CTRL + SHIFT +I ,可以实现自动的缩进 7.Ct

Android Studio快捷键每日一练(1)

原文地址:http://www.developerphil.com/android-studio-tips-of-the-day-roundup-1/ 1.高亮显示相同的字符串 苹果:Cmd+shift+F7    Windows:Ctrl+shift+F7 这个快捷键会在当前文件中搜索这个字符串出现的所有位置.不同于一些简单的模式匹配,该快捷键能够感知当前的作用域并仅仅只高亮相关的字符串.然后可以使用菜单Edit->Find->Find Next/Previous在这些匹配项中进行移动. 更

robotframework 常用快捷键

重命名-->F2搜索关键字-->F5执行用例-->F8创建新工程-->ctrl+n创建新测试套-->ctrl+shift+f创建新用例-->ctrl+shift+t创建新关键字-->ctrl+shift+k向上移动用例-->ctrl+↑向下移动用例-->ctrl+↓显示关键字信息--> ctrl+鼠标悬浮(鼠标悬浮于关键字上)自动补全关键字-->ctrl+shift+空格删除行-->ctrl+d删除单元格-->ctrl+shif