zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    uni app 零基础小白到项目实战
    uni-app 事件以及事件绑定
    uni-app 事件以及事件绑定
    uni-app 组件
    uni-app 组件
    uni-app 网络请求
    uni-app 网络请求
    uni-app 图片上传实战
    uni-app 图片上传实战
    uni-app下拉刷新加载刷新数据
  • 原文地址:https://www.cnblogs.com/leestar54/p/4811711.html
Copyright © 2011-2022 走看看