Feeling

    三人行,必有我师焉

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

cvs -d:pserver:anonymous@feeling.cvs.sourceforge.net:/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;
}

很简单吧^_^
posted on 2006-11-27 11:59 三人行,必有我师焉 阅读(3353) 评论(4)  编辑  收藏

评论

# re: SWT Extension:在Win32平台下运用Java使用注册表和系统钩子 2006-11-28 10:18 心内求法
顶了!
另外想请教一下,文中的代码是怎么发布的呢?  回复  更多评论
  

# re: SWT Extension:在Win32平台下运用Java使用注册表和系统钩子 2006-11-28 18:53 三人行,必有我师焉
编辑器里有一个按钮是编辑代码的,点进去copy你的代码就好了  回复  更多评论
  

# re: SWT Extension:在Win32平台下运用Java使用注册表和系统钩子 2006-11-29 11:20 心内求法
哦,好的,非常感谢  回复  更多评论
  

# re: SWT Extension:在Win32平台下运用Java使用注册表和系统钩子 2007-08-24 09:03 WTE
hook = Extension.SetSystemHook(13, proc);
为什么不用swt的setWindowsHookEX()?是不是用这个函数须要有dll才能实现全局钩子的功能?  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: