发信人: tengel() 
整理人: wenbobo(2002-12-06 23:07:00), 站内信件
 | 
 
 
系统钩子的应用
 ----我的拙见,请网友多指教
 
 对于Win32程序来说,应用程序各自拥有虚拟的4G地址空间,增强
 了应用程序之间的独立性.但是也给编程者带来了问题,如:如何
 是我的一段代码到另外一个应用程序的地址空间去执行,使用
 Win32系统钩子是一个比较简单的方法.
 钩子的安装,卸载,是通过使用:
 SetWindowsHookEx和UnhookWindowsHookEx两个函数来实现的,
 具体的参数如下:
 The SetWindowsHookEx function installs an application-defined hook pro cedure into a hook chain. You would install a hook procedure to monito r the system for certain types of events. These events are associated  either with a specific thread or with all threads in the system. 
 
 HHOOK SetWindowsHookEx(
   int idHook,        // type of hook to install
   HOOKPROC lpfn,     // address of hook procedure
   HINSTANCE hMod,    // handle to application instance
   DWORD dwThreadId   // identity of thread to install hook for
 );
 
 The UnhookWindowsHookEx function removes a hook procedure installed in  a hook chain by the SetWindowsHookEx function. 
 
 BOOL UnhookWindowsHookEx(
   HHOOK hhk   // handle to hook procedure to remove
 );
 
 以上内容摘自MSDN
 
 钩子分为局部钩子和系统钩子两种,对于局部钩子,只对特定线程起作用,
 而系统钩子,则对系统内任何进程和线程起作用.
 一旦安装了系统钩子,钩子函数就能够进入到安装函数所指定的线程内运行
 访问该线程所在进程内存空间.这实际上也就在一定程度上实现了进程的跨
 边界访问.对于系统线程,必须在DLL中.
 
 一个应用的例子:
 当我第一次使用PCanywhere时,我很惊讶于,他竟能够把光标指针的形状传
 递到另外一台计算机上去,我们采用GDI方法截取屏幕一般并不能够把光标
 指针的图形也截取下来,那么怎么才能得到光标指针的图形呢?
 一般在一个应用程序中,我们可以通过以下方法取得光标位图:
 	hCur=GetCursor();
 	DrawIcon到一个内存设备环境里面
 
 但是并不能够得到另外进程的光标位图,因为光标对象是GDI对象,在其他
 进程中不可见.如果使用系统钩子呢?当然可以.
 我们为了试验,先安装一个WH_GETMESSAGE系统钩:
 	hHook=SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,HINSTANCE(hmod),NULL) ;
 
 在GetMsgProc中,你需要的的时候作如下处理:
 			HCURSOR hCur=GetCursor();
 			HBITMAP hBmp;
 			HWND hDeskWnd=GetDesktopWindow();
 			HDC hDC=::GetDC(hDeskWnd);
 			HDC hmemDC=::CreateCompatibleDC(hDC);
 			hBmp=::CreateCompatibleBitmap(hDC,32,32);
 			::SelectObject(hmemDC,hBmp);
 			::DrawIconEx(hmemDC,0,0,hCur,32,32,0,NULL,DI_DEFAULTSIZE|DI_IMAGE); 
 			::GetDIBits(hmemDC,hBmp,0,32,pdwBitmap,(LPBITMAPINFO)&bmpih,DIB_RGB _COLORS);
 			::DeleteObject(hBmp);
 			::DeleteDC(hmemDC);
 			::ReleaseDC(hDeskWnd,hDC);
 
 那么在pdwBitmap数组中存放的就是光标的位图数组,为了让其他应用程序能
 够访问到该数组,只需要把他定义到DLL的共享数据段或者采用内存映像文件
 之类.
  --                                            _
    O           @___       G               : \  
   /|__       /|/         /\|\             :  \
  /|/_       / /\         \ X_             :   \
   /  |     __/  \          | \      0     :    \
  /    0        0|          /              :     \
  ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.33.10]
  | 
 
 
 |