看似简单代码,谁能指点一下(200分)

  • 主题发起人 主题发起人 dok001
  • 开始时间 开始时间
D

dok001

Unregistered / Unconfirmed
GUEST, unregistred user!
不少资料介绍有鼠标记录回放的例子,代码看似简单,功能强大,而且可用在后台,部分取代键盘钩子的dll.谁能指点一下:<br>&nbsp; 很多的教学软件或系统监视软件可以自动记录回放用户的输入文字或点击按钮等操作操作,这个功能的实现是使用<br>&gt;了Windows的Hook函数。<br>&gt; &nbsp;Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows消息,函数语法为:<br>&gt; &nbsp;SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD)<br>&gt; &nbsp;其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同<br>&gt;的消息监视类型,在这里我们将使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消<br>&gt;息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为:<br>&gt; &nbsp;Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;<br>&gt; &nbsp;其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样<br>&gt;一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。<br>&gt; &nbsp;在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。<br>&gt; &nbsp;WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠<br>&gt;标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于<br>&gt;将保存的操作返给系统回放。<br>&gt; &nbsp;下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一<br>&gt;个Edit控件用于验证操作。<br>&gt; &nbsp;下面是Form1的全部代码<br>&gt;unit Unit1;<br>&gt;interface<br>&gt;uses<br>&gt; &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&gt; &nbsp;StdCtrls;<br>&gt;type<br><br>&gt; &nbsp;TForm1 = class(TForm)<br>&gt; &nbsp;Button1: TButton;<br>&gt; &nbsp;Button2: TButton;<br>&gt; &nbsp;Button3: TButton;<br>&gt; &nbsp;Edit1: TEdit;<br>&gt; &nbsp;Button4: TButton;<br>&gt; &nbsp;procedure FormCreate(Sender: TObject);<br>&gt; &nbsp;procedure Button1Click(Sender: TObject);<br>&gt; &nbsp;procedure Button2Click(Sender: TObject);<br>&gt; &nbsp;procedure Button3Click(Sender: TObject);<br>&gt; &nbsp;private<br>&gt; &nbsp;{ Private declarations }<br>&gt; &nbsp;public<br>&gt; &nbsp;{ Public declarations }<br>&gt; &nbsp;end;<br>&gt;var<br><br>&gt; &nbsp;Form1: TForm1;<br>&gt; &nbsp;EventArr:array[0..1000]of EVENTMSG;<br>&gt; &nbsp;EventLog:Integer;<br>&gt; &nbsp;PlayLog:Integer;<br>&gt; &nbsp;hHook,hPlay:Integer;<br>&gt; &nbsp;recOK:Integer;<br>&gt; &nbsp;canPlay:Integer;<br>&gt; &nbsp;bDelay:Bool;<br>&gt;implementation<br>&gt;{$R *.DFM}<br>&gt;Function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;<br>&gt;begin<br>&gt; &nbsp;canPlay:=1;<br>&gt; &nbsp;Result:=0;<br>&gt; &nbsp;if iCode &lt; 0 then //必须将消息传递到消息链的下一个接受单元<br>&gt; &nbsp;Result := CallNextHookEx(hPlay,iCode,wParam,lParam)<br>&gt; &nbsp;else if iCode = HC_SYSMODALON then<br>&gt; &nbsp;canPlay:=0<br>&gt; &nbsp;else if iCode = HC_SYSMODALOFF then<br>&gt; &nbsp;canPlay:=1<br>&gt; &nbsp;else if ((canPlay =1 )and(iCode=HC_GETNEXT)) then begin<br>&gt; &nbsp;if bDelay then begin<br>&gt; &nbsp;bDelay:=False;<br>&gt; &nbsp;Result:=50;<br>&gt; &nbsp;end;<br>&gt; &nbsp;pEventMSG(lParam)^:=EventArr[PlayLog];<br>&gt; &nbsp;end<br>&gt; &nbsp;else if ((canPlay = 1)and(iCode = HC_SKIP))then begin<br>&gt; &nbsp;bDelay := True;<br>&gt; &nbsp;PlayLog:=PlayLog+1;<br>&gt; &nbsp;end;<br>&gt; &nbsp;if PlayLog&gt;=EventLog then begin<br>&gt; &nbsp;UNHookWindowsHookEx(hPlay);<br>&gt; &nbsp;end;<br>&gt;end;<br>&gt;function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;<br>&gt;begin<br>&gt; &nbsp;recOK:=1;<br>&gt; &nbsp;Result:=0;<br>&gt; &nbsp;if iCode &lt; 0 then<br>&gt; &nbsp;Result := CallNextHookEx(hHook,iCode,wParam,lParam)<br>&gt; &nbsp;else if iCode = HC_SYSMODALON then<br>&gt; &nbsp;recOK:=0<br>&gt; &nbsp;else if iCode = HC_SYSMODALOFF then<br>&gt; &nbsp;recOK:=1<br>&gt; &nbsp;else if ((recOK&gt;0) and (iCode = HC_ACTION)) then begin<br>&gt; &nbsp;EventArr[EventLog]:=pEventMSG(lParam)^;<br>&gt; &nbsp;EventLog:=EventLog+1;<br>&gt; &nbsp;if EventLog&gt;=1000 then begin<br>&gt; &nbsp;UnHookWindowsHookEx(hHook);<br>&gt; &nbsp;end;<br>&gt; &nbsp;end;<br>&gt;end;<br>&gt;procedure TForm1.FormCreate(Sender: TObject);<br>&gt;begin<br>&gt; &nbsp;Button1.Caption:='纪录';<br>&gt; &nbsp;Button2.Caption:='停止';<br>&gt; &nbsp;Button3.Caption:='回放';<br>&gt; &nbsp;Button4.Caption:='范例';<br>&gt; &nbsp;Button2.Enabled:=False;<br>&gt; &nbsp;Button3.Enabled:=False;<br>&gt;end;<br>&gt;procedure TForm1.Button1Click(Sender: TObject);<br>&gt;begin<br>&gt; &nbsp;EventLog:=0;<br>&gt; &nbsp;//建立键盘鼠标操作消息纪录链<br>&gt; &nbsp;hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0);<br>&gt; &nbsp;Button2.Enabled:=True;<br>&gt; &nbsp;Button1.Enabled:=False;<br>&gt;end;<br>&gt;procedure TForm1.Button2Click(Sender: TObject);<br>&gt;begin<br>&nbsp; UnHookWindowsHookEx(hHook);<br>&gt; &nbsp;hHook:=0;<br>&gt; &nbsp;Button1.Enabled:=True;<br>&gt; &nbsp;Button2.Enabled:=False;<br>&gt; &nbsp;Button3.Enabled:=True;<br>&gt;end;<br>&gt;procedure TForm1.Button3Click(Sender: TObject);<br>&gt;begin<br>&gt; &nbsp;PlayLog:=0;<br>&gt; &nbsp;//建立键盘鼠标操作消息纪录回放链<br>&gt; &nbsp;hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,<br>&gt; &nbsp;HInstance,0);<br>&gt; &nbsp;Button3.Enabled:=False;<br>&gt;end;<br>&gt;end.<br>&gt; &nbsp;代码添加完毕后,运行程序,点击“纪录”按钮开始纪录操作,这时你可以在文本控件中输入一些文字或者点击<br>&gt;“范例”按钮,然后点击“停止”按钮停止纪录,再点击“回放”按钮就可以讲先前所做的操作回放。<br>&gt; &nbsp;在上面的程序中,HookProc是纪录操作的消息函数,每当有鼠标键盘消息发生时,系统都会调用该函数,消息信<br>&gt;息就保存在地址lParam中,我们可以讲消息保存在一个数组中。PlayProc是消息回放函数,当系统可以执行消息回放<br>&gt;时调用该函数,程序就将先前纪录的消息值返回到lParam指向的区域中,系统就会执行该消息,从而实现了消息回放。<br><br><br><br>如果我现在只想知道键盘动了没有.例子中"程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中"...现在能不能将保存在数组中的值利用一下,判别键盘动了没有.如将每一个取值和上一次取值比较,相同(键盘静滞)则返回一个变量值0,不同(有操作)返回1,不是也能达到键盘钩子dll的效果,不过怎么改,我的水平太差,老是出错,请指点!!<br>
 
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process. <br>你的HOOK的回调函数必需放在你自己编写的动态库里<br>hMod<br>[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process. <br><br>hMod为DLL的句柄
 
好象问题接近解决,不过我的英文较差.<br>问一句,不编dll行不行!人家原代码就是不用编dll直接实现的!
 
按照英文的原意,不编写DLL可以,但是只能HOOK住本进程的线程(最后一个参数不能为0,必需为从属本进程的线程ID),并且倒数第二个参数也必需设置为0
 
你这个只是初级的!!!
 
楼主你的问题恐怕无法实现,<br>这个钩子不监视键盘消息~~~<br>呵呵~~~~~~~~~~~~~~
 
不编Dll可以的,这个钩子比较特殊。判断键盘是否动作也是可以做到的,<br>你是不是处理EVENTMSG做得不对?
 
我写了一个小例子,希望对你有帮助。<br>#include "windows.h"<br>//---------------------------------------------------------------------------<br>// 函数声明<br>//---------------------------------------------------------------------------<br>BOOL CALLBACK LibMain(HANDLE, DWORD, LPVOID);<br>//此函数也可以不要,仅用于获得调用窗口句柄和自定义消息<br>extern "C" __declspec(dllexport) int __stdcall InitHooksDll(HWND, UINT);<br>//安装、卸载<br>extern "C" __declspec(dllexport) int InstallHooks(int, BOOL);<br>LRESULT CALLBACK JournalRecordProc &nbsp;(int, WPARAM, LPARAM);<br>LRESULT CALLBACK JournalPlaybackProc(int, WPARAM, LPARAM);<br><br>//---------------------------------------------------------------------------<br>// 全局量<br>//--------------------------------------------------------------------------- <br>HINSTANCE hInstance &nbsp; &nbsp; &nbsp; &nbsp;= 0;<br>HHOOK &nbsp; &nbsp; hJournalRecord &nbsp; = 0;<br>HHOOK &nbsp; &nbsp; hJournalPlayback = 0;<br><br>//记录开始时间<br>DWORD &nbsp; &nbsp; dwRecordBeginTime;<br><br>//数据保存在内存中<br>typedef struct tag_EventNode{<br>&nbsp; EVENTMSG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Event;<br>&nbsp; struct tag_EventNode *lpNextEvent;<br>}EventNode;<br><br>EventNode *lpEventHead &nbsp; &nbsp;= 0;<br>EventNode *lpEventTail &nbsp; &nbsp;= 0;<br>EventNode *lpCurrentEvent = 0;<br><br>// 共享数据<br>#pragma data_seg("SHARDATA")<br>&nbsp; static HWND hWndApplication = 0;<br>&nbsp; static UINT iCustomMsg;<br>#pragma data_seg()<br><br>//---------------------------------------------------------------------------<br>// 库入口<br>//---------------------------------------------------------------------------<br><br>BOOL CALLBACK DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)<br>{<br>&nbsp; hInstance = hModule;<br>&nbsp; return 1;<br>}<br>int __stdcall InitHooksDll(HWND hWnd, UINT iMsg)<br>{<br>&nbsp; hWndApplication = hWnd;<br>&nbsp; iCustomMsg &nbsp; &nbsp; &nbsp;= iMsg;<br>&nbsp; return 1;<br>}<br><br>int InstallHooks(int iHookIndex, BOOL fInstall)<br>{<br>&nbsp; BOOL fRes;<br>&nbsp; <br>&nbsp; if (fInstall)<br>&nbsp; {<br>&nbsp; &nbsp; switch (iHookIndex)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; case WH_JOURNALRECORD: &nbsp; //0<br>&nbsp; &nbsp; &nbsp; if (!hJournalRecord)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; hJournalRecord = SetWindowsHookEx(iHookIndex, JournalRecordProc, hInstance, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; return hJournalRecord != 0;<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; case WH_JOURNALPLAYBACK: //1<br>&nbsp; &nbsp; &nbsp; if (!hJournalPlayback)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; hJournalPlayback = SetWindowsHookEx(iHookIndex, JournalPlaybackProc, hInstance, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; return hJournalPlayback != 0;<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>&nbsp; }<br>&nbsp; else<br>&nbsp; {<br>&nbsp; &nbsp; switch (iHookIndex)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; case WH_JOURNALRECORD:<br>&nbsp; &nbsp; &nbsp; fRes = &nbsp;UnhookWindowsHookEx(hJournalRecord);<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, 0, (LPARAM)"");<br>&nbsp; &nbsp; &nbsp; hJournalRecord = 0;<br>&nbsp; &nbsp; &nbsp; return fRes;<br>&nbsp; &nbsp; case WH_JOURNALPLAYBACK:<br>&nbsp; &nbsp; &nbsp; fRes = &nbsp;UnhookWindowsHookEx(hJournalPlayback);<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"", 0);<br>&nbsp; &nbsp; &nbsp; hJournalPlayback = 0;<br>&nbsp; &nbsp; &nbsp; return fRes;<br>&nbsp; &nbsp; }<br>&nbsp; }<br>&nbsp; return 0;<br>}<br><br>LRESULT CALLBACK JournalRecordProc(int iCode, WPARAM wParam, LPARAM lParam)<br>{<br>&nbsp; EventNode &nbsp;*lpEventNode;<br>&nbsp; LPEVENTMSG lpEvent;<br><br>&nbsp; if (iCode &gt;= 0)<br>&nbsp; {<br>&nbsp; &nbsp; lpEvent = (LPEVENTMSG)lParam;<br>&nbsp; &nbsp; if (hJournalPlayback)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, 0, (LPARAM)"失败:正在重演中");<br>&nbsp; &nbsp; &nbsp; return 0;<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; if ((lpEventNode = (EventNode *)malloc(sizeof(EventNode))) == 0)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; //内存溢出,卸载记录Hook<br>&nbsp; &nbsp; &nbsp; InstallHooks(WH_JOURNALRECORD, 0);<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, 0, (LPARAM)"失败:内存溢出");<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; if (lpEventTail == 0)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; dwRecordBeginTime = (DWORD)GetTickCount();<br>&nbsp; &nbsp; &nbsp; lpEventHead = lpEventNode;<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, 0, (LPARAM)"成功:记录开始");<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; lpEventTail-&gt;lpNextEvent = lpEventNode;<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, 0, (LPARAM)"成功:记录中......");<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; lpEventTail = lpEventNode;<br>&nbsp; &nbsp; lpEventTail-&gt;lpNextEvent = 0;<br><br>&nbsp; &nbsp; lpEventTail-&gt;Event.message = lpEvent-&gt;message;<br>&nbsp; &nbsp; lpEventTail-&gt;Event.paramL &nbsp;= lpEvent-&gt;paramL;<br>&nbsp; &nbsp; lpEventTail-&gt;Event.paramH &nbsp;= lpEvent-&gt;paramH;<br>&nbsp; &nbsp; lpEventTail-&gt;Event.time &nbsp; &nbsp;= lpEvent-&gt;time;<br>&nbsp; &nbsp; lpEventTail-&gt;Event.hwnd &nbsp; &nbsp;= lpEvent-&gt;hwnd;<br>&nbsp; }//if (iCode &gt; 0)<br>&nbsp; return CallNextHookEx(hJournalRecord, iCode, wParam, lParam);<br>}<br><br>LRESULT CALLBACK JournalPlaybackProc(int iCode, WPARAM wParam, LPARAM lParam)<br>{<br>&nbsp; static DWORD dwEventTimeInterval;<br>&nbsp; static long &nbsp;lRes;<br>&nbsp; LPEVENTMSG &nbsp; lpEvent;<br>&nbsp; <br>&nbsp; if (iCode &gt;= 0)<br>&nbsp; {<br>&nbsp; &nbsp; if (lpEventHead == 0 || hJournalRecord)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; //无记录<br>&nbsp; &nbsp; &nbsp; InstallHooks(WH_JOURNALPLAYBACK, 0);<br>&nbsp; &nbsp; &nbsp; if (lpEventHead == 0)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"失败:无记录数据", 0);<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; if (hJournalRecord)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"失败:正在记录中", 0);<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; return CallNextHookEx(hJournalPlayback, iCode, wParam, lParam);<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; if (lpCurrentEvent == 0)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; lpCurrentEvent = lpEventHead;<br>&nbsp; &nbsp; &nbsp; lpEventTail = 0;<br>&nbsp; &nbsp; &nbsp; dwEventTimeInterval = GetTickCount() - dwRecordBeginTime;<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"成功:重演开始", 0);<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; if (iCode == HC_SKIP)//准备下个事件<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; if (lpCurrentEvent-&gt;lpNextEvent == 0)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; free(lpEventHead);<br>&nbsp; &nbsp; &nbsp; &nbsp; lpEventHead = lpCurrentEvent = 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; InstallHooks(WH_JOURNALPLAYBACK, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"成功:重演结束", 0);<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; lpCurrentEvent = lpCurrentEvent-&gt;lpNextEvent;<br>&nbsp; &nbsp; &nbsp; &nbsp; free(lpEventHead);<br>&nbsp; &nbsp; &nbsp; &nbsp; lpEventHead = lpCurrentEvent;<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"成功:准备好数据", 0);<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; }//if (iCode == HC_SKIP)<br>&nbsp; &nbsp; else if (iCode == HC_GETNEXT)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; lpEvent = (LPEVENTMSG)lParam;<br>&nbsp; &nbsp; &nbsp; lpEvent-&gt;message = lpCurrentEvent-&gt;Event.message;<br>&nbsp; &nbsp; &nbsp; lpEvent-&gt;paramL &nbsp;= lpCurrentEvent-&gt;Event.paramL;<br>&nbsp; &nbsp; &nbsp; lpEvent-&gt;paramH &nbsp;= lpCurrentEvent-&gt;Event.paramH;<br>&nbsp; &nbsp; &nbsp; lpEvent-&gt;time &nbsp; &nbsp;= lpCurrentEvent-&gt;Event.time + dwEventTimeInterval;<br>&nbsp; &nbsp; &nbsp; lpEvent-&gt;hwnd &nbsp; &nbsp;= lpCurrentEvent-&gt;Event.hwnd;<br><br>&nbsp; &nbsp; &nbsp; lRes = lpEvent-&gt;time - GetTickCount();<br>&nbsp; &nbsp; &nbsp; if (lRes &lt; 0L)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; lRes = 0L;<br>&nbsp; &nbsp; &nbsp; &nbsp; lpEvent-&gt;time = GetTickCount();<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; SendMessage(hWndApplication, iCustomMsg, (WPARAM)"成功:重演中......", 0);<br>&nbsp; &nbsp; &nbsp; return (DWORD)lRes;<br>&nbsp; &nbsp; }<br>&nbsp; }//if (iCode &gt; 0)<br>&nbsp; return CallNextHookEx(hJournalPlayback, iCode, wParam, lParam);<br>}<br><br>
 
只有按键可以不用dll,其他不行,回放的代码我也有,一起研究?
 
后退
顶部