上個(gè)星期在Sourceforge的Feeling項(xiàng)目下新增加了一個(gè)org.eclipse.swt.extension子項(xiàng)目,意在增強(qiáng)SWT的本機(jī)功能。我一向是SWT的Fans,不過卻很抵觸大型的RCP項(xiàng)目,喜歡only dependent SWT。經(jīng)過一個(gè)星期的努力,現(xiàn)在已經(jīng)整合了在Win32平臺(tái)下獲取系統(tǒng)、磁盤、內(nèi)存、CPU相關(guān)信息,注冊(cè)表,以及系統(tǒng)鉤子等功能,喜歡SWT的朋友可以試用。目前還沒有放出一個(gè)版本,請(qǐng)通過sf的CVS下載代碼:
cvs -d:pserver:anonymous@feeling.cvs.sourceforge.net:/cvsroot/feeling login
由于一直使用的都是Java,對(duì)Win32編程并不是非常熟悉。但局限于Java的功能,對(duì)我們有相當(dāng)大的限制,IBM就屢屢向突破這個(gè)限制,因此產(chǎn)生了SWT。這里我重點(diǎn)想說的是怎么使用Win32的系統(tǒng)鉤子。SWT里已經(jīng)包含了大量的Win32函數(shù),不過那都是局限于Eclipse的需要,如果Eclipse不需要,SWT是不予以優(yōu)先考慮的。通過SWT我們很容易使用線程鉤子監(jiān)控自己程序的鍵盤鼠標(biāo)事件,而且封裝的很好。但是想使用系統(tǒng)鉤子確是一件不可能的事情,先看看鉤子的函數(shù)原型:
?HHOOK?SetWindowsHookEx(?int??idHook,?HOOKPROC?lpfn,?HINSTANCE?hMod,?DWORD?dwThreadId);?
idHook -- 系統(tǒng)鉤子類型,實(shí)際上是一個(gè)int值,具體的定義請(qǐng)看MSDN
lpfn -- 鉤子回調(diào)函數(shù)指針,當(dāng)收到鉤子消息時(shí)就執(zhí)行這個(gè)回調(diào)函數(shù),回調(diào)函數(shù)有3個(gè)參數(shù),不同類型的鉤子這3個(gè)參數(shù)有不同的含義,具體請(qǐng)看MSDN。
hMod -- DLL實(shí)例句柄(我猜是這樣,我不熟悉Win32API編程),當(dāng)鉤子為系統(tǒng)鉤子時(shí)這個(gè)參數(shù)是必須的,如果是單個(gè)程序或者線程使用的鉤子那么可以不用這個(gè)值。
dwThreadId -- 線程ID,如果是單個(gè)程序或者線程使用的鉤子這個(gè)參數(shù)是必須的。
在SWT生成的DLL中,并沒有系統(tǒng)鉤子必須用到的hMod,并不像一般的DLL有DllMain入口可以接受到DLL實(shí)例句柄。因此我們只要在JNI下的C代碼里添加這個(gè)DLL實(shí)例句柄就可以完成系統(tǒng)鉤子的功能了:
#define?Dll_Export?__declspec(dllexport)

HINSTANCE?instance?=?NULL;

BOOL?APIENTRY?DllMain(HINSTANCE?hInstance,?DWORD??ul_reason_for_call,?LPVOID?lpReserved)


{
????instance?=?hInstance;
????return?TRUE;
}

Dll_Export?HHOOK?SetHook(int?hookType,HOOKPROC?hookproc)


{
????return?SetWindowsHookEx(hookType,?hookproc,?instance,?NULL);
}

Dll_Export?BOOL?UnHook(HHOOK?hook)


{
????if(hook?!=?NULL)
????????return?UnhookWindowsHookEx(hook);
????else
????????return?0;
}

#ifndef?NO_SetSystemHook
JNIEXPORT?jint?JNICALL?Swt_extension_NATIVE(SetSystemHook)
????(JNIEnv?*env,?jclass?that,?jint?arg0,?jint?arg1)


{
????jint?rc?=?0;
????rc?=?(jint)SetHook(arg0,?(HOOKPROC)arg1);
????return?rc;
}
#endif

#ifndef?NO_UnSystemHook
JNIEXPORT?jboolean?JNICALL?Swt_extension_NATIVE(UnSystemHook)
????(JNIEnv?*env,?jclass?that,?jint?arg0)


{
????jboolean?rc?=?0;
????rc?=?(jboolean)UnHook((HHOOK)arg0);
????return?rc;
}
#endif那么通過SWT來實(shí)現(xiàn)系統(tǒng)鉤子有多大難度呢?各位看看代碼就知道了:
Callback?callback?=?new?Callback?(this,?"keyHook",?3);?//$NON-NLS-1$
int?proc?=?callback.getAddress?();
hook?=?Extension.SetSystemHook(13,?proc);

………………………………

int?keyHook(int?nCode,int?wParam,int?lParam)


{
????int?Result=OS.CallNextHookEx(hook,nCode,wParam,lParam);
????………………
????return?Result;
}
很簡(jiǎn)單吧^_^