SWT Extension:在Win32平台下运用Java使用注册表和系统钩子

SWT Extension:在Win32平台下运用Java使用注册表和系统钩子
上个星期在Sourceforge的Feeling项目下新增加了一个org.eclipse.swt.extension子项目,意在增强SWT的本机功能。我一向是SWT的Fans,不过却很抵触大型的RCP项目,喜欢only dependent SWT。经过一个星期的努力,现在已经整合了在Win32平台下获取系统、磁盘、内存、CPU相关信息,注册表,以及系统钩子等功能,喜欢SWT的朋友可以试用。目前还没有放出一个版本,请通过sf的CVS下载代码:

cvs -d:pserver:[email protected]:/cvsroot/feeling login

由于一直使用的都是Java,对Win32编程并不是非常熟悉。但局限于Java的功能,对我们有相当大的限制,IBM就屡屡向突破这个限制,因此产生了SWT。这里我重点想说的是怎么使用Win32的系统钩子。SWT里已经包含了大量的Win32函数,不过那都是局限于Eclipse的需要,如果Eclipse不需要,SWT是不予以优先考虑的。通过SWT我们很容易使用线程钩子监控自己程序的键盘鼠标事件,而且封装的很好。但是想使用系统钩子确是一件不可能的事情,先看看钩子的函数原型:

 HHOOK SetWindowsHookEx(  int   idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId); 


idHook --
系统钩子类型,实际上是一个int值,具体的定义请看MSDN
lpfn -- 钩子回调函数指针,当收到钩子消息时就执行这个回调函数,回调函数有3个参数,不同类型的钩子这3个参数有不同的含义,具体请看MSDN。
hMod -- DLL实例句柄(我猜是这样,我不熟悉Win32API编程),当钩子为系统钩子时这个参数是必须的,如果是单个程序或者线程使用的钩子那么可以不用这个值。
dwThreadId -- 线程ID,如果是单个程序或者线程使用的钩子这个参数是必须的。

在SWT生成的DLL中,并没有系统钩子必须用到的hMod,并不像一般的DLL有DllMain入口可以接受到DLL实例句柄。因此我们只要在JNI下的C代码里添加这个DLL实例句柄就可以完成系统钩子的功能了:

#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来实现系统钩子有多大难度呢?各位看看代码就知道了:

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;
}

很简单吧^_^

你可能感兴趣的:(SWT Extension:在Win32平台下运用Java使用注册表和系统钩子)