c# 屏蔽快捷鍵的實(shí)現(xiàn)示例
前言
有時(shí)候開(kāi)發(fā)會(huì)遇到這樣一個(gè)需求,軟件需要屏蔽用戶(hù)的組合快捷鍵或某些按鍵,避免強(qiáng)制退出軟件,防止勿操作等。
原理
1、要實(shí)現(xiàn)組合鍵,按鍵攔截,需要用到user32.dll中的SetWindowsHookEx。
2、要攔截ctrl+alt+del,需要使用ntdll.dll的ZwSuspendProcess函數(shù)掛起winlogon程序,退出之后使用ZwResumeProcess恢復(fù)winlogon程序。
3、軟件需要開(kāi)啟topMost,以及全屏,否則離開(kāi)軟件則攔截?zé)o效。
4、如果要實(shí)現(xiàn)熱鍵監(jiān)聽(tīng)(非焦點(diǎn)攔截),則需要用到user32.dll的RegisterHotKey以及UnregisterHotKey。
實(shí)現(xiàn)
1、Program類(lèi)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace LockForm
{
static class Program
{
/// <summary>
/// 應(yīng)用程序的主入口點(diǎn)。
/// </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類(lèi)
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 鍵盤(pán)鉤子
public delegate int HookProc(int nCode, int wParam, IntPtr lParam);//定義全局鉤子過(guò)程委托,以防被回收(鉤子函數(shù)原型)
HookProc KeyBoardProcedure;
//定義鍵盤(pán)鉤子的相關(guān)內(nèi)容,用于截獲鍵盤(pán)消息
static int hHook = 0;//鉤子函數(shù)的句柄
public const int WH_KEYBOARD = 13;
//鉤子結(jié)構(gòu)函數(shù)
public struct KeyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
//安裝鍵盤(pán)鉤子
public void HookStart()
{
if (hHook == 0)
{
//實(shí)例化一個(gè)HookProc對(duì)象
KeyBoardProcedure = new HookProc(Form1.KeyBoardHookProc);
//創(chuàng)建線(xiàn)程鉤子
hHook = Win32API.SetWindowsHookEx(WH_KEYBOARD, KeyBoardProcedure, Win32API.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
//如果設(shè)置線(xiàn)程鉤子失敗
if (hHook == 0)
{
HookClear();
}
}
}
//取消鉤子
public void HookClear()
{
bool rsetKeyboard = true;
if (hHook != 0)
{
rsetKeyboard = Win32API.UnhookWindowsHookEx(hHook);
hHook = 0;
}
if (!rsetKeyboard)
{
throw new Exception("取消鉤子失敗!");
}
}
//對(duì)截獲的鍵盤(pán)操作的處理
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
//設(shè)置鉤子
[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);
//調(diào)用下一個(gè)鉤子
[DllImport("user32.dll")]
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
PS:
windows api查詢(xún)
http://www.pinvoke.net/index.aspx
demo下載
鏈接:http://pan.baidu.com/s/1jGpOvsE 密碼:dbj2
以上就是c# 屏蔽快捷鍵的實(shí)現(xiàn)示例的詳細(xì)內(nèi)容,更多關(guān)于c# 屏蔽快捷鍵的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# ThreadPool之QueueUserWorkItem使用案例詳解
這篇文章主要介紹了C# ThreadPool之QueueUserWorkItem使用案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
C#中使用快速排序按文件創(chuàng)建時(shí)間將文件排序的源碼
C#中使用快速排序按文件創(chuàng)建時(shí)間將文件排序的源碼...2007-03-03
C#實(shí)現(xiàn)Winform鼠標(biāo)拖動(dòng)窗口大小時(shí)設(shè)定窗口最小尺寸的方法
這篇文章主要介紹了C#實(shí)現(xiàn)Winform鼠標(biāo)拖動(dòng)窗口大小時(shí)設(shè)定窗口最小尺寸的方法,涉及WinForm改變窗口大小時(shí)動(dòng)態(tài)判斷當(dāng)前窗口尺寸的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-11-11
C#?WPF中RadioButton控件的用法及應(yīng)用場(chǎng)景
在WPF應(yīng)用程序中,RadioButton控件是一種常用的用戶(hù)界面元素,本文主要介紹了C#?WPF中RadioButton控件的用法及應(yīng)用場(chǎng)景,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
C#基于SerialPort類(lèi)實(shí)現(xiàn)串口通訊詳解
這篇文章主要為大家詳細(xì)介紹了C#基于SerialPort類(lèi)實(shí)現(xiàn)串口通訊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
winform開(kāi)發(fā)使用通用多線(xiàn)程基類(lèi)分享(以隊(duì)列形式)
多線(xiàn)程這個(gè)概念大家都很熟悉,對(duì)于winform的開(kāi)發(fā)人員來(lái)說(shuō),用的還是多的.但估計(jì)都是用Timer,或者backgroundWorker,為大家寫(xiě)了一個(gè)多線(xiàn)程的基類(lèi),只有你用到多線(xiàn)程拿過(guò)來(lái)就可以用了2013-12-12

