WPF毫秒级桌面时钟的实现-C#中Hook(钩子)的应用

最近由于项目中需要精确记录某些操作的发生时间,但又没有办法打日志,因此写了个小工具,用来记录当前的毫秒级本机时间。

(程序内部实现了全局钩子,监听所有的键盘事件,即KeyDown,KeyUp事件。)

工具功能如下:

1.通过任意键盘按键来记录当前时间

2.可以在列表处单击记录当前时间

C#中对于Hook API的包装如下:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Runtime.InteropServices;

using System.Text;

namespace HookLib

{

public static class HookHelper

{

public delegate int HookProc(

int nCode,

IntPtr wParam,

IntPtr lParam

);

public static int HookCallback( int nCode, IntPtr wParam, IntPtr lParam)

{

if (IntPtr .Zero == HookPtr || null == HookId)

{

return 0;

}

if (nCode >= 0)

{

if (null != HookCallbackEvent)

{

return HookCallbackEvent(nCode, wParam, lParam);

}

}

return CallNextHookEx(HookPtr, HookId.Value, wParam, lParam);

}

public static IntPtr SetWindowsHookEx()

{

if (null == HookId)

{

throw new Exception( "You must set HookId first!" );

}

HookPtr = SetWindowsHookEx(

HookId.Value,

KeyboardCallback,

Instance,

0);

return HookPtr;

}

public static bool UnhookWindowsHookEx()

{

if (null == HookPtr || IntPtr.Zero == HookPtr)

{

throw new Exception( "HookPtr is null");

}

return UnhookWindowsHookEx(HookPtr);

}

public static int WH_KEYBOARD_LL = 13;

public static IntPtr HookPtr;

public static int? HookId = WH_KEYBOARD_LL;

public static event HookProc HookCallbackEvent;

public static HookProc KeyboardCallback = new HookProc (HookHelper.HookCallback);

public static IntPtr Instance = Marshal.GetHINSTANCE(Assembly .GetAssembly(typeof( HookHelper)).GetModules()[0]);

#region Win32API

[ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,

SetLastError = true)]

public static extern IntPtr SetWindowsHookEx(

int idHook,

HookProc lpfn, //如果是全局钩子,回调函数应该就写在dll内

IntPtr hMod,   //如果是全局钩子,应该是包含lpfn方法的dll句柄,注意此句柄要保持生命周期

int dwThreadId //如果是全局钩子,置为0;否则应该是保护lpfn方法的进程id

);

[ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,

SetLastError = true)]

public static extern int CallNextHookEx(

IntPtr hhk,

int nCode,

IntPtr wParam,

IntPtr lParam

);

[ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,

SetLastError = true)]

public static extern bool UnhookWindowsHookEx(

IntPtr hhk

);

[ DllImport("Kernel32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]

public static extern int GetLastError();

#endregion

}

}


HookHelper的用法:

1.可以使用原始的win32 api,如

public static extern IntPtr SetWindowsHookEx(

int idHook,

HookProc lpfn,

IntPtr hMod,

int dwThreadId

);

2.可以使用包装好的2个方法,只要外部指定要处理的HookId(安装何种类型的钩子),以及处理钩子的回调函数HookCallbackEvent, 如

private void MainView_Loaded (object sender, System .Windows. RoutedEventArgs e )

{

//Add hook

HookHelper.HookCallbackEvent += F5Proc;

HookHelper.HookId = HookHelper. WH_KEYBOARD_LL;

HookHelper.SetWindowsHookEx ();

}


注意事项:

1.如果是全局钩子,请把钩子的回调处理函数放在dll中

2.C#好像不支持wm_keyboard这样的钩子,需要替换为wm_keyboard_ll则可以

3.如果是全局钩子,请务必把进程实例设为回调函数所在dll的实例。

4.请保证回调处理函数的生命周期,要不然被垃圾回收器回收后找不到调用函数。


Demo 下载地址:http://download.csdn.net/detail/muzizongheng/8390369

时间: 2024-10-15 22:05:13

WPF毫秒级桌面时钟的实现-C#中Hook(钩子)的应用的相关文章

在Windows及Linux下获取毫秒级运行时间的方法

在Windows下获取毫秒级运行时间的方法 头文件:<Windows.h> 函数原型: /*获取时钟频率,保存在结构LARGE_INTEGER中***/ WINBASEAPI BOOL WINAPI QueryPerformanceFrequency( _Out_ LARGE_INTEGER * lpFrequency ); /*获取从某个时间点开始的时钟周期数,保存在结构LARGE_INTEGER中**/ WINBASEAPI BOOL WINAPI QueryPerformanceFreq

如何统计毫秒级的时间差

计算毫秒级的时间差算是一个常见的需求吧... 手头上是windows编程的项目,所以首先就想到的是GetTickCount(),但MSDN上这么说: 写个程序试一下吧: 1 #include <stdio.h> 2 #include <windows.h> 3 4 int main(void) 5 { 6 DWORD dwLastTime = GetTickCount(); 7 for (int i = 0; i != 10; ++i) 8 { 9 DWORD dwCurrentT

C++计时器:毫秒级和微秒级

1.毫秒级 使用GetTickCount()获取系统启动所经过的毫秒数 #include<iostream> using namespace std; int main(){ DWORD start= ::GetTickCount(); //获取毫秒级数目 Sleep(1000); cout << ::GetTickCount() - start<< endl; system("pause"); } 2. 使用clock() #include <

c/c++中sleep()函数毫秒级的实现

近期看到好多人在问.c/c++中的sleep函数是秒级的,能不能实现毫秒级的呢?当然非常easy.我的写法例如以下 #include <stdio.h> #include <sys/select.h> static void sleep_ms(unsigned int secs) { struct timeval tval; tval.tv_sec=secs/1000; tval.tv_usec=(secs*1000)%1000000; select(0,NULL,NULL,NUL

WPF对象级资源的定义与查找

文章概述: 本演示介绍了如何定义WPF对象级的资源,并通过XAML代码和C#访问和使用对象级资源. 相关下载(代码.屏幕录像):http://pan.baidu.com/s/1hqvJNY8 在线播放:http://v.youku.com/v_show/id_XODA1NTU2Mzky.html 温馨提示:如果屏幕录像和代码不能正常下载,可站内留言,或发邮件到[email protected] 一.完整的定义和使用资源 <Window x:Class="Demo008.MainWindow

【天气APP】之桌面时钟witget组件

桌面时钟之组件开发: 整个流程例如以下: 下载地址demo:www.github.com/xufeifandj service+组件+广播进行后台实时更新时间 (一)开机广播监听开机启动service服务启动后.马上动态注冊一个广播去监听时间发生变化. IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_TIME_TICK);  //时间发生改变 intentFilter.add

毫秒级百万数据分页存储过程[欢迎转载]

数据分页一直是一个经久不衰的话题,在园子里看到了N多高手,都比我厉害, 今天把我使用的分页代码继续分享;请高手手下留情,少拍砖啦...哈哈; 欢迎大家转载!!!! 首先参考园子里的高手方法生成一个百万数据表; 耗时 33 秒; 然后创建分页存储过程;这个是基于SQL 2005 的ROW_NUMBER的, SQL 2000 不适用; SQL 2008 我没有安装,所以也没有测试过!估计应该可以运行. 2种算法可以选择 1. 使用  BETWEEN   ;  2.  TOP  ; 代码中已经注释了.

shell脚本示例:计算毫秒级、微秒级时间差

有时候需要计算命令的执行时间长度,可以使用time命令,虽然time命令可以精确到毫秒级,但time命令无法计算一堆命令的执行时间.可以也可以直接使用date命令计算命令执行前后的时间差,但直接使用date命令计算时间差只能精确到秒级.因此,要计算毫秒级或者微秒级的时间长度,需要对date命令的结果进行一番计算转换. 本文只给出了毫秒级时间差的计算方法,若要计算微秒级时间差,对脚本稍作修改即可. 脚本如下: #!/bin/bash # filename: msec_diff.sh functio

Linux Shell获得毫秒级的时间戳

在linux Shell中并没有毫秒级的时间单位,只有秒和纳秒其实这样就足够了,因为纳秒的单位范围是(000000000..999999999),所以从纳秒也是可以的到毫秒的. current=`date "+%Y-%m-%d %H:%M:%S"`     #获取当前时间,例:2015-03-11 12:33:41        timeStamp=`date -d "$current" +%s`      #将current转换为时间戳,精确到秒 currentT