请教一个“屏幕取词”的代码,哪个朋友有,提供一下,要具体能够实现的,谢谢了(50分)

  • 主题发起人 主题发起人 980
  • 开始时间 开始时间
9

980

Unregistered / Unconfirmed
GUEST, unregistred user!
我在www.tomore.com里面找了几个,但是实现的不怎么样,一句话读取的根本就不完整。哪个朋友有这个,谢谢了,可以发邮件过来也可以的。<br>liu980_980@163.com
 
没做过呢
 
以前写过,但没找到,可能在家里的电脑上<br>顺便找了一个,没有测试过<br>unit GetWord;<br><br>interface<br><br>uses<br> &nbsp;SysUtils,<br> &nbsp;windows,<br> &nbsp;messages;<br><br>const NHD_GETWORD_TIMER = 2;<br>const NHD_MAX_TEXTLEN = 1024;<br>const NHD_WIN_INITPOSX = -1;<br>const NHD_WIN_INITPOSY = -1;<br>const NHD_FLYWIN_WIDTH = 1;<br>const NHD_FLYWIN_HEIGHT = 1;<br>const NHD_CLASSNAME_LEN = 256;<br>const NHD_GW_WAITING_TIME = 200; &nbsp; //get word waiting time;<br><br> &nbsp;(*设置屏幕抓取函数*)<br> type TBL_SetFlag32 = function (nFlag : word; &nbsp; &nbsp;//设置是否取词<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hNotifyWnd : HWND; &nbsp; &nbsp;//当取词后得窗口句柄<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseX : integer; &nbsp; &nbsp;//X坐标<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseY : integer): DWORD;stdcall; &nbsp; &nbsp;//Y坐标<br>(* &nbsp; 功能:<br>启动或停止取词。<br> &nbsp; 参数:<br> &nbsp; &nbsp; &nbsp; nFlag<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输入] 指定下列值之一:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GETWORD_ENABLE: 开始取词。在重画被取单词区域前设置此标志。nhw32.dll是通过<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;重画单词区域,截取TextOutA, TextOutW, ExtTextOutA,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ExtTextOutW等Windows API函数的参数来取词的。<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GETWORD_DISABLE: 停止取词。<br> &nbsp; &nbsp; &nbsp; hNotifyWnd<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输入] 通知窗口句柄。当取到此时,向该通知窗口发送一登记消息:GWMSG_GETWORDOK。<br> &nbsp; &nbsp; &nbsp; MouseX<br>[输入] 指定取词点的X坐标。<br> &nbsp; &nbsp; &nbsp; MouseY<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输入] 指定取词点的Y坐标。<br> &nbsp; &nbsp;返回值:<br> &nbsp; &nbsp; &nbsp; 可忽略。<br>*)<br>type TLPRECT = ^TRECT; &nbsp;(*定义指针先*)<br> type TBL_GetText32 = function(lpszCurWord : pchar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nBufferSize : integer;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpWordRect : TLPRECT ): DWORD;stdcall;<br> &nbsp; &nbsp;(*功能:<br> &nbsp; &nbsp; &nbsp;从内部缓冲区取出单词文本串。对英语文本,该函数最长取出一行内以空格为界的三个英文单词串,<br> &nbsp; &nbsp; &nbsp;遇空格,非英文字母及除'-'外的标点符号,则终止取词。对汉字文本,该函数最长取出一行汉字串,<br> &nbsp; &nbsp; &nbsp;遇英语字母,标点符号等非汉语字符,则终止取词。该函数不能同时取出英语和汉语字符。<br> &nbsp; &nbsp;参数:<br> &nbsp; &nbsp; &nbsp; lpszCurWord<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输入] 目的缓冲区指针。<br> &nbsp; &nbsp; &nbsp; nBufferSize<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输入] 目的缓冲区大小。<br> &nbsp; &nbsp; &nbsp; lpWordRect<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[输出] 指向 RECT 结构的指针。该结构定义了被取单词所在矩形区域。<br> &nbsp; &nbsp;返回值:<br> &nbsp; &nbsp; &nbsp; &nbsp;当前光标在全部词中的位置。*)<br><br> type &nbsp; TSetNHW32 = function(): boolean; stdcall;<br> (*<br> &nbsp; &nbsp; 功能:<br> &nbsp; &nbsp; &nbsp; &nbsp;Win NT/2000 环境下的初始化函数。一般在程序开始时,调用一次。<br> &nbsp; &nbsp;参数:<br> &nbsp; &nbsp; &nbsp; &nbsp;无。<br> &nbsp; &nbsp;返回值:<br> &nbsp; &nbsp; &nbsp; &nbsp;如果成功 TRUE ,失败 FALSE 。<br> *)<br><br> type &nbsp;TResetNHW32= function():boolean; stdcall;<br>(* &nbsp; &nbsp;功能:<br> &nbsp; &nbsp; &nbsp; &nbsp;Win NT/2000 环境下的去初始化函数。一般在程序结束时调用。<br> &nbsp; &nbsp;参数:<br> &nbsp; &nbsp; &nbsp; &nbsp;无。<br> &nbsp; &nbsp;返回值:<br> &nbsp; &nbsp; &nbsp; &nbsp;如果成功 TRUE ,失败 FALSE 。*)<br><br><br><br>function NHD_FlyWndProc(hWnd, Msg,wParam,lParam: Integer): Integer; stdcall;<br>function NHD_CreateWindow(hInst: Integer): HWND;<br>procedure NHD_BeginGetWord(ptMousePos: TPOINT);<br><br>function NHD_ExitGetWords(): boolean;<br>function NHD_DestroyWindow(): boolean;<br>procedure NHD_FreeLoadedLib();<br>function NHD_InitGetWords(hInst: THANDLE; hwnd: HWND): HWND;<br>function NHD_LoadGetWordLib(): boolean;<br><br>var<br> &nbsp;WinClass: TWndClassA;<br> &nbsp;Inst: Integer;<br> &nbsp;Msg: TMsg;<br><br> &nbsp;g_TextBuffer : array[0..1024] of char;<br><br> &nbsp;g_hFlyWin : HWND;<br> &nbsp;g_nGWTimerID : word;<br> &nbsp;<br> &nbsp;g_hGetWordInst : Integer;<br> &nbsp;BL_SetFlag32 : TBL_SetFlag32;<br> &nbsp;BL_GetText32 : TBL_GetText32;<br> &nbsp;SetNHW32 : TSetNHW32;<br> &nbsp;ResetNHW32 : TResetNHW32;<br> &nbsp;g_hNHMainWin : HWND;<br> &nbsp;<br> &nbsp;g_WM_GetWordOk:WORD;<br> &nbsp;g_bInGetWord : boolean;<br> &nbsp;currpoint:Tpoint;<br> &nbsp;G_Rect : TRECT;<br>implementation<br><br>uses unit1;<br><br>function NHD_CreateWindow(hInst: Integer): HWND;<br>var<br> &nbsp; hwnd : LongWord;<br> &nbsp; wc : TWndClassA;<br>begin<br> &nbsp;if hInst = 0 then begin<br> &nbsp; &nbsp;result :=0;<br> &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;with wc do<br> &nbsp;begin<br> &nbsp; &nbsp;style &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= WS_EX_TOPMOST;<br> &nbsp; &nbsp;lpfnWndProc &nbsp; &nbsp; &nbsp; &nbsp;:= @NHD_FlyWndProc; &nbsp;(*消息处理函数*)<br> &nbsp; &nbsp;hInstance &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= hInst;<br> &nbsp; &nbsp;hbrBackground &nbsp; &nbsp; &nbsp;:= color_btnface + 1;<br> &nbsp; &nbsp;lpszClassname &nbsp; &nbsp; &nbsp;:= 'NHD_FLYWIN_DEMO';<br> &nbsp; &nbsp;hicon &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= 0;<br> &nbsp; &nbsp;hCursor &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= 0;<br> &nbsp; &nbsp;cbClsExtra &nbsp; &nbsp; &nbsp; &nbsp; := 0;<br> &nbsp; &nbsp;cbWndExtra &nbsp; &nbsp; &nbsp; &nbsp; := 0;<br> &nbsp;end;<br> &nbsp;RegisterClass(wc);<br><br> &nbsp;hwnd := CreateWindowEx (WS_EX_TOPMOST or WS_EX_TOOLWINDOW,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'NHD_FLYWIN_DEMO',<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'NHD_FlyWindow_Demo',<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WS_POPUP or WS_VISIBLE,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NHD_WIN_INITPOSX,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NHD_WIN_INITPOSY,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NHD_FLYWIN_WIDTH,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NHD_FLYWIN_HEIGHT,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0, &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hInst,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nil);<br> &nbsp; &nbsp;<br> &nbsp;result := hwnd;<br>end;<br><br>function NHD_FlyWndProc(hWnd, Msg,wParam,lParam: Integer): Integer; stdcall;<br>begin<br> &nbsp;//Unhook textout when reveived msg from getword;<br> &nbsp;if msg = g_WM_GetWordOk then begin<br> &nbsp; &nbsp;if g_bInGetWord then begin<br> &nbsp; &nbsp; &nbsp;g_bInGetWord := FALSE;<br> &nbsp; &nbsp; &nbsp;KillTimer(g_hFlyWin, NHD_GETWORD_TIMER);<br> &nbsp; &nbsp; &nbsp;g_nGWTimerID := 0;<br> &nbsp; &nbsp; &nbsp;BL_SetFlag32(GETWORD_DISABLE, 0, 0, 0);<br><br> &nbsp; &nbsp; &nbsp;if wParam = 0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp;BL_GetText32(@g_TextBuffer, sizeof(g_TextBuffer), @G_Rect);<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;PostMessage(g_hNHMainWin, NHD_WM_GETWORD_OK, 0, 0);<br> &nbsp; &nbsp; &nbsp;result := 0;<br> &nbsp; &nbsp; &nbsp;exit;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br><br> &nbsp;result := DefWindowProc(hWnd, msg, wParam, lParam);<br>end;<br><br>procedure NHD_GetWordTimerProc(hwnd: HWND; msg: word; idTimer: word; dwTime: DWORD);stdcall;<br>begin<br>//may be proior finished by Getword message;<br> &nbsp;if g_bInGetWord then begin<br> &nbsp; &nbsp;g_bInGetWord := FALSE;<br> &nbsp; &nbsp;//UnHook TextOut;<br> &nbsp; &nbsp;BL_SetFlag32(GETWORD_DISABLE, 0, 0, 0);<br> &nbsp; &nbsp;BL_GetText32(g_TextBuffer, NHD_MAX_TEXTLEN, @G_Rect);<br> &nbsp;end;<br><br> &nbsp;KillTimer(g_hFlyWin, NHD_GETWORD_TIMER);<br> &nbsp;g_nGWTimerID := 0;<br><br> &nbsp;PostMessage(g_hNHMainWin, NHD_WM_GETWORD_OK, 0, 0);<br>end;<br><br>procedure NHD_BeginGetWord(ptMousePos: TPOINT);<br>var<br> &nbsp;szAppClassName : array [0..NHD_CLASSNAME_LEN] of char;<br> &nbsp;hAppWin : LongWord;<br> &nbsp;nFlyWinLeft : integer;<br> &nbsp;nFlyWinWidth : integer;<br> &nbsp;rcAppWin : TRECT ;<br> &nbsp;cmpstr : string;<br>begin<br><br>//get window from mouse point;<br>hAppWin := WindowFromPoint(ptMousePos);<br><br>//check if the app window is EDIT, if it is, redraw whole line;<br>GetClassName(hAppWin, szAppClassName, NHD_CLASSNAME_LEN);<br><br>(*DbgPrintf(&quot;hAppWin: %x/n&quot;, hAppWin);<br>DbgPrintf(&quot;ClassName: %s/n&quot;, szAppClassName);*)<br>cmpstr := trim(strpas(szAppClassName));<br>// &nbsp; &nbsp; &nbsp; &nbsp;Form1.Edit1.text := cmpstr;<br><br>if ((cmpstr = 'Edit') or //NotePad<br> &nbsp;(cmpstr = 'Internet Explorer_Server') or //IE4.0<br> &nbsp;(cmpstr = 'RichEdit') or //<br> &nbsp;(cmpstr = 'RichEdit20A') or //WordPad<br> &nbsp;(cmpstr = 'RichEdit20W') or //WordPad<br> &nbsp;(cmpstr = 'HTML_Internet Explorer') or //IE3.0<br> &nbsp;(cmpstr = 'ThunderTextBox') or //VB Edit<br> &nbsp;(cmpstr = 'ThunderRT5TextBox') or //VB Edit<br> &nbsp;(cmpstr = 'ThunderRT6TextBox') or //VB Edit<br> &nbsp;(cmpstr = 'EXCEL&lt;') or //Excel 2000<br> &nbsp;(cmpstr = 'EXCEL7') &nbsp;or //Excel 2000<br> &nbsp;(cmpstr = 'EXCEL6') or //Excel 2000<br> &nbsp;(cmpstr = 'ConsoleWindowClass') or //NT V86<br> &nbsp;(cmpstr = 'Edit') or<br> &nbsp;(cmpstr = 'tty') &nbsp;or<br> &nbsp;(cmpstr = 'ttyGrab')) //Word97<br>then begin<br>GetWindowRect(hAppWin, rcAppWin);<br>nFlyWinLeft := rcAppWin.left - 4;<br>nFlyWinWidth := rcAppWin.right - rcAppWin.left - 8;<br><br>//don't not repaint whole line if too long;<br>if (ptMousePos.x - nFlyWinLeft) &gt; 200 then begin<br>nFlyWinLeft := ptMousePos.x - 200;<br>end;<br><br>//DbgPrintf(&quot;!!!!tty window&quot;);<br>end else begin<br>nFlyWinLeft := ptMousePos.x;<br>nFlyWinWidth := NHD_FLYWIN_WIDTH;<br>end;<br><br>//note: move the flywin to cursor pos &quot;x - 1&quot; to aviod mouse shape changing between ARROW and EDIT in edit area;<br>//use SetWindowPos instead of MoveWindow, for MoveWindow can not make menu item redraw.<br>SetWindowPos(g_hFlyWin, HWND_TOPMOST, <br> &nbsp; &nbsp;nFlyWinLeft, <br>ptMousePos.y - 1 ,<br>nFlyWinWidth,<br>NHD_FLYWIN_HEIGHT,<br>SWP_NOACTIVATE or SWP_NOREDRAW);<br><br>//set flag to avoid re-entry;<br>g_bInGetWord := TRUE;<br><br>//hook TextOut;<br>BL_SetFlag32(GETWORD_ENABLE, g_hFlyWin, ptMousePos.x, ptMousePos.y);<br><br>MoveWindow(g_hFlyWin, -1, -1, NHD_FLYWIN_WIDTH, NHD_FLYWIN_HEIGHT, TRUE);<br><br>g_nGWTimerID := SetTimer(g_hFlyWin, NHD_GETWORD_TIMER, NHD_GW_WAITING_TIME, @NHD_GetWordTimerProc);<br>end;<br><br>function NHD_CopyWordsTo(szBuffer: pchar; nBufferSize: Integer):Boolean;<br>var<br> nLen : integer;<br>begin<br> &nbsp;nLen := sizeof(g_TextBuffer);<br> &nbsp;if(nLen + 1) &gt; nBufferSize<br> &nbsp;then begin<br> &nbsp; &nbsp;result := false;<br> &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;ZeroMemory(szBuffer,nBufferSize);<br> &nbsp;CopyMemory(szBuffer, @g_TextBuffer, nLen);<br><br> &nbsp;result := true;<br> end;<br><br>function NHD_ExitGetWords(): boolean;<br>begin<br> &nbsp;//free libarys:<br> &nbsp;NHD_FreeLoadedLib();<br><br> &nbsp;NHD_DestroyWindow();<br><br> &nbsp;result := TRUE;<br>end;<br><br>function NHD_DestroyWindow(): boolean;<br>begin<br> &nbsp;if g_hFlyWin&lt;&gt;0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DestroyWindow(g_hFlyWin);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;g_hFlyWin := 0;<br> &nbsp;end;<br><br> &nbsp;result := TRUE;<br>end;<br><br>procedure NHD_FreeLoadedLib();<br>begin<br> &nbsp;if g_hGetWordInst&lt;&gt;0 then begin<br> &nbsp; &nbsp;//only valid in windows NT enviroment<br><br> &nbsp; &nbsp;if @ResetNHW32&lt;&gt;nil then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ResetNHW32();<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;FreeLibrary(g_hGetWordInst);<br> &nbsp; &nbsp;//g_hGetWordInst = 0;<br> &nbsp;end;<br>end;<br><br>function NHD_InitGetWords(hInst: THANDLE; &nbsp;hwnd: HWND): HWND;<br>begin<br> &nbsp;//save NH main window to send run time error messages:<br> &nbsp;g_hNHMainWin := hwnd;<br><br> &nbsp;if NHD_LoadGetWordLib=false then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NHD_FreeLoadedLib();<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;//Create fly_window (cause paint) and show text window;<br> &nbsp;g_hFlyWin := NHD_CreateWindow(hInst);<br> &nbsp;if g_hFlyWin=0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NHD_FreeLoadedLib();<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;g_WM_GetWordOk := RegisterWindowMessage('BL_HASSTRING');<br> &nbsp;if g_WM_GetWordOk=0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NHD_FreeLoadedLib();<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;result := g_hFlyWin;<br>end;<br><br>function NHD_LoadGetWordLib(): boolean;<br>begin<br> &nbsp;g_hGetWordInst := LoadLibrary('nhw32.dll');<br> &nbsp;if g_hGetWordInst=0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;messagebox(0,'装载动态链接库失败','警告',mb_ok or mb_iconwarning or mb_applmodal);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result := FALSE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br> &nbsp;@BL_SetFlag32 := GetProcAddress(g_hGetWordInst,'BL_SetFlag32');<br> &nbsp;if @BL_SetFlag32=nil then begin<br> &nbsp; messagebox(0,'装载屏幕取词动态链接库函数: BL_SetFlag32失败!','信息',MB_OK or MB_APPLMODAL or MB_ICONWARNING);<br> &nbsp; result := false;<br> &nbsp; exit;<br> &nbsp;end;<br><br> &nbsp;@BL_GetText32 := GetProcAddress(g_hGetWordInst,'BL_GetText32');<br> &nbsp;if @BL_GetText32=nil then begin<br> &nbsp; messagebox(0,'装载屏幕取词动态链接库函数: BL_GetText32失败!','信息',MB_OK or MB_APPLMODAL or MB_ICONWARNING);<br> &nbsp; result := false;<br> &nbsp; exit;<br> &nbsp;end;<br><br> &nbsp;@SetNHW32 := GetProcAddress(g_hGetWordInst,'SetNHW32');<br> &nbsp;if @SetNHW32=nil then begin<br> &nbsp; messagebox(0,'装载屏幕取词动态链接库函数: SetNHW32失败!','信息',MB_OK or MB_APPLMODAL or MB_ICONWARNING);<br> &nbsp; result := false;<br> &nbsp; exit;<br> &nbsp;end;<br><br> &nbsp;@ResetNHW32 := GetProcAddress(g_hGetWordInst,'ResetNHW32');<br> &nbsp;if @ResetNHW32=nil then begin<br> &nbsp; messagebox(0,'装载屏幕取词动态链接库函数: ResetNHW32失败!','信息',MB_OK or MB_APPLMODAL or MB_ICONWARNING);<br> &nbsp; result := false;<br> &nbsp; exit;<br> &nbsp;end;<br><br> &nbsp;if SetNHW32()=false then begin<br> &nbsp; messagebox(0,'无法设置屏幕取词!','信息',MB_OK or MB_APPLMODAL or MB_ICONWARNING);<br> &nbsp; result := false;<br> &nbsp; exit;<br> &nbsp;end;<br><br> result := true;<br>end;<br><br>end.
 
楼上的哥们 明天把家里的弄来给我贴上 或者发过来可以吗,谢谢了
 
to 浪人情哥, 我把你给我贴的代码测试了一下 ,除了错误,怎么调试呢????,这个帖子的原位置在那里
 
我这里有一个这样的软件~~~~~以前做的,要的话加我的QQ117697830
 
to &nbsp;cf83325 &nbsp;哥们你的哪个 我怎么没有找到屏幕取词的功能呢。你说的函数我没有找到
 
为什么<br>unit UnitHookDll;<br><br>interface<br><br>uses Windows, SysUtils, Classes, math, messages, dialogs, UnitNt2000Hook,<br> &nbsp; &nbsp;UnitHookType;<br><br>const<br> &nbsp; &nbsp;COLOR1=255;<br> &nbsp; &nbsp;COLOR2=0;<br> &nbsp; &nbsp;COLOR3=255;<br> &nbsp; &nbsp;Trap=true; //True陷阱式,False表示改引入表式<br><br> &nbsp; &nbsp;procedure StartHook; stdcall; {开始取词}<br> &nbsp; &nbsp;procedure StopHook; stdcall; {停止取词}<br><br>implementation<br><br>var<br> &nbsp; &nbsp;MouseHook: THandle;<br> &nbsp; &nbsp;pShMem: PShareMem;<br> &nbsp; &nbsp;hMappingFile: THandle;<br> &nbsp; &nbsp;FirstProcess:boolean;{是否是第一个进程}<br> &nbsp; &nbsp;Hook: array[fBeginPaint..fDrawTextW] of THookClass;{API HOOK类}<br> &nbsp; &nbsp;i:integer;<br><br>{自定义的BeginPaint}<br>function NewBeginPaint(Wnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;<br>type<br> &nbsp; TBeginPaint=function (Wnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;<br>begin<br> &nbsp; Hook[fBeginPaint].Restore;<br> &nbsp; result:=TBeginPaint(Hook[fBeginPaint].OldFunction)(Wnd,lpPaint);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0;<br> &nbsp; Hook[fBeginPaint].Change;<br>end;<br><br>{自定义的GetWindowDC}<br>function NewGetWindowDC(Wnd: HWND): HDC; stdcall;<br>type<br> &nbsp; TGetWindowDC=function (Wnd: HWND): HDC; stdcall;<br>begin<br> &nbsp; Hook[fGetWindowDC].Restore;<br> &nbsp; result:=TGetWindowDC(Hook[fGetWindowDC].OldFunction)(Wnd);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0; <br> &nbsp; Hook[fGetWindowDC].Change;<br>end;<br><br>{自定义的GetDC}<br>function NewGetDC(Wnd: HWND): HDC; stdcall;<br>type<br> &nbsp; TGetDC=function (Wnd: HWND): HDC; stdcall;<br>begin<br> &nbsp; Hook[fGetDC].Restore;<br> &nbsp; result:=TGetDC(Hook[fGetDC].OldFunction)(Wnd);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0;<br> &nbsp; Hook[fGetDC].Change;<br>end;<br><br>{自定义的CreateCompatibleDC}<br>function NewCreateCompatibleDC(DC: HDC): HDC; stdcall;<br>type<br> &nbsp; TCreateCompatibleDC=function (DC: HDC): HDC; stdcall;<br>begin<br> &nbsp; Hook[fCreateCompatibleDC].Restore;<br> &nbsp; result:=TCreateCompatibleDC(Hook[fCreateCompatibleDC].OldFunction)(DC);<br> &nbsp; if DC=pshmem^.DCMouse then{如果是当前鼠标的窗口HDC}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCCompatible:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCCompatible:=0;<br> &nbsp; Hook[fCreateCompatibleDC].Change;<br>end;<br><br>function NewTextOutA(theDC: HDC; nXStart, nYStart: integer; str: pchar; count: integer): bool;<br> &nbsp; &nbsp;stdcall;<br>type<br> &nbsp;TTextOutA=function (theDC: HDC; nXStart, nYStart: integer; str: pchar; count: integer): bool;stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fTextOutA].Restore;{暂停截取API,恢复被截的函数}<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPoint(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Str, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fTextOutA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TTextOutA(Hook[fTextOutA].OldFunction)(theDC, nXStart,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nYStart, str, count);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fTextOutA].Change;{重新截取API}<br>end;<br><br><br>function NewTextOutW(theDC: HDC; nXStart, nYStart: integer; str: pWidechar; count: integer): bool; stdcall;<br>type<br> &nbsp; TTextOutW=function (theDC: HDC; nXStart, nYStart: integer; str: pWidechar; count: integer): bool; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fTextOutW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPointW(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Pchar(WideCharToString(Str)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fTextOutW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TTextOutW(Hook[fTextOutW].OldFunction)(theDC, nXStart, nYStart, str, Count);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fTextOutW].Change;{重新截取API}<br>end;<br><br>function NewExtTextOutA(theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: PAnsiChar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>type<br> &nbsp;TExtTextOutA=function (theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: PAnsiChar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fExtTextOutA].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPoint(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Str, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fExtTextOutA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TExtTextOutA(Hook[fExtTextOutA].OldFunction)(theDC, nXStart, nYStart, toOptions, rect, Str,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Count, Dx);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fExtTextOutA].Change;{重新截取API}<br>end;<br><br>function NewExtTextOutW(theDC: HDC; nXStart, nYStart: integer; toOptions:<br> &nbsp; &nbsp;Longint; rect: PRect;<br> &nbsp; &nbsp;Str: Pwidechar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>type<br> &nbsp;TExtTextOutW=function (theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: Pwidechar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean; &nbsp; &nbsp;<br>begin<br> &nbsp; &nbsp;Hook[fExtTextOutW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPointW(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Pchar(WideCharToString(Str)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fExtTextOutW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp;if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TExtTextOutW(Hook[fExtTextOutW].OldFunction)(theDC, nXStart, nYStart, toOptions,Rect, Str, Count, Dx);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fExtTextOutW].Change;{重新截取API}<br>end;<br><br>function NewDrawTextA(theDC: HDC; lpString: PAnsiChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>type<br> &nbsp;TDrawTextA=function (theDC: HDC; lpString: PAnsiChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>var<br> &nbsp; &nbsp;poMouse,poOri,poDC: TPoint;<br> &nbsp; &nbsp;dwBytes: integer;<br> &nbsp; &nbsp;RectSave,rec:TRect;<br> &nbsp; &nbsp;faint:boolean; &nbsp; &nbsp;<br>begin<br> &nbsp; &nbsp;Hook[fDrawTextA].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := 0;{局部逻辑坐标初始化为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RectSave := lpRect;{显示的矩形}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OffsetRect(RectSave, poOri.x+poDC.x, poOri.y+poDC.y);{显示的矩形加上偏移}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PtInRect(RectSave, poMouse) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if nCount=-1 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strcopy(@(pShMem^.Text[0]), lpString);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBytes := min(nCount, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CopyMemory(@(pShMem^.Text[0]), lpString, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TDrawTextA(Hook[fDrawTextA].OldFunction)(theDC, lpString, nCount, lpRect, uFormat);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fDrawTextA].Change;{重新截取API}<br>end;<br><br>function NewDrawTextW(theDC: HDC; lpString: PWideChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>type<br> &nbsp;TDrawTextW=function (theDC: HDC; lpString: PWideChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>var<br> &nbsp; &nbsp;poMouse,poOri,poDC: TPoint;<br> &nbsp; &nbsp;dwBytes: integer;<br> &nbsp; &nbsp;RectSave,rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fDrawTextW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := 0;{局部逻辑坐标初始化为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RectSave := lpRect;{显示的矩形}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OffsetRect(RectSave, poOri.x+poDC.x, poOri.y+poDC.y);{显示的矩形加上偏移}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PtInRect(RectSave, poMouse) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if nCount=-1 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strcopy(@(pShMem^.Text[0]), Pchar(WideCharToString(lpString)));<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBytes := min(nCount*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CopyMemory(@(pShMem^.Text[0]), Pchar(WideCharToString(lpString)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.Text[dwBytes] := Chr(13);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#13)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TDrawTextW(Hook[fDrawTextW].OldFunction)(theDC, lpString, nCount, lpRect, uFormat);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fDrawTextW].Change;{重新截取API}<br>end;<br><br>{遍历所有菜单项}<br>procedure IterateThroughItems(WND:HWND;menu:Hmenu;p:TPoint;Level:integer);<br>var<br> &nbsp; i:integer;<br> &nbsp; info:TMenuItemInfo;<br> &nbsp; rec:TRect;<br>begin<br> &nbsp; for i:=0 to GetMenuItemCount(menu)-1 do {遍历所有子菜单项}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;fillchar(info,sizeof(info),0);<br> &nbsp; &nbsp; &nbsp;info.cbSize:=sizeof(info);<br> &nbsp; &nbsp; &nbsp;info.fMask:=MIIM_TYPE or MIIM_SUBMENU;<br> &nbsp; &nbsp; &nbsp;info.cch:=256;<br> &nbsp; &nbsp; &nbsp;getmem(info.dwTypeData,256);<br> &nbsp; &nbsp; &nbsp;{取菜单的文字}<br> &nbsp; &nbsp; &nbsp;GetMenuItemInfo(menu,i,true,info);<br> &nbsp; &nbsp; &nbsp;{取菜单的坐标}<br> &nbsp; &nbsp; &nbsp;GetMenuItemRect(wnd,menu,i,rec);<br> &nbsp; &nbsp; &nbsp;{如果鼠标在菜单的矩形区域内}<br> &nbsp; &nbsp; &nbsp;if (rec.Left&lt;=p.X)and(p.X&lt;=rec.Right)and(rec.Top&lt;=p.Y)and(p.Y&lt;=rec.Bottom)then<br> &nbsp; &nbsp; &nbsp;if (info.cch&lt;&gt;0) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; {取出菜单文字}<br> &nbsp; &nbsp; &nbsp; &nbsp; strlcopy(pShMem^.Text,info.dwTypeData,min(info.cch,MaxStringLen));<br> &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.bCanSpyNow := False;<br> &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; PostMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextW, 2);<br> &nbsp; &nbsp; &nbsp;end;<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;freemem(info.dwTypeData,256);<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;info.dwTypeData:=nil;<br> &nbsp; &nbsp; &nbsp;if info.hSubMenu&lt;&gt;0 then {如果它有下级子菜单,则归递调用}<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; IterateThroughItems(wnd,info.hSubMenu,p,Level+1);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; end;<br>end;<br><br>{定时器,每10毫秒被调用一次}<br>procedure fOnTimer(theWnd: HWND; msg, idTimer: Cardinal; dwTime: DWORD); stdcall;<br>var<br> &nbsp; &nbsp;InvalidRect: TRECT;<br> &nbsp; &nbsp;buffer:array[0..256]of char;<br> &nbsp; &nbsp;menu:Hmenu;<br> &nbsp; &nbsp;MousePoint:TPoint;<br>begin<br> &nbsp; &nbsp;pShMem^.nTimePassed := pShMem^.nTimePassed + 1;<br> &nbsp; &nbsp;if pShMem^.nTimePassed = 10 then {如果鼠标停留了0.1秒}<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;MousePoint:=pshmem^.pMouse;<br> &nbsp; &nbsp; &nbsp;{获取当前鼠标所在的窗口(等效于Delphi的控件)句柄}<br> &nbsp; &nbsp; &nbsp;pshmem^.hHookWnd := WindowFromPoint(MousePoint);<br> &nbsp; &nbsp; &nbsp;{屏幕坐标转换为窗口(等效于Delphi的控件)客户区的坐标}<br> &nbsp; &nbsp; &nbsp;ScreenToClient(pshmem^.hHookWnd, MousePoint);<br> &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := true;{可以开始取词}<br> &nbsp; &nbsp; &nbsp;{如果客户区的坐标为负值,则说明鼠标位于菜单或标题的上空}<br> &nbsp; &nbsp; &nbsp;if(MousePoint.x&lt;0)or(MousePoint.y&lt;0) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;{读取并设置标题,让其重绘}<br> &nbsp; &nbsp; &nbsp; &nbsp;Getwindowtext(pshmem^.hHookWnd,buffer,sizeof(buffer)-1);<br> &nbsp; &nbsp; &nbsp; &nbsp;Setwindowtext(pshmem^.hHookWnd,pchar(string(buffer)+' '));<br> &nbsp; &nbsp; &nbsp; &nbsp;Setwindowtext(pshmem^.hHookWnd,buffer);<br> &nbsp; &nbsp; &nbsp; &nbsp;{客户区的坐标恢复为屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp;ClientToScreen(pshmem^.hHookWnd, MousePoint);<br> &nbsp; &nbsp; &nbsp; &nbsp;{取出当前的菜单}<br> &nbsp; &nbsp; &nbsp; &nbsp;menu:=GetMenu(pshmem^.hHookWnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;if menu&lt;&gt;0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {遍历所有菜单,判断是否位于鼠标的下方}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IterateThroughItems(pshmem^.hHookWnd,menu,MousePoint,1);<br> &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp;else begin{否则,说明鼠标位于客户区}<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.left := MousePoint.x;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.top := MousePoint.y;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.Right := MousePoint.x + 1;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.Bottom := MousePoint.y + 1;<br> &nbsp; &nbsp; &nbsp; &nbsp;{重绘客户区}<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidateRect(pshmem^.hHookWnd, @InvalidRect, false);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else if pShMem^.nTimePassed &gt;= 11 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; pShMem^.nTimePassed := 11;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;{清空pShmem}<br>end;<br><br>{鼠标钩子}<br>function MouseHookProc(nCode: integer; wPar: WParam; lPar: LParam): lResult;<br> &nbsp; &nbsp;stdcall;<br>var<br> &nbsp; &nbsp;pMouseInf: TMouseHookStruct;<br>begin<br> &nbsp; &nbsp;pShMem^.nTimePassed := 0;<br> &nbsp; &nbsp;if (nCode &gt;= 0) and ((wPar = WM_MOUSEMOVE)or(wPar = WM_NCMOUSEMOVE)) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;pMouseInf := (PMouseHookStruct(lPar))^;<br> &nbsp; &nbsp; &nbsp; &nbsp;if (pShMem^.pMouse.x &lt;&gt; pMouseInf.pt.x) or<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(pShMem^.pMouse.y &lt;&gt; pMouseInf.pt.y) then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if nCode = HC_NOREMOVE then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.fStrMouseQueue := 'Not removed from the queue'<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.fStrMouseQueue := 'Removed from the queue';<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.pMouse := pMouseInf.pt;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{鼠标所在的窗口}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.hHookWnd := pMouseInf.hwnd;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{1是自定义的数值,表明这是鼠标消息}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;postMessage(pShMem^.hProcWnd, WM_MOUSEPT, 1, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Result := CallNextHookEx(MouseHook, nCode, wPar, lPar);<br>end;<br><br>{开始取词}<br>procedure StartHook; stdcall;<br>begin<br> &nbsp; if MouseHook=0 then<br> &nbsp; begin<br> &nbsp; &nbsp; pShMem^.fTimerID := SetTimer(0, 0, 10, @fOnTimer);<br> &nbsp; &nbsp; {注入其它进程}<br> &nbsp; &nbsp; MouseHook := SetWindowsHookEx(WH_MOUSE, MouseHookProc, HInstance, 0);<br> &nbsp; end;<br>end;<br><br>{停止取词}<br>procedure StopHook; stdcall;<br>begin<br> &nbsp; if MouseHook&lt;&gt;0 then<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;KillTimer(0, pShMem^.fTimerID);<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(MouseHook);<br> &nbsp; &nbsp; &nbsp;MouseHook:=0;<br> &nbsp; end;<br>end;<br><br>initialization<br> &nbsp; &nbsp; &nbsp; &nbsp;hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName);<br> &nbsp; &nbsp; &nbsp; &nbsp;if hMappingFile=0 then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShareMem),MappingFileName);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FirstProcess:=true; {这是第一个进程,即主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp; &nbsp;else FirstProcess:=false;<br> &nbsp; &nbsp; &nbsp; &nbsp;if hMappingFile=0 then Exception.Create('不能建立共享内存!');<br><br> &nbsp; &nbsp; &nbsp; &nbsp;pShMem := &nbsp;MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0);<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem = nil then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hMappingFile);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exception.Create('不能映射共享内存!');<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;if FirstProcess then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.bCanSpyNow:=false;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fBeginPaint]:=THookClass.Create(Trap,@BeginPaint,@NewBeginPaint);{Trap=True陷阱式}<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fGetWindowDC]:=THookClass.Create(Trap,@GetWindowDC,@NewGetWindowDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fGetDC]:=THookClass.Create(Trap,@GetDC,@NewGetDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fCreateCompatibleDC]:=THookClass.Create(Trap,@CreateCompatibleDC,@NewCreateCompatibleDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fTextOutA]:=THookClass.Create(Trap,@TextOutA,@NewTextOutA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fTextOutW]:=THookClass.Create(Trap,@TextOutW,@NewTextOutW);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fExtTextOutA]:=THookClass.Create(Trap,@ExtTextOutA,@NewExtTextOutA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fExtTextOutW]:=THookClass.Create(Trap,@ExtTextOutW,@NewExtTextOutW);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fDrawTextA]:=THookClass.Create(Trap,@DrawTextA,@NewDrawTextA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fDrawTextW]:=THookClass.Create(Trap,@DrawTextW,@NewDrawTextW); <br>finalization<br> &nbsp; &nbsp; &nbsp; &nbsp;for i:=Low(hook) to High(hook) do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Hook&lt;&gt;nil then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Hook.Destroy;<br> &nbsp; &nbsp; &nbsp; &nbsp;UnMapViewOfFile(pShMem); {取消映射视图}<br> &nbsp; &nbsp; &nbsp; &nbsp;CloseHandle(hMappingFile); {关闭映射文件句柄}<br>end.<br><br><br>这个dll 的代码 我更改了 对于英文 能够显示完整的一句话 &nbsp;而对于中英文标点混合的,就不能显示一句话了呢,请高人指点
 
给你发一个,pgx01234@163.com
 
pgx01234,:能给我发一个吗?xinyan2004@126.com
 
给我也发一个吧 <br>xuminjob@126.com
 
我也发一个,行不?<br>谢谢。<br>zxjrainbow@21cn.com
 
谢谢 pgx01234 了 你的不能取一行的文字 只能取鼠标左右几个文字的信息,我更改很多地方也没有达到 &nbsp;取一行文字的 ,还能指导下不了
 
不好意思<br>这个代码我是从网上下的,还没研究过呢。
 
那也谢谢你了 pgx01234 &nbsp;看有没有高手 ,这个周 揭贴了
 
这是我以前Down的一个,基本没了一下,没有错<br>以下是代码:<br>{Dll部分}<br>library GetWordDll;<br><br>uses<br> &nbsp; &nbsp;Windows,<br> &nbsp; &nbsp;SysUtils,<br> &nbsp; &nbsp;Classes,<br> &nbsp; &nbsp;UnitHookDll in 'UnitHookDll.pas',<br> &nbsp; &nbsp;UnitNt2000Hook in 'UnitNt2000Hook.pas',<br> &nbsp; &nbsp;UnitHookType in 'UnitHookType.pas';<br><br>exports<br> &nbsp; &nbsp;StartHook,<br> &nbsp; &nbsp;StopHook,<br>// &nbsp; &nbsp;MouseWndProc,<br> &nbsp; &nbsp;{以下导出列表都是必须的,<br> &nbsp; &nbsp;不能少,因为程序要取其地址}<br> &nbsp; &nbsp;NewBeginPaint,<br> &nbsp; &nbsp;NewCreateCompatibleDC,<br> &nbsp; &nbsp;NewTextOutA,<br> &nbsp; &nbsp;NewTextOutW,<br> &nbsp; &nbsp;NewExtTextOutA,<br> &nbsp; &nbsp;NewExtTextOutW,<br> &nbsp; &nbsp;NewDrawTextA,<br> &nbsp; &nbsp;NewDrawTextW; <br>begin<br>end.<br><br><br>unit UnitHookDll;<br><br>interface<br><br>uses Windows, SysUtils, Classes, math, messages, dialogs, UnitNt2000Hook,<br> &nbsp; &nbsp;UnitHookType;<br><br>const<br> &nbsp; &nbsp;COLOR1=255;<br> &nbsp; &nbsp;COLOR2=0;<br> &nbsp; &nbsp;COLOR3=255;<br> &nbsp; &nbsp;Trap=true; //True陷阱式,False表示改引入表式<br><br> &nbsp; &nbsp;procedure StartHook; stdcall; {开始取词}<br> &nbsp; &nbsp;procedure StopHook; stdcall; {停止取词}<br> &nbsp; &nbsp;function NewBeginPaint(Wnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;<br> &nbsp; &nbsp;function NewCreateCompatibleDC(DC: HDC): HDC; stdcall;<br> &nbsp; &nbsp;function NewTextOutA(theDC: HDC; nXStart, nYStart: integer; str: pchar; count: integer): bool;stdcall;<br> &nbsp; &nbsp;function NewTextOutW(theDC: HDC; nXStart, nYStart: integer; str: pWidechar; count: integer): bool; stdcall;<br> &nbsp; &nbsp;function NewExtTextOutA(theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rect: PRect; Str: PAnsiChar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br> &nbsp; &nbsp;function NewExtTextOutW(theDC: HDC; nXStart, nYStart: integer; toOptions:<br> &nbsp; &nbsp; &nbsp; &nbsp;Longint; rect: PRect;Str: Pwidechar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br> &nbsp; &nbsp;function NewDrawTextA(theDC: HDC; lpString: PAnsiChar; nCount: Integer;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br> &nbsp; &nbsp;function NewDrawTextW(theDC: HDC; lpString: PWideChar; nCount: Integer;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall; &nbsp; &nbsp; &nbsp; <br>implementation<br><br>var<br> &nbsp; &nbsp;MouseHook: THandle;<br> &nbsp; &nbsp;pShMem: PShareMem;<br> &nbsp; &nbsp;hMappingFile: THandle;<br> &nbsp; &nbsp;FirstProcess:boolean;{是否是第一个进程}<br> &nbsp; &nbsp;Hook: array[fBeginPaint..fDrawTextW] of THookClass;{API HOOK类}<br> &nbsp; &nbsp;i:integer;<br><br>{自定义的BeginPaint}<br>function NewBeginPaint(Wnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;<br>type<br> &nbsp; TBeginPaint=function (Wnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;<br>begin<br> &nbsp; Hook[fBeginPaint].Restore;<br> &nbsp; result:=TBeginPaint(Hook[fBeginPaint].OldFunction)(Wnd,lpPaint);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0;<br> &nbsp; Hook[fBeginPaint].Change;<br>end;<br><br>{自定义的GetWindowDC}<br>function NewGetWindowDC(Wnd: HWND): HDC; stdcall;<br>type<br> &nbsp; TGetWindowDC=function (Wnd: HWND): HDC; stdcall;<br>begin<br> &nbsp; Hook[fGetWindowDC].Restore;<br> &nbsp; result:=TGetWindowDC(Hook[fGetWindowDC].OldFunction)(Wnd);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0; <br> &nbsp; Hook[fGetWindowDC].Change;<br>end;<br><br>{自定义的GetDC}<br>function NewGetDC(Wnd: HWND): HDC; stdcall;<br>type<br> &nbsp; TGetDC=function (Wnd: HWND): HDC; stdcall;<br>begin<br> &nbsp; Hook[fGetDC].Restore;<br> &nbsp; result:=TGetDC(Hook[fGetDC].OldFunction)(Wnd);<br> &nbsp; if Wnd=pshmem^.hHookWnd then{如果是当前鼠标的窗口句柄}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCMouse:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCMouse:=0;<br> &nbsp; Hook[fGetDC].Change;<br>end;<br><br>{自定义的CreateCompatibleDC}<br>function NewCreateCompatibleDC(DC: HDC): HDC; stdcall;<br>type<br> &nbsp; TCreateCompatibleDC=function (DC: HDC): HDC; stdcall;<br>begin<br> &nbsp; Hook[fCreateCompatibleDC].Restore;<br> &nbsp; result:=TCreateCompatibleDC(Hook[fCreateCompatibleDC].OldFunction)(DC);<br> &nbsp; if DC=pshmem^.DCMouse then{如果是当前鼠标的窗口HDC}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;pshmem^.DCCompatible:=result;{记录它的返回值}<br> &nbsp; end<br> &nbsp; else pshmem^.DCCompatible:=0;<br> &nbsp; Hook[fCreateCompatibleDC].Change;<br>end;<br><br>function NewTextOutA(theDC: HDC; nXStart, nYStart: integer; str: pchar; count: integer): bool;<br> &nbsp; &nbsp;stdcall;<br>type<br> &nbsp;TTextOutA=function (theDC: HDC; nXStart, nYStart: integer; str: pchar; count: integer): bool;stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fTextOutA].Restore;{暂停截取API,恢复被截的函数}<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPoint(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Str, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fTextOutA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TTextOutA(Hook[fTextOutA].OldFunction)(theDC, nXStart,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nYStart, str, count);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fTextOutA].Change;{重新截取API}<br>end;<br><br><br>function NewTextOutW(theDC: HDC; nXStart, nYStart: integer; str: pWidechar; count: integer): bool; stdcall;<br>type<br> &nbsp; TTextOutW=function (theDC: HDC; nXStart, nYStart: integer; str: pWidechar; count: integer): bool; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fTextOutW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPointW(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Pchar(WideCharToString(Str)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fTextOutW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TTextOutW(Hook[fTextOutW].OldFunction)(theDC, nXStart, nYStart, str, Count);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fTextOutW].Change;{重新截取API}<br>end;<br><br>function NewExtTextOutA(theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: PAnsiChar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>type<br> &nbsp;TExtTextOutA=function (theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: PAnsiChar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fExtTextOutA].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPoint(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Str, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fExtTextOutA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TExtTextOutA(Hook[fExtTextOutA].OldFunction)(theDC, nXStart, nYStart, toOptions, rect, Str,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Count, Dx);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fExtTextOutA].Change;{重新截取API}<br>end;<br><br>function NewExtTextOutW(theDC: HDC; nXStart, nYStart: integer; toOptions:<br> &nbsp; &nbsp;Longint; rect: PRect;<br> &nbsp; &nbsp;Str: Pwidechar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>type<br> &nbsp;TExtTextOutW=function (theDC: HDC; nXStart, nYStart: integer; toOptions:Longint;<br> &nbsp; &nbsp;rect: PRect; Str: Pwidechar; Count: Longint; Dx: PInteger): BOOL; stdcall;<br>var<br> &nbsp; &nbsp;dwBytes: DWORD;<br> &nbsp; &nbsp;poOri, poDC, poText, poMouse: TPoint;<br> &nbsp; &nbsp;Size: TSize;<br> &nbsp; &nbsp;Rec:TRect;<br> &nbsp; &nbsp;faint:boolean; &nbsp; &nbsp;<br>begin<br> &nbsp; &nbsp;Hook[fExtTextOutW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := nXStart;{显示的相对坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := nYStart;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {计算显示文字的屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poDC.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poDC.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果对齐属性是居中}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (GetTextAlign(theDC) and TA_UPDATECP) &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCurrentPositionEx(theDC, @poOri);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.x := poText.x + poOri.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poText.y := poText.y + poOri.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {显示文字的长和宽}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetTextExtentPointW(theDC, Str, Count, Size);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (poMouse.x &gt;= poText.x) and (poMouse.x &lt;= poText.x + Size.cx)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and (poMouse.y &gt;= poText.y) and (poMouse.y &lt;= poText.y + Size.cy)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwBytes := min(Count*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(@(pShMem^.Text), Pchar(WideCharToString(Str)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fExtTextOutW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TExtTextOutW(Hook[fExtTextOutW].OldFunction)(theDC, nXStart, nYStart, toOptions,Rect, Str, Count, Dx);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fExtTextOutW].Change;{重新截取API}<br>end;<br><br>function NewDrawTextA(theDC: HDC; lpString: PAnsiChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>type<br> &nbsp;TDrawTextA=function (theDC: HDC; lpString: PAnsiChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>var<br> &nbsp; &nbsp;poMouse,poOri,poDC: TPoint;<br> &nbsp; &nbsp;dwBytes: integer;<br> &nbsp; &nbsp;RectSave,rec:TRect;<br> &nbsp; &nbsp;faint:boolean; &nbsp; &nbsp;<br>begin<br> &nbsp; &nbsp;Hook[fDrawTextA].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := 0;{局部逻辑坐标初始化为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RectSave := lpRect;{显示的矩形}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OffsetRect(RectSave, poOri.x+poDC.x, poOri.y+poDC.y);{显示的矩形加上偏移}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PtInRect(RectSave, poMouse) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if nCount=-1 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strcopy(@(pShMem^.Text[0]), lpString);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBytes := min(nCount, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CopyMemory(@(pShMem^.Text[0]), lpString, dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextA, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TDrawTextA(Hook[fDrawTextA].OldFunction)(theDC, lpString, nCount, lpRect, uFormat);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fDrawTextA].Change;{重新截取API}<br>end;<br><br>function NewDrawTextW(theDC: HDC; lpString: PWideChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>type<br> &nbsp;TDrawTextW=function (theDC: HDC; lpString: PWideChar; nCount: Integer;<br> &nbsp; &nbsp;var lpRect: TRect; uFormat: UINT): Integer; stdcall;<br>var<br> &nbsp; &nbsp;poMouse,poOri,poDC: TPoint;<br> &nbsp; &nbsp;dwBytes: integer;<br> &nbsp; &nbsp;RectSave,rec:TRect;<br> &nbsp; &nbsp;faint:boolean;<br>begin<br> &nbsp; &nbsp;Hook[fDrawTextW].Restore;{暂停截取API,恢复被截的函数}<br>// &nbsp; &nbsp;SetTextColor(thedc,RGB(COLOR1,COLOR2,COLOR3));<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem^.bCanSpyNow then{是否开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetDCOrgEx(theDC, poOri);{HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.x := 0;{局部逻辑坐标初始化为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poDC.y := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(poOri.X=0)and(poOri.Y=0)then{如果HDC的坐标为(0,0)}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (theDC=pShmem^.DCCompatible)then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; faint:=false{精确匹配,就是指定的内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else faint:=true;{模糊匹配,&quot;可能&quot;是内存HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{取鼠标当前处的窗口(等效于Delphi的控件)坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetWindowRect(pShMem^.hHookWnd,Rec);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.X:=Rec.Left;{把窗口坐标作为HDC的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poOri.Y:=Rec.Top;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin{如果是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{局部逻辑坐标转化为设备相关坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPToDP(theDC, poDC, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;faint:=false;{精确匹配,是普通HDC}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RectSave := lpRect;{显示的矩形}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OffsetRect(RectSave, poOri.x+poDC.x, poOri.y+poDC.y);{显示的矩形加上偏移}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {获取当前鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(poMouse);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {鼠标是否在文本的范围内}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PtInRect(RectSave, poMouse) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if nCount=-1 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strcopy(@(pShMem^.Text[0]), Pchar(WideCharToString(lpString)));<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{最多取MaxStringLen个字节}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBytes := min(nCount*2, MaxStringLen);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{拷贝字符串}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CopyMemory(@(pShMem^.Text[0]), Pchar(WideCharToString(lpString)), dwBytes);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{以空字符结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.Text[dwBytes] := Chr(0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextW, 2);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {如果输出的不是Tab键,而且是精确匹配的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string(pShMem^.Text)&lt;&gt;#3)and(not faint) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := False;{取词结束}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp;{调用被截的函数}<br> &nbsp; &nbsp; &nbsp; &nbsp;result := TDrawTextW(Hook[fDrawTextW].OldFunction)(theDC, lpString, nCount, lpRect, uFormat);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Hook[fDrawTextW].Change;{重新截取API}<br>end;<br><br>{遍历所有菜单项}<br>procedure IterateThroughItems(WND:HWND;menu:Hmenu;p:TPoint;Level:integer);<br>var<br> &nbsp; i:integer;<br> &nbsp; info:TMenuItemInfo;<br> &nbsp; rec:TRect;<br>begin<br> &nbsp; for i:=0 to GetMenuItemCount(menu)-1 do {遍历所有子菜单项}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;fillchar(info,sizeof(info),0);<br> &nbsp; &nbsp; &nbsp;info.cbSize:=sizeof(info);<br> &nbsp; &nbsp; &nbsp;info.fMask:=MIIM_TYPE or MIIM_SUBMENU;<br> &nbsp; &nbsp; &nbsp;info.cch:=256;<br> &nbsp; &nbsp; &nbsp;getmem(info.dwTypeData,256);<br> &nbsp; &nbsp; &nbsp;{取菜单的文字}<br> &nbsp; &nbsp; &nbsp;GetMenuItemInfo(menu,i,true,info);<br> &nbsp; &nbsp; &nbsp;{取菜单的坐标}<br> &nbsp; &nbsp; &nbsp;GetMenuItemRect(wnd,menu,i,rec);<br> &nbsp; &nbsp; &nbsp;{如果鼠标在菜单的矩形区域内}<br> &nbsp; &nbsp; &nbsp;if (rec.Left&lt;=p.X)and(p.X&lt;=rec.Right)and(rec.Top&lt;=p.Y)and(p.Y&lt;=rec.Bottom)then<br> &nbsp; &nbsp; &nbsp;if (info.cch&lt;&gt;0) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; {取出菜单文字}<br> &nbsp; &nbsp; &nbsp; &nbsp; strlcopy(pShMem^.Text,info.dwTypeData,min(info.cch,MaxStringLen));<br> &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.bCanSpyNow := False;<br> &nbsp; &nbsp; &nbsp; &nbsp; {发送WM_MOUSEPT成功取词的消息给主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp; PostMessage(pShMem^.hProcWnd, WM_MOUSEPT, fDrawTextW, 2);<br> &nbsp; &nbsp; &nbsp;end;<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;freemem(info.dwTypeData,256);<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;info.dwTypeData:=nil;<br> &nbsp; &nbsp; &nbsp;if info.hSubMenu&lt;&gt;0 then {如果它有下级子菜单,则归递调用}<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; IterateThroughItems(wnd,info.hSubMenu,p,Level+1);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; end;<br>end;<br><br>{定时器,每10毫秒被调用一次}<br>procedure fOnTimer(theWnd: HWND; msg, idTimer: Cardinal; dwTime: DWORD); stdcall;<br>var<br> &nbsp; &nbsp;InvalidRect: TRECT;<br> &nbsp; &nbsp;buffer:array[0..256]of char;<br> &nbsp; &nbsp;menu:Hmenu;<br> &nbsp; &nbsp;MousePoint:TPoint;<br>begin<br> &nbsp; &nbsp;pShMem^.nTimePassed := pShMem^.nTimePassed + 1;<br> &nbsp; &nbsp;if pShMem^.nTimePassed = 10 then {如果鼠标停留了0.1秒}<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;MousePoint:=pshmem^.pMouse;<br> &nbsp; &nbsp; &nbsp;{获取当前鼠标所在的窗口(等效于Delphi的控件)句柄}<br> &nbsp; &nbsp; &nbsp;pshmem^.hHookWnd := WindowFromPoint(MousePoint);<br> &nbsp; &nbsp; &nbsp;{屏幕坐标转换为窗口(等效于Delphi的控件)客户区的坐标}<br> &nbsp; &nbsp; &nbsp;ScreenToClient(pshmem^.hHookWnd, MousePoint);<br> &nbsp; &nbsp; &nbsp;pShMem^.bCanSpyNow := true;{可以开始取词}<br> &nbsp; &nbsp; &nbsp;{如果客户区的坐标为负值,则说明鼠标位于菜单或标题的上空}<br> &nbsp; &nbsp; &nbsp;if(MousePoint.x&lt;0)or(MousePoint.y&lt;0) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;{读取并设置标题,让其重绘}<br> &nbsp; &nbsp; &nbsp; &nbsp;Getwindowtext(pshmem^.hHookWnd,buffer,sizeof(buffer)-1);<br> &nbsp; &nbsp; &nbsp; &nbsp;Setwindowtext(pshmem^.hHookWnd,pchar(string(buffer)+' '));<br> &nbsp; &nbsp; &nbsp; &nbsp;Setwindowtext(pshmem^.hHookWnd,buffer);<br> &nbsp; &nbsp; &nbsp; &nbsp;{客户区的坐标恢复为屏幕坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp;ClientToScreen(pshmem^.hHookWnd, MousePoint);<br> &nbsp; &nbsp; &nbsp; &nbsp;{取出当前的菜单}<br> &nbsp; &nbsp; &nbsp; &nbsp;menu:=GetMenu(pshmem^.hHookWnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;if menu&lt;&gt;0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {遍历所有菜单,判断是否位于鼠标的下方}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IterateThroughItems(pshmem^.hHookWnd,menu,MousePoint,1);<br> &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp;else begin{否则,说明鼠标位于客户区}<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.left := MousePoint.x;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.top := MousePoint.y;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.Right := MousePoint.x + 1;<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidRect.Bottom := MousePoint.y + 1;<br> &nbsp; &nbsp; &nbsp; &nbsp;{重绘客户区}<br> &nbsp; &nbsp; &nbsp; &nbsp;InvalidateRect(pshmem^.hHookWnd, @InvalidRect, false);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else if pShMem^.nTimePassed &gt;= 11 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; pShMem^.nTimePassed := 11;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;{清空pShmem}<br>end;<br><br>{鼠标钩子}<br>function MouseHookProc(nCode: integer; wPar: WParam; lPar: LParam): lResult;<br> &nbsp; &nbsp;stdcall;<br>var<br> &nbsp; &nbsp;pMouseInf: TMouseHookStruct;<br>begin<br> &nbsp; &nbsp;pShMem^.nTimePassed := 0;<br> &nbsp; &nbsp;if (nCode &gt;= 0) and ((wPar = WM_MOUSEMOVE)or(wPar = WM_NCMOUSEMOVE)) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;pMouseInf := (PMouseHookStruct(lPar))^;<br> &nbsp; &nbsp; &nbsp; &nbsp;if (pShMem^.pMouse.x &lt;&gt; pMouseInf.pt.x) or<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(pShMem^.pMouse.y &lt;&gt; pMouseInf.pt.y) then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if nCode = HC_NOREMOVE then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.fStrMouseQueue := 'Not removed from the queue'<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.fStrMouseQueue := 'Removed from the queue';<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{鼠标的坐标}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.pMouse := pMouseInf.pt;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{鼠标所在的窗口}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.hHookWnd := pMouseInf.hwnd;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{1是自定义的数值,表明这是鼠标消息}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;postMessage(pShMem^.hProcWnd, WM_MOUSEPT, 1, 1);<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Result := CallNextHookEx(MouseHook, nCode, wPar, lPar);<br>end;<br><br>{开始取词}<br>procedure StartHook; stdcall;<br>begin<br> &nbsp; if MouseHook=0 then<br> &nbsp; begin<br> &nbsp; &nbsp; pShMem^.fTimerID := SetTimer(0, 0, 10, @fOnTimer);<br> &nbsp; &nbsp; {注入其它进程}<br> &nbsp; &nbsp; MouseHook := SetWindowsHookEx(WH_MOUSE, MouseHookProc, HInstance, 0);<br> &nbsp; end;<br>end;<br><br>{停止取词}<br>procedure StopHook; stdcall;<br>begin<br> &nbsp; if MouseHook&lt;&gt;0 then<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;KillTimer(0, pShMem^.fTimerID);<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(MouseHook);<br> &nbsp; &nbsp; &nbsp;MouseHook:=0;<br> &nbsp; end;<br>end;<br><br>initialization<br> &nbsp; &nbsp; &nbsp; &nbsp;hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName);<br> &nbsp; &nbsp; &nbsp; &nbsp;if hMappingFile=0 then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShareMem),MappingFileName);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FirstProcess:=true; {这是第一个进程,即主程序}<br> &nbsp; &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp; &nbsp;else FirstProcess:=false;<br> &nbsp; &nbsp; &nbsp; &nbsp;if hMappingFile=0 then Exception.Create('不能建立共享内存!');<br><br> &nbsp; &nbsp; &nbsp; &nbsp;pShMem := &nbsp;MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0);<br> &nbsp; &nbsp; &nbsp; &nbsp;if pShMem = nil then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hMappingFile);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exception.Create('不能映射共享内存!');<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;if FirstProcess then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pShMem^.bCanSpyNow:=false;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fBeginPaint]:=THookClass.Create(Trap,@BeginPaint,@NewBeginPaint);{Trap=True陷阱式}<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fGetWindowDC]:=THookClass.Create(Trap,@GetWindowDC,@NewGetWindowDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fGetDC]:=THookClass.Create(Trap,@GetDC,@NewGetDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fCreateCompatibleDC]:=THookClass.Create(Trap,@CreateCompatibleDC,@NewCreateCompatibleDC);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fTextOutA]:=THookClass.Create(Trap,@TextOutA,@NewTextOutA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fTextOutW]:=THookClass.Create(Trap,@TextOutW,@NewTextOutW);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fExtTextOutA]:=THookClass.Create(Trap,@ExtTextOutA,@NewExtTextOutA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fExtTextOutW]:=THookClass.Create(Trap,@ExtTextOutW,@NewExtTextOutW);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fDrawTextA]:=THookClass.Create(Trap,@DrawTextA,@NewDrawTextA);<br> &nbsp; &nbsp; &nbsp; &nbsp;Hook[fDrawTextW]:=THookClass.Create(Trap,@DrawTextW,@NewDrawTextW); <br>finalization<br> &nbsp; &nbsp; &nbsp; &nbsp;for i:=Low(hook) to High(hook) do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Hook&lt;&gt;nil then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Hook.Destroy;<br> &nbsp; &nbsp; &nbsp; &nbsp;UnMapViewOfFile(pShMem); {取消映射视图}<br> &nbsp; &nbsp; &nbsp; &nbsp;CloseHandle(hMappingFile); {关闭映射文件句柄}<br>end.<br><br><br>unit UnitHookType;<br><br>interface<br><br>uses windows, messages;<br><br>const<br> &nbsp; &nbsp;MaxStringLen = 100;<br> &nbsp; &nbsp;WM_MOUSEPT = WM_USER + 1138;<br> &nbsp; &nbsp;MappingFileName = 'GetWord32 for 9x NT 2000';<br> &nbsp; &nbsp;fBeginPaint=0;<br> &nbsp; &nbsp;fGetWindowDC=1;<br> &nbsp; &nbsp;fGetDC=2;<br> &nbsp; &nbsp;fCreateCompatibleDC=3;<br> &nbsp; &nbsp;fTextOutA=4;<br> &nbsp; &nbsp;fTextOutW=5;<br> &nbsp; &nbsp;fExtTextOutA=6;<br> &nbsp; &nbsp;fExtTextOutW=7;<br> &nbsp; &nbsp;fDrawTextA=8;<br> &nbsp; &nbsp;fDrawTextW=9;<br>type<br> &nbsp; &nbsp;PPointer = ^Pointer;<br> &nbsp; &nbsp;TShareMem = packed record<br> &nbsp; &nbsp; &nbsp; &nbsp;hProcWnd: HWND; {主应用窗口句柄}<br> &nbsp; &nbsp; &nbsp; &nbsp;hHookWnd: HWND; {鼠标所在窗口}<br> &nbsp; &nbsp; &nbsp; &nbsp;pMouse: TPoint; {鼠标信息}<br> &nbsp; &nbsp; &nbsp; &nbsp;DCMouse,DCCompatible: HDC;<br> &nbsp; &nbsp; &nbsp; &nbsp;fTimerID: integer;<br> &nbsp; &nbsp; &nbsp; &nbsp;fStrMouseQueue: array[0..MaxStringLen] of Char; {鼠标信息串}<br> &nbsp; &nbsp; &nbsp; &nbsp;nTimePassed: integer; {鼠标停留的时间}<br> &nbsp; &nbsp; &nbsp; &nbsp;bCanSpyNow: Boolean; {开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;Text: array[0..MaxStringLen] of Char; {字符串}<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;PShareMem = ^TShareMem;<br><br>implementation<br><br>end.<br><br><br>unit UnitNt2000Hook;<br><br>interface<br><br>uses classes, Windows,SysUtils, messages,dialogs;<br><br>type<br> &nbsp;TImportCode = packed record<br> &nbsp; &nbsp; JumpInstruction: Word;<br> &nbsp; &nbsp; AddressOfPointerToFunction: PPointer;<br> &nbsp;end;<br> &nbsp;PImportCode = ^TImportCode;<br> &nbsp;PImage_Import_Entry = ^Image_Import_Entry;<br> &nbsp;Image_Import_Entry = record<br> &nbsp; &nbsp;Characteristics: DWORD;<br> &nbsp; &nbsp;TimeDateStamp: DWORD;<br> &nbsp; &nbsp;MajorVersion: Word;<br> &nbsp; &nbsp;MinorVersion: Word;<br> &nbsp; &nbsp;Name: DWORD;<br> &nbsp; &nbsp;LookupTable: DWORD;<br> &nbsp;end;<br> &nbsp;TLongJmp = packed record<br> &nbsp; &nbsp; JmpCode: ShortInt; {指令,用$E9来代替系统的指令}<br> &nbsp; &nbsp; FuncAddr: DWORD; {函数地址}<br> &nbsp;end;<br><br> &nbsp;THookClass = class<br> &nbsp;private<br> &nbsp; &nbsp; Trap:boolean; {调用方式:True陷阱式,False改引入表式}<br> &nbsp; &nbsp; hProcess: Cardinal; {进程句柄,只用于陷阱式}<br> &nbsp; &nbsp; AlreadyHook:boolean; {是否已安装Hook,只用于陷阱式}<br> &nbsp; &nbsp; AllowChange:boolean; {是否允许安装、卸载Hook,只用于改引入表式}<br> &nbsp; &nbsp; Oldcode: array[0..4]of byte; {系统函数原来的前5个字节}<br> &nbsp; &nbsp; Newcode: TLongJmp; {将要写在系统函数的前5个字节}<br> &nbsp;private<br> &nbsp;public<br> &nbsp; &nbsp; OldFunction,NewFunction:Pointer;{被截函数、自定义函数}<br> &nbsp; &nbsp; constructor Create(IsTrap:boolean;OldFun,NewFun:pointer);<br> &nbsp; &nbsp; constructor Destroy;<br> &nbsp; &nbsp; procedure Restore;<br> &nbsp; &nbsp; procedure Change;<br> &nbsp;published<br> &nbsp;end;<br><br>implementation<br><br>{取函数的实际地址。如果函数的第一个指令是Jmp,则取出它的跳转地址(实际地址),这往往是由于程序中含有Debug调试信息引起的}<br>function FinalFunctionAddress(Code: Pointer): Pointer;<br>Var<br> &nbsp;func: PImportCode;<br>begin<br> &nbsp;Result:=Code;<br> &nbsp;if Code=nil then exit;<br> &nbsp;try<br> &nbsp; &nbsp;func:=code;<br> &nbsp; &nbsp;if (func.JumpInstruction=$25FF) then<br> &nbsp; &nbsp; &nbsp;{指令二进制码FF 25 &nbsp;汇编指令jmp [...]}<br> &nbsp; &nbsp; &nbsp;Func:=func.AddressOfPointerToFunction^;<br> &nbsp; &nbsp;result:=Func;<br> &nbsp;except<br> &nbsp; &nbsp;Result:=nil;<br> &nbsp;end;<br>end;<br><br>{更改引入表中指定函数的地址,只用于改引入表式}<br>function PatchAddressInModule(BeenDone:Tlist;hModule: THandle; OldFunc,NewFunc: Pointer):integer;<br>const<br> &nbsp; SIZE=4;<br>Var<br> &nbsp; Dos: PImageDosHeader;<br> &nbsp; NT: PImageNTHeaders;<br> &nbsp; ImportDesc: PImage_Import_Entry;<br> &nbsp; rva: DWORD;<br> &nbsp; Func: PPointer;<br> &nbsp; DLL: String;<br> &nbsp; f: Pointer;<br> &nbsp; written: DWORD;<br> &nbsp; mbi_thunk:TMemoryBasicInformation;<br> &nbsp; dwOldProtect:DWORD;<br>begin<br> &nbsp;Result:=0;<br> &nbsp;if hModule=0 then exit;<br> &nbsp;Dos:=Pointer(hModule);<br> &nbsp;{如果这个DLL模块已经处理过,则退出。BeenDone包含已处理的DLL模块}<br> &nbsp;if BeenDone.IndexOf(Dos)&gt;=0 then exit;<br> &nbsp;BeenDone.Add(Dos);{把DLL模块名加入BeenDone}<br> &nbsp;OldFunc:=FinalFunctionAddress(OldFunc);{取函数的实际地址}<br><br> &nbsp;{如果这个DLL模块的地址不能访问,则退出}<br> &nbsp;if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;<br> &nbsp;{如果这个模块不是以'MZ'开头,表明不是DLL,则退出}<br> &nbsp;if Dos.e_magic&lt;&gt;IMAGE_DOS_SIGNATURE then exit;{IMAGE_DOS_SIGNATURE='MZ'}<br><br> &nbsp;{定位至NT Header}<br> &nbsp;NT :=Pointer(Integer(Dos) + dos._lfanew);<br> &nbsp;{定位至引入函数表}<br> &nbsp;RVA:=NT^.OptionalHeader.<br> &nbsp; &nbsp; DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;<br> &nbsp;if RVA=0 then exit;{如果引入函数表为空,则退出}<br> &nbsp;{把函数引入表的相对地址RVA转换为绝对地址}<br> &nbsp;ImportDesc := pointer(DWORD(Dos)+RVA);{Dos是此DLL模块的首地址}<br><br> &nbsp;{遍历所有被引入的下级DLL模块}<br> &nbsp;While (ImportDesc^.Name&lt;&gt;0) do<br> &nbsp;begin<br> &nbsp; &nbsp;{被引入的下级DLL模块名字}<br> &nbsp; &nbsp;DLL:=PChar(DWORD(Dos)+ImportDesc^.Name);<br> &nbsp; &nbsp;{把被导入的下级DLL模块当做当前模块,进行递归调用}<br> &nbsp; &nbsp;PatchAddressInModule(BeenDone,GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);<br><br> &nbsp; &nbsp;{定位至被引入的下级DLL模块的函数表}<br> &nbsp; &nbsp;Func:=Pointer(DWORD(DOS)+ImportDesc.LookupTable);<br> &nbsp; &nbsp;{遍历被引入的下级DLL模块的所有函数}<br> &nbsp; &nbsp;While Func^&lt;&gt;nil do<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;f:=FinalFunctionAddress(Func^);{取实际地址}<br> &nbsp; &nbsp; &nbsp;if f=OldFunc then {如果函数实际地址就是所要找的地址}<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; VirtualQuery(Func,mbi_thunk, sizeof(TMemoryBasicInformation));<br> &nbsp; &nbsp; &nbsp; &nbsp; VirtualProtect(Func,SIZE,PAGE_EXECUTE_WRITECOPY,mbi_thunk.Protect);{更改内存属性}<br> &nbsp; &nbsp; &nbsp; &nbsp; WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,SIZE,written);{把新函数地址覆盖它}<br> &nbsp; &nbsp; &nbsp; &nbsp; VirtualProtect(Func, SIZE, mbi_thunk.Protect,dwOldProtect);{恢复内存属性}<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;If Written=4 then Inc(Result);<br>// &nbsp; &nbsp; &nbsp;else showmessagefmt('error:%d',[Written]);<br> &nbsp; &nbsp; &nbsp;Inc(Func);{下一个功能函数}<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;Inc(ImportDesc);{下一个被引入的下级DLL模块}<br> &nbsp;end;<br>end;<br><br>{HOOK的入口,其中IsTrap表示是否采用陷阱式}<br>constructor THookClass.Create(IsTrap:boolean;OldFun,NewFun:pointer);<br>begin<br> &nbsp; {求被截函数、自定义函数的实际地址}<br> &nbsp; OldFunction:=FinalFunctionAddress(OldFun);<br> &nbsp; NewFunction:=FinalFunctionAddress(NewFun);<br><br> &nbsp; Trap:=IsTrap;<br> &nbsp; if Trap then{如果是陷阱式}<br> &nbsp; begin<br> &nbsp; &nbsp; &nbsp;{以特权的方式来打开当前进程}<br> &nbsp; &nbsp; &nbsp;hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessID);<br> &nbsp; &nbsp; &nbsp;{生成jmp xxxx的代码,共5字节}<br> &nbsp; &nbsp; &nbsp;Newcode.JmpCode := ShortInt($E9); {jmp指令的十六进制代码是E9}<br> &nbsp; &nbsp; &nbsp;NewCode.FuncAddr := DWORD(NewFunction) - DWORD(OldFunction) - 5;<br> &nbsp; &nbsp; &nbsp;{保存被截函数的前5个字节}<br> &nbsp; &nbsp; &nbsp;move(OldFunction^,OldCode,5);<br> &nbsp; &nbsp; &nbsp;{设置为还没有开始HOOK}<br> &nbsp; &nbsp; &nbsp;AlreadyHook:=false;<br> &nbsp; end;<br> &nbsp; {如果是改引入表式,将允许HOOK}<br> &nbsp; if not Trap then AllowChange:=true;<br> &nbsp; Change; {开始HOOK}<br> &nbsp; {如果是改引入表式,将暂时不允许HOOK}<br> &nbsp; if not Trap then AllowChange:=false;<br>end;<br><br>{HOOK的出口}<br>constructor THookClass.Destroy;<br>begin<br> &nbsp; {如果是改引入表式,将允许HOOK}<br> &nbsp; if not Trap then AllowChange:=true;<br> &nbsp; Restore; {停止HOOK}<br> &nbsp; if Trap then{如果是陷阱式}<br> &nbsp; &nbsp; &nbsp;CloseHandle(hProcess);<br>end;<br><br>{开始HOOK}<br>procedure THookClass.Change;<br>var<br> &nbsp; nCount: DWORD;<br> &nbsp; BeenDone: TList;<br>begin<br> &nbsp;if Trap then{如果是陷阱式}<br> &nbsp;begin<br> &nbsp; &nbsp;if (AlreadyHook)or (hProcess = 0) or (OldFunction = nil) or (NewFunction = nil) then<br> &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp; &nbsp;AlreadyHook:=true;{表示已经HOOK}<br> &nbsp; &nbsp;WriteProcessMemory(hProcess, OldFunction, @(Newcode), 5, nCount);<br> &nbsp;end<br> &nbsp;else begin{如果是改引入表式}<br> &nbsp; &nbsp; &nbsp; if (not AllowChange)or(OldFunction=nil)or(NewFunction=nil)then exit;<br> &nbsp; &nbsp; &nbsp; BeenDone:=TList.Create; {用于存放当前进程所有DLL模块的名字}<br> &nbsp; &nbsp; &nbsp; try<br> &nbsp; &nbsp; &nbsp; &nbsp; PatchAddressInModule(BeenDone,GetModuleHandle(nil),OldFunction,NewFunction);<br> &nbsp; &nbsp; &nbsp; finally<br> &nbsp; &nbsp; &nbsp; &nbsp; BeenDone.Free;<br> &nbsp; &nbsp; &nbsp; end;<br> &nbsp;end;<br>end;<br><br>{恢复系统函数的调用}<br>procedure THookClass.Restore;<br>var<br> &nbsp; nCount: DWORD;<br> &nbsp; BeenDone: TList;<br>begin<br> &nbsp;if Trap then{如果是陷阱式}<br> &nbsp;begin<br> &nbsp; &nbsp;if (not AlreadyHook) or (hProcess = 0) or (OldFunction = nil) or (NewFunction = nil) then<br> &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp; &nbsp;WriteProcessMemory(hProcess, OldFunction, @(Oldcode), 5, nCount);<br> &nbsp; &nbsp;AlreadyHook:=false;{表示退出HOOK}<br> &nbsp;end<br> &nbsp;else begin{如果是改引入表式}<br> &nbsp; &nbsp;if (not AllowChange)or(OldFunction=nil)or(NewFunction=nil)then exit;<br> &nbsp; &nbsp;BeenDone:=TList.Create;{用于存放当前进程所有DLL模块的名字}<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp;PatchAddressInModule(BeenDone,GetModuleHandle(nil),NewFunction,OldFunction);<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp;BeenDone.Free;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br>end;<br><br>end.
 
{以下是调用}<br>unit UnitMain;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> &nbsp;StdCtrls,UnitHookType, ExtCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Label2: TLabel;<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure FormClose(Sender: TObject; var Action: TCloseAction);<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;procedure getMouseInfo(var theMess:TMessage); message WM_MOUSEPT;{处理WM_MOUSEPT}<br> &nbsp;private<br> &nbsp; &nbsp;hMapObj : THandle;<br> &nbsp; &nbsp;pShMem : PShareMem;<br> &nbsp; &nbsp;fWndClosed:boolean;{是否正在退出主程序}<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br>// &nbsp;{未公开的函数,实现隐浮窗口}<br>// &nbsp;procedure SwitchToThisWindow(wnd:Hwnd;Switch:BOOL);stdcall;external 'user32.dll';<br> &nbsp;procedure StartHook; stdcall; external 'GetWordDll.DLL';<br> &nbsp;procedure StopHook; stdcall; external 'GetWordDll.DLL';<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;if button1.caption='取词' then<br> &nbsp;begin<br> &nbsp; &nbsp; StartHook;<br> &nbsp; &nbsp; button1.caption:='停止';<br> &nbsp;end<br> &nbsp;else begin<br> &nbsp; &nbsp; StopHook;<br> &nbsp; &nbsp; button1.caption:='取词';<br> &nbsp;end;<br>end;<br><br>const<br> &nbsp;StrProcNames : array[fTextOutA..fDrawTextW+1] of String =<br> &nbsp; &nbsp;('来自TextOutA',<br> &nbsp; &nbsp; '来自TextOutW',<br> &nbsp; &nbsp; '来自ExtTextOutA',<br> &nbsp; &nbsp; '来自ExtTextOutW',<br> &nbsp; &nbsp; '来自DrawTextA',<br> &nbsp; &nbsp; '来自DrawTextW',<br> &nbsp; &nbsp; '来自菜单');<br><br>procedure TForm1.getMouseInfo(var theMess : TMessage);<br>begin<br> &nbsp;if fWndClosed then<br> &nbsp; &nbsp;Exit;<br> &nbsp;if theMess.LParam = 1 then{显示鼠标位置}<br>{ &nbsp; &nbsp;Label1.caption := 'X:' + IntToStr(pShMem^.pMouse.x) + ' ' +<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Y:' + IntToStr(pShMem^.pMouse.y) + ' ' +<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'HWND:0x' + IntToHex(pShMem^.hHookWnd, 8) + ' ' +<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pShMem^.fStrMouseQueue }<br> &nbsp;else if theMess.LParam = 2 then<br> &nbsp;begin<br> &nbsp; &nbsp;Label2.caption := pShMem^.Text;<br> &nbsp; &nbsp;if (theMess.WParam&gt;=0)and(theMess.WParam&lt;=5) then<br>// &nbsp; &nbsp; &nbsp; &nbsp;Label3.Caption :=StrProcNames[theMess.Wparam];<br> &nbsp;end;<br>end;<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br> &nbsp;fWndClosed := True;{正在退出主程序}<br> &nbsp;if button1.caption&lt;&gt;'取词' then<br> &nbsp; &nbsp;Button1Click(sender);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br> &nbsp;SetForegroundWindow(self.Handle);{实现隐浮窗口}<br> &nbsp;hMapObj := OpenFileMapping(FILE_MAP_WRITE,{获取完全访问映射文件}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; False,{不可继承的}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCTSTR(MappingFileName));{映射文件名字}<br> &nbsp;if hMapObj = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;ShowMessage('不能定位内存映射文件块!');<br> &nbsp; &nbsp;Halt;<br> &nbsp;end;<br><br> &nbsp;pShMem := MapViewOfFile(hMapObj,FILE_MAP_WRITE,0,0,0);<br> &nbsp;if pShMem = nil then<br> &nbsp;begin<br> &nbsp; &nbsp;ShowMessage('映射文件错误'+ IntToStr(GetLastError));<br> &nbsp; &nbsp;CloseHandle(hMapObj);<br> &nbsp; &nbsp;Halt;<br> &nbsp;end;<br><br> &nbsp;FillChar(pShMem^, SizeOf(TShareMem), 0);<br> &nbsp;pShMem^.hProcWnd := Self.Handle;<br> &nbsp;fWndClosed:=false;<br>end;<br><br>initialization<br>finalization<br><br>end.<br><br>unit UnitHookType;<br><br>interface<br><br>uses windows, messages;<br><br>const<br> &nbsp; &nbsp;MaxStringLen = 100;<br> &nbsp; &nbsp;WM_MOUSEPT = WM_USER + 1138;<br> &nbsp; &nbsp;MappingFileName = 'GetWord32 for 9x NT 2000';<br> &nbsp; &nbsp;fBeginPaint=0;<br> &nbsp; &nbsp;fGetWindowDC=1;<br> &nbsp; &nbsp;fGetDC=2;<br> &nbsp; &nbsp;fCreateCompatibleDC=3;<br> &nbsp; &nbsp;fTextOutA=4;<br> &nbsp; &nbsp;fTextOutW=5;<br> &nbsp; &nbsp;fExtTextOutA=6;<br> &nbsp; &nbsp;fExtTextOutW=7;<br> &nbsp; &nbsp;fDrawTextA=8;<br> &nbsp; &nbsp;fDrawTextW=9;<br>type<br> &nbsp; &nbsp;PPointer = ^Pointer;<br> &nbsp; &nbsp;TShareMem = packed record<br> &nbsp; &nbsp; &nbsp; &nbsp;hProcWnd: HWND; {主应用窗口句柄}<br> &nbsp; &nbsp; &nbsp; &nbsp;hHookWnd: HWND; {鼠标所在窗口}<br> &nbsp; &nbsp; &nbsp; &nbsp;pMouse: TPoint; {鼠标信息}<br> &nbsp; &nbsp; &nbsp; &nbsp;DCMouse,DCCompatible: HDC;<br> &nbsp; &nbsp; &nbsp; &nbsp;fTimerID: integer;<br> &nbsp; &nbsp; &nbsp; &nbsp;fStrMouseQueue: array[0..MaxStringLen] of Char; {鼠标信息串}<br> &nbsp; &nbsp; &nbsp; &nbsp;nTimePassed: integer; {鼠标停留的时间}<br> &nbsp; &nbsp; &nbsp; &nbsp;bCanSpyNow: Boolean; {开始取词}<br> &nbsp; &nbsp; &nbsp; &nbsp;Text: array[0..MaxStringLen] of Char; {字符串}<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;PShareMem = ^TShareMem;<br><br>implementation<br><br>end.<br>我自己写的就不好意思了,因为牵涉到公司利益
 
在《Delphi下深入windows核心编程》里面有代码,自己找本来吧。
 
谢谢 浪人情哥了<br> 我测试下
 
多人接受答案了。
 
后退
顶部