高难度! 怎样判断鼠标是否在 popMenu 上? ( 积分: 200 )

  • 主题发起人 主题发起人 let_it_be
  • 开始时间 开始时间
L

let_it_be

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个 popMenu, 当PopMenu 弹出后,用Timer 监视鼠标的位置,可以判断鼠标是否在一些控件(例如Tbutton, TLabel, Tpanel)上,<br><br>但是: 怎样判断鼠标是否在弹出菜单上? 如果能找到弹出菜单的窗口, 可以用GetWindowRect, 再用ptInRect 判断 应该可以, 能得到这个窗口吗?
 
我有一个 popMenu, 当PopMenu 弹出后,用Timer 监视鼠标的位置,可以判断鼠标是否在一些控件(例如Tbutton, TLabel, Tpanel)上,<br><br>但是: 怎样判断鼠标是否在弹出菜单上? 如果能找到弹出菜单的窗口, 可以用GetWindowRect, 再用ptInRect 判断 应该可以, 能得到这个窗口吗?
 
var<br> &nbsp;MyHandle:HWND;<br> &nbsp;Pos:TPoint;<br>begin<br> &nbsp;//鼠标的位置<br> &nbsp;GetCursorPos(Pos);<br> &nbsp;//鼠标位置的句柄(可得到Enabled为False的Form句柄,但不能得到其它Enabled为False的控件句柄)<br> &nbsp;MyHandle:=WindowFromPoint(Pos);<br> &nbsp;if MyHandle=PopMenu1.Handle then<br> &nbsp;//Your Code <br>end;
 
procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;MyHandle:HWND;<br> &nbsp;Pos:TPoint;<br>begin<br> &nbsp;//鼠标的位置<br> &nbsp;GetCursorPos(Pos);<br> &nbsp;//鼠标位置的句柄(可得到Enabled为False的Form句柄,但不能得到其它Enabled为False的控件句柄)<br> &nbsp;MyHandle:=WindowFromPoint(Pos);<br> &nbsp;if MyHandle=pm.Handle then &nbsp;[red]//不行[/red] ???<br> &nbsp;begin<br><br> &nbsp; &nbsp; beep; <br> &nbsp;end;<br> &nbsp;//Your Code<br>end;
 
procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;MyHandle:HWND;<br> &nbsp;Pos:TPoint;<br>begin<br> &nbsp;//鼠标的位置<br> &nbsp;GetCursorPos(Pos);<br> &nbsp;//鼠标位置的句柄(可得到Enabled为False的Form句柄,但不能得到其它Enabled为False的控件句柄)<br> &nbsp;MyHandle:=WindowFromPoint(Pos);<br>[blue] &nbsp;textOut(getDc(0), 0, 0, pchar(inttostr(MyHandle)), length(inttostr(MyHandle)));<br> &nbsp;textOut(getDc(0), 0, 20, pchar(inttostr(pm.Handle)), length(inttostr(MyHandle)));[/blue] <br> if MyHandle=pm.Handle then<br> &nbsp;begin<br><br> &nbsp; &nbsp; beep;<br> &nbsp;end;<br> &nbsp;//Your Code<br>end;
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, ExtCtrls, StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;HandleText: TLabel;<br> &nbsp; &nbsp;Timer1: TTimer;<br> &nbsp; &nbsp;TitleText: TLabel;<br> &nbsp; &nbsp;procedure Timer1Timer(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;Pos: TPoint;<br> &nbsp;Handle: HWND;<br> &nbsp;Buf: array[0..1024] of Char;<br>begin<br> &nbsp;GetCursorPos(Pos); //得到當前光標的位置<br> &nbsp;Handle := WindowFromPoint(Pos); //返回當前位置的句柄<br> &nbsp;HandleText.Caption := IntToStr(Handle);<br> &nbsp;SendMessage(Handle, WM_GETTEXT, 33, Integer(@Buf)); //得到標題<br> &nbsp;TitleText.Caption := Buf;<br>end;<br>end.
 
procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;MyHandle:HWND;<br> &nbsp;Pos:TPoint;<br>begin<br> &nbsp;GetCursorPos(Pos);<br> &nbsp;MyHandle:=WindowFromPoint(Pos);<br> &nbsp;Caption:=IntToStr(PopupMenu1.WindowHandle)+':'+IntToStr(MyHandle);<br> &nbsp;//不知为什么PopupMenu1.WindowHandle&lt;&gt;MyHandle<br>end;
 
我记得有个消息的<br>只要拦截这个消息就可以了<br>不知道是不是WM_COMMAND
 
如果是托盘程序怎么办呀?当窗体隐藏了,点右键出现的快捷菜单怎么让它消失呀?<br>判断鼠标在不在这个 popup 上,如果不在,如果使它消失呢?
 
学习一下
 
通过消息钩子拦截WM_MENUSELECT消息,检查MF_MOUSESELECT标志。
 
屏幕取词源码<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><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.
 
能不能简单点, 当popmenu 弹出后, 能不能的到这个menu 的 window Rect?
 
大家请发言!
 
var<br> &nbsp;popMenuHandle: Hwnd;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;MyHandle:HWND;<br> &nbsp;Pos:TPoint;<br>begin<br> &nbsp;GetCursorPos(Pos);<br> &nbsp;MyHandle:=WindowFromPoint(Pos);<br> &nbsp;if myHandle=popmenuHandle then<br> &nbsp; &nbsp;....<br>end;<br><br>用FindWindow 找到 类名称TPutilWindow &nbsp;的 窗口的handle(popmemuhandle);<br><br>ok?
 
const<br> &nbsp;CM_MENUSELECT = WM_USER + 800;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;...<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp; &nbsp;procedure CMMenuSelect(var Message: TMessage); message CM_MENUSELECT;<br><br><br>var<br> &nbsp;MsgHook: HHook;<br> &nbsp;MenuItemText: string;<br><br>function GetMenuItemText(Menu: HMENU; MousePt: TPoint): string;<br>var<br> &nbsp;ID: Integer;<br> &nbsp;Info: TMenuItemInfo;<br> &nbsp;S: array[0..255] of Char;<br>begin<br> &nbsp;ID := Integer(MenuItemFromPoint(WindowFromPoint(MousePt), Menu, MousePt));<br> &nbsp;FillChar(Info, SizeOf(Info), 0);<br> &nbsp;Info.cbSize := SizeOf(Info);<br> &nbsp;Info.fMask := MIIM_TYPE;<br> &nbsp;Info.dwTypeData := S;<br> &nbsp;Info.cch := 255;<br> &nbsp;if not GetMenuItemInfo(Menu, ID, True, Info) or (Info.cch = 0) then<br> &nbsp; &nbsp;Result := ''<br> &nbsp;else<br> &nbsp; &nbsp;Result := S;<br>end;<br><br>function MsgHookCallback(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;<br>var<br> &nbsp;P: PCWPSTRUCT;<br> &nbsp;Flags: Word;<br> &nbsp;Menu: HMENU;<br> &nbsp;MousePt: TPoint;<br>begin<br> &nbsp;if Code = HC_ACTION then<br> &nbsp;begin<br> &nbsp; &nbsp;P := PCWPSTRUCT(lParam);<br> &nbsp; &nbsp;if P.message = WM_MENUSELECT then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Flags := HIWORD(P.wParam);<br> &nbsp; &nbsp; &nbsp;Menu := P.lParam;<br> &nbsp; &nbsp; &nbsp;if (Menu &lt;&gt; 0) and (Flags and MF_MOUSESELECT &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;GetCursorPos(MousePt);<br> &nbsp; &nbsp; &nbsp; &nbsp;MenuItemText := GetMenuItemText(Menu, MousePt);<br> &nbsp; &nbsp; &nbsp; &nbsp;PostMessage(Form1.Handle, CM_MENUSELECT, Menu, MakeLong(MousePt.X, MousePt.Y));<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br> &nbsp;Result := CallNextHookEx(MsgHook, Code, WParam, LParam);<br>end;<br><br>procedure TForm1.N4Click(Sender: TObject);<br>begin<br> &nbsp;if MsgHook = 0 then<br> &nbsp; &nbsp;MsgHook := SetWindowsHookEx(WH_CALLWNDPROC, @MsgHookCallback, HInstance, GetCurrentThreadID);<br>end;<br><br>procedure TForm1.N5Click(Sender: TObject);<br>begin<br> &nbsp;if MsgHook &lt;&gt; 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;UnhookWindowsHookEx(MsgHook);<br> &nbsp; &nbsp;MsgHook := 0;<br> &nbsp;end;<br>end;<br><br>procedure TForm1.CMMenuSelect(var Message: TMessage);<br>begin<br> &nbsp;Memo1.Lines.Add(Format('菜单项:%s 菜单句柄:%.8x 鼠标位置:(%d, %d)',<br> &nbsp; &nbsp;[MenuItemText, Message.WParam, LOWORD(Message.LParam), HIWORD(Message.LParam)]));<br>end;
 
最简单。 delphi6 测试通过<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;pt: TPoint;<br> &nbsp;wnd: Hwnd;<br> &nbsp;cName: array[0..255] of char;<br> &nbsp;s: string;<br>begin<br> &nbsp;getCursorPos(pt);<br> &nbsp;wnd:=windowFromPoint(pt);<br> &nbsp;getClassname(wnd, cname, sizeof(cname));<br> &nbsp;s:=strpas(cname);<br> &nbsp;if s='#32768' then beep;<br>end;
 
后退
顶部