博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 屏蔽快捷键
阅读量:7051 次
发布时间:2019-06-28

本文共 6874 字,大约阅读时间需要 22 分钟。

前言

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

原理

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    {        ///         /// 应用程序的主入口点。        ///         [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

转载于:https://www.cnblogs.com/leestar54/p/4811711.html

你可能感兴趣的文章
centos5.7下的kdump
查看>>
[JavaEE笔记]Cookie
查看>>
ELK+Filebeat (1)
查看>>
leetcode 443. String Compression
查看>>
在没联网环境下,启动tomcat出错
查看>>
关于Git bash-127.0.0.7:8888拒绝访问的小问题--环境变量
查看>>
有价值的数据
查看>>
LayUi超级好用的前端工具
查看>>
[Ubuntu] ubuntu的tty下挂载移动硬盘拷贝数据
查看>>
犯了个低级错误
查看>>
Outlook Anywhere 客户端配置详解
查看>>
IOS在Xcode 4.x以上如何 创建 和 添加 静态库
查看>>
Repeater控件数据导出Excel
查看>>
下载Android源码出现的问题
查看>>
远程桌面如何复制本地文件 远程桌面拷贝电脑上的文件方法
查看>>
[转]解决JS浮点数(小数)计算加减乘除的BUG
查看>>
ASP.NET MVC应用程序的安全性介绍总括(高级编程)
查看>>
记录下,我们平时开发当中不得不知道的HTTP状态码
查看>>
HDU-1045 Fire NetFire Net 最大团
查看>>
Eclipse自动部署项目到Tomcat的webapps下的有效方法
查看>>