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

你可能感兴趣的:(c# 屏蔽快捷键)