C#如何獲取鍵盤(pán)和鼠標(biāo)處于空閑狀態(tài)下的時(shí)間? 可以通過(guò)windows api 函數(shù) GetLastInputInfo或者全局鉤子HOOK來(lái)實(shí)現(xiàn)
用 GetLastInputInfo 寫(xiě)(鍵鼠空閑15分鐘自動(dòng)彈出一個(gè)頁(yè)面)
新建windows 應(yīng)用程序項(xiàng)目
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace APPDEMO
{
static class Program
{
private static VedioForm vf = null;
private static System.Windows.Forms.Timer timer1 = null;
/// <summary>
/// 應(yīng)用程序的主入口點(diǎn)。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//啟用定時(shí)器
if (timer1 == null)
{
timer1 = new Timer();
}
timer1.Interval = 60 * 1000;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
Application.Run(new MainForm());
}
private static void timer1_Tick(object sender, EventArgs e)
{
//判斷空閑時(shí)間是否超過(guò)15分鐘,超過(guò)則自動(dòng)彈出視頻播放窗口
if (GetIdleTick() / 1000 >= 15 * 60)
{
ShowVidioForm();
}
}
/// <summary>
/// 打開(kāi)視頻播放窗口
/// </summary>
private static void ShowVidioForm()
{
try
{
if (vf == null)
{
vf = new VedioForm();
}
vf.ShowDialog();
}
catch
{
}
}
/// <summary>
/// 獲取鼠標(biāo)鍵盤(pán)空閑時(shí)間
/// </summary>
/// <returns></returns>
public static long GetIdleTick()
{
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
if (!GetLastInputInfo(ref lastInputInfo)) return 0;
return Environment.TickCount - (long)lastInputInfo.dwTime;
}
[StructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public uint dwTime;
}
/// <summary>
/// 調(diào)用windows API獲取鼠標(biāo)鍵盤(pán)空閑時(shí)間
/// </summary>
/// <param name="plii"></param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
}
}
用HOOK鉤子來(lái)實(shí)現(xiàn) 創(chuàng)建鉤子類文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-506940.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TengDa.Core
{
class KeyboardHook
{
public event KeyEventHandler KeyDownEvent;
public event KeyPressEventHandler KeyPressEvent;
public event KeyEventHandler KeyUpEvent;
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0; //聲明鍵盤(pán)鉤子處理的初始值
//值在Microsoft SDK的Winuser.h里查詢
public const int WH_KEYBOARD_LL = 13; //線程鍵盤(pán)鉤子監(jiān)聽(tīng)鼠標(biāo)消息設(shè)為2,全局鍵盤(pán)監(jiān)聽(tīng)鼠標(biāo)消息設(shè)為13
HookProc KeyboardHookProcedure; //聲明KeyboardHookProcedure作為HookProc類型
//鍵盤(pán)結(jié)構(gòu)
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; //定一個(gè)虛擬鍵碼。該代碼必須有一個(gè)價(jià)值的范圍1至254
public int scanCode; // 指定的硬件掃描碼的關(guān)鍵
public int flags; // 鍵標(biāo)志
public int time; // 指定的時(shí)間戳記的這個(gè)訊息
public int dwExtraInfo; // 指定額外信息相關(guān)的信息
}
//使用此功能,安裝了一個(gè)鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//調(diào)用此函數(shù)卸載鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//使用此功能,通過(guò)信息鉤子繼續(xù)下一個(gè)鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
// 取得當(dāng)前線程編號(hào)(線程鉤子需要用到)
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
//使用WINDOWS API函數(shù)代替獲取當(dāng)前實(shí)例的函數(shù),防止鉤子失效
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
public void Start()
{
// 安裝鍵盤(pán)鉤子
if (hKeyboardHook == 0)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
//************************************
//鍵盤(pán)線程鉤子
SetWindowsHookEx(13, KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());//指定要監(jiān)聽(tīng)的線程idGetCurrentThreadId(),
//鍵盤(pán)全局鉤子,需要引用空間(using System.Reflection;)
//SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
//
//關(guān)于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函數(shù)將鉤子加入到鉤子鏈表中,說(shuō)明一下四個(gè)參數(shù):
//idHook 鉤子類型,即確定鉤子監(jiān)聽(tīng)何種消息,上面的代碼中設(shè)為2,即監(jiān)聽(tīng)鍵盤(pán)消息并且是線程鉤子,如果是全局鉤子監(jiān)聽(tīng)鍵盤(pán)消息應(yīng)設(shè)為13,
//線程鉤子監(jiān)聽(tīng)鼠標(biāo)消息設(shè)為7,全局鉤子監(jiān)聽(tīng)鼠標(biāo)消息設(shè)為14。lpfn 鉤子子程的地址指針。如果dwThreadId參數(shù)為0 或是一個(gè)由別的進(jìn)程創(chuàng)建的
//線程的標(biāo)識(shí),lpfn必須指向DLL中的鉤子子程。 除此以外,lpfn可以指向當(dāng)前進(jìn)程的一段鉤子子程代碼。鉤子函數(shù)的入口地址,當(dāng)鉤子鉤到任何
//消息后便調(diào)用這個(gè)函數(shù)。hInstance應(yīng)用程序?qū)嵗木浔?。?biāo)識(shí)包含lpfn所指的子程的DLL。如果threadId 標(biāo)識(shí)當(dāng)前進(jìn)程創(chuàng)建的一個(gè)線程,而且子
//程代碼位于當(dāng)前進(jìn)程,hInstance必須為NULL??梢院芎?jiǎn)單的設(shè)定其為本應(yīng)用程序的實(shí)例句柄。threaded 與安裝的鉤子子程相關(guān)聯(lián)的線程的標(biāo)識(shí)符
//如果為0,鉤子子程與所有的線程關(guān)聯(lián),即為全局鉤子
//************************************
//如果SetWindowsHookEx失敗
if (hKeyboardHook == 0)
{
Stop();
throw new Exception("安裝鍵盤(pán)鉤子失敗");
}
}
}
public void Stop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!(retKeyboard)) throw new Exception("卸載鉤子失?。?);
}
//ToAscii職能的轉(zhuǎn)換指定的虛擬鍵碼和鍵盤(pán)狀態(tài)的相應(yīng)字符或字符
[DllImport("user32")]
public static extern int ToAscii(int uVirtKey, //[in] 指定虛擬關(guān)鍵代碼進(jìn)行翻譯。
int uScanCode, // [in] 指定的硬件掃描碼的關(guān)鍵須翻譯成英文。高階位的這個(gè)值設(shè)定的關(guān)鍵,如果是(不壓)
byte[] lpbKeyState, // [in] 指針,以256字節(jié)數(shù)組,包含當(dāng)前鍵盤(pán)的狀態(tài)。每個(gè)元素(字節(jié))的數(shù)組包含狀態(tài)的一個(gè)關(guān)鍵。如果高階位的字節(jié)是一套,關(guān)鍵是下跌(按下)。在低比特,如果設(shè)置表明,關(guān)鍵是對(duì)切換。在此功能,只有肘位的CAPS LOCK鍵是相關(guān)的。在切換狀態(tài)的NUM個(gè)鎖和滾動(dòng)鎖定鍵被忽略。
byte[] lpwTransKey, // [out] 指針的緩沖區(qū)收到翻譯字符或字符。
int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.
//獲取按鍵的狀態(tài)
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
private const int WM_KEYDOWN = 0x100;//KEYDOWN
private const int WM_KEYUP = 0x101;//KEYUP
private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
private const int WM_SYSKEYUP = 0x105;//SYSKEYUP
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// 偵聽(tīng)鍵盤(pán)事件
if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// raise KeyDown
if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyDownEvent(this, e);
}
//鍵盤(pán)按下
if (KeyPressEvent != null && wParam == WM_KEYDOWN)
{
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
KeyPressEvent(this, e);
}
}
// 鍵盤(pán)抬起
if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUpEvent(this, e);
}
}
//如果返回1,則結(jié)束消息,這個(gè)消息到此為止,不再傳遞。
//如果返回0或調(diào)用CallNextHookEx函數(shù)則消息出了這個(gè)鉤子繼續(xù)往下傳遞,也就是傳給消息真正的接受者
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
~KeyboardHook()
{
Stop();
}
}
}
調(diào)用 方法文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-506940.html
private void hook_KeyDown(object sender, KeyEventArgs e)
{
// 這里寫(xiě)具體實(shí)現(xiàn)
if (e.KeyCode.Equals(Keys.PrintScreen))
{
}
}
/// <summary>
/// 開(kāi)始監(jiān)聽(tīng)
/// </summary>
public void startListen()
{
myKeyEventHandeler = new KeyEventHandler(hook_KeyDown);
k_hook.KeyDownEvent += myKeyEventHandeler;//鉤住鍵按下
k_hook.Start();//安裝鍵盤(pán)鉤子
}
/// <summary>
/// 結(jié)束監(jiān)聽(tīng)
/// </summary>
public void stopListen()
{
if (myKeyEventHandeler != null)
{
k_hook.KeyDownEvent -= myKeyEventHandeler;//取消按鍵事件
myKeyEventHandeler = null;
k_hook.Stop();//關(guān)閉鍵盤(pán)鉤子
}
}
到了這里,關(guān)于C#全局監(jiān)聽(tīng)鍵盤(pán)事件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!