为什么postmessage发送的鼠标移动消息不能精确定位?(50分)不够再加(50分)

  • 主题发起人 主题发起人 16cy
  • 开始时间 开始时间
to cqwty:<br>我试一下。<br>不过还想问一下,什么消息能获取当前鼠标所在位置?(请不要用getcursorpos,因为这个函数获取的是窗体外的鼠标位置,不是当前窗体的鼠标位置)
 
你可以用SetWindowsHookEx()拦截wh_mouse消息,这样你的定位应该是准确的<br>postmessage肯定不行,它是把消息传递给窗口过程,然后由窗口过程再分发,肯定有误差<br>sendmessage是直接发送到目标对象,应该比postmessage准确
 
to weichao9999:<br>你可以用SetWindowsHookEx()拦截wh_mouse消息,这样你的定位应该是准确的,能给我段代码吗?<br><br>另外我用sendmessage试过也一样
 
鼠标的hook很多了,先自己搜索一下吧,我有代码不过明天给你贴吧!
 
在应用程序取其它应用程序的光标所在控件的句柄 &nbsp;<br><br><br>来自:zhou_an_jun, 时间:2004-3-30 10:35:36, ID:2529231<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> setcapture(Handle);<br>end;<br><br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;<br> &nbsp;Shift: TShiftState; X, Y: Integer);<br>var<br> &nbsp; &nbsp;point : TPoint;<br> &nbsp; &nbsp;hwnd : THandle;<br>begin<br> &nbsp; &nbsp;point.x := x;<br> &nbsp; &nbsp;point.y := y;<br> &nbsp; &nbsp;point := ClientToScreen(point); &nbsp;// 客户区坐标转换到屏幕坐标<br> &nbsp; &nbsp;hwnd := WindowFromPoint(point); &nbsp;// 取鼠标点击的窗体句柄<br> &nbsp; &nbsp;//ReleaseCapture;// 终止捕获鼠标输入<br> &nbsp; &nbsp;if hwnd=handle then edit1.text := '没有点击其他窗体!'<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; edit1.Text := inttostr(hwnd);<br> &nbsp; &nbsp; &nbsp; end;<br>end;<br> &nbsp;<br><br><br>来自:cnaoszh, 时间:2004-3-30 12:00:32, ID:2529444<br>楼上只解决了鼠标按下时窗口的句柄<br><br>var MPoint:TPoint; <br> &nbsp; &nbsp;controlhwnd: Integer; <br><br>getcaretpos(MPoint); <br>controlhwnd:=windowfrompoint(MPoint); <br><br>controlhwnd就是你想要的, &nbsp; <br><br><br>来自:老人家, 时间:2004-3-30 12:48:22, ID:2529536<br>根本就不行 &nbsp;<br><br><br>来自:cnaoszh, 时间:2004-4-1 9:01:48, ID:2532739<br>做了个例子;<br><br>主程序:<br><br>unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> &nbsp;StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Edit1: TEdit;<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Label1: TLabel;<br> &nbsp; &nbsp;Button2: TButton;<br> &nbsp; &nbsp;procedure Button1Click(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>uses Unit2;<br><br>{$R *.DFM}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> run(Edit1);<br>end;<br><br>end.<br><br>子程序:<br><br>unit Unit2;<br><br>interface<br>uses Windows,Messages, SysUtils,TLHelp32,Dialogs,stdctrls;<br>var<br> &nbsp; HHExtendKeyProc:HHook;<br> &nbsp; FEdit:TEdit;<br> &nbsp; procedure stop();<br> &nbsp; procedure run(CurEdit:TEdit);<br><br>implementation<br>//&Iuml;&ucirc;&Iuml;&cent;&sup1;&sup3;×&Oacute;&frac12;&Oslash;&raquo;&ntilde;&frac14;ü&Aring;&Igrave;&Ecirc;&auml;&Egrave;&euml;<br>function LogProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;<br>var<br> &nbsp;CurResult:String;<br> &nbsp;ExtendStr:String;<br>begin<br> &nbsp; if (nCode &lt; 0) or (nCode &lt;&gt; HC_ACTION) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := CallNextHookEx(HHExtendKeyProc, nCode, wParam, lParam);<br> &nbsp; &nbsp;exit;<br> &nbsp;end;<br> &nbsp; if (peventmsg(lparam)^.message = WM_LBUTTONDOWN) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Fedit.text:=inttostr(peventmsg(lparam)^.hwnd);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp;Result:=CallNextHookEx(HHExtendKeyProc,nCode,wParam,lParam);<br>end;<br>//&AElig;&ocirc;&para;&macr;&Iacute;&pound;&Ouml;&sup1;&sup1;&sup3;×&Oacute;<br><br>procedure SetHook(fSet:boolean);<br>begin<br> &nbsp;if fSet=true then<br> &nbsp; begin<br> &nbsp; &nbsp; if HHExtendKeyProc=0 then<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp;HHExtendKeyProc:=SetWindowsHookEx(WH_JOURNALRECORD,@LogProc,hinstance,0);<br> &nbsp; &nbsp; end;<br> &nbsp;end<br> else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp;if HHExtendKeyProc&lt;&gt;0 then<br> &nbsp; &nbsp; &nbsp; UnhookWindowsHookEx(HHExtendKeyProc);<br> &nbsp; &nbsp;HHExtendKeyProc:=0;<br> &nbsp; end;<br>end;<br>procedure stop();<br>begin<br> &nbsp; SetHook(False);<br>end;<br>//&iquest;&ordf;&Ecirc;&frac14;<br>procedure run(CurEdit:TEdit);<br>begin<br> &nbsp;FEdit:= CurEdit;<br> &nbsp;SetHook(true);<br>end;<br>end.
 
为什么postmessage发送的鼠标移动消息不能精确定位?<br>我不是问怎么hook鼠标消息。
 
你用sendmessage看看,
 
用这个试试吧,<br> &nbsp; &nbsp; &nbsp; setcursorpos(100,100);<br> &nbsp; &nbsp; &nbsp; mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);<br> &nbsp; &nbsp; &nbsp; mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);<br><br>另外,再借你的地盘问个问题,我记得你也在找这个办法,不知道你找到没有<br>我要做一个(热血江湖)会加自动加血加蓝的外挂,<br>具体代码如下:<br>unit Mainf;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, ComCtrls,StdCtrls, ExtCtrls;<br><br>type<br> &nbsp;TMainForm = class(TForm)<br> &nbsp; &nbsp;TimerSM: TTimer;<br> &nbsp; &nbsp;TimerNG: TTimer;<br> &nbsp; &nbsp;TimerJN: TTimer;<br> &nbsp; &nbsp;CheckBoxSM: TCheckBox;<br> &nbsp; &nbsp;CheckBoxNG: TCheckBox;<br> &nbsp; &nbsp;EditSM: TEdit;<br> &nbsp; &nbsp;EditNG: TEdit;<br> &nbsp; &nbsp;CheckBoxJN: TCheckBox;<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Button2: TButton;<br> &nbsp; &nbsp;Label1:TLabel;<br> &nbsp; &nbsp;procedure CheckBoxSMClick(Sender: TObject);<br> &nbsp; &nbsp;procedure TimerSMTimer(Sender: TObject);<br> &nbsp; &nbsp;procedure Button2Click(Sender: TObject);<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure CheckBoxNGClick(Sender: TObject);<br> &nbsp; &nbsp;procedure TimerNGTimer(Sender: TObject);<br> &nbsp; &nbsp;procedure CheckBoxJNClick(Sender: TObject);<br> &nbsp; &nbsp;procedure TimerJNTimer(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br>const<br> &nbsp;SHENGMING: dword = $01453318; //红<br> &nbsp;NEIGONG: dword = $0145331C; // 蓝<br><br>var<br> &nbsp;MainForm: TMainForm;<br><br> &nbsp;hw: HWND;<br> &nbsp;pid: dword;//游戏句柄ID<br> &nbsp;h: THandle;//游戏句柄<br> &nbsp;tt: Cardinal;<br> &nbsp;procedure KeyF2;//按键<br> &nbsp;procedure KeyF3;<br> &nbsp;procedure KeyF4;<br><br>implementation<br><br>{$R *.dfm}<br>procedure TMainForm.Button1Click(Sender: TObject);<br>begin<br> &nbsp;if &nbsp;h = 0 then //如果句柄没打开<br> &nbsp; begin<br> &nbsp; &nbsp;hw:=FindWindow(nil,'YB_OnlineClient'); &nbsp; &nbsp;///<br> &nbsp; &nbsp;if hw = 0 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// &nbsp; &nbsp; &nbsp; 获得句柄ID<br> &nbsp; &nbsp; &nbsp;Exit; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;///<br> &nbsp; &nbsp;GetWindowThreadProcessId(hw, @pid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;///<br> &nbsp; &nbsp;h := OpenProcess(PROCESS_ALL_ACCESS, false, pid); &nbsp; &nbsp;///<br> &nbsp; &nbsp;if h = 0 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;///打开句柄<br> &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;///<br> &nbsp; end;<br> &nbsp;TimerNG.Interval := 1000 div trunc(5);<br> &nbsp;TimerSM.Interval := 1000 div trunc(5);<br> &nbsp;TimerJN.Interval := 1000 div trunc(2);///每秒钟运行次数<br>end;<br>procedure TMainForm.CheckBoxSMClick(Sender: TObject);<br>begin<br> &nbsp; if CheckBoxSM.Checked then &nbsp;//控制Timer是否运行<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; EditSM.Enabled := false;<br> &nbsp; &nbsp; TimerSM.Enabled := true;<br> &nbsp; &nbsp;end<br> &nbsp; else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; EditSM.Enabled := true;<br> &nbsp; &nbsp; TimerSM.Enabled := false;<br> &nbsp;end;<br>end;<br><br>procedure TMainForm.TimerSMTimer(Sender: TObject);<br>var<br> &nbsp;Sm: integer;<br> // tt: DWORD;<br>begin<br> &nbsp;ReadProcessMemory(h,pointer( SHENGMING), @Sm,sizeof(Sm), tt);<br>//扫描内存数据<br> &nbsp;<br> &nbsp;if ((Sm &lt;= StrToInt(EditSM.Text))and(Sm&lt;&gt;0)) and (h&lt;&gt;0) then<br>//如果血量值少于设定值并且不等于0<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp;KeyF3;<br> &nbsp; &nbsp; //按F3键<br> &nbsp; &nbsp; Label1.Caption :='F3运行中';<br> &nbsp; &nbsp; end;<br><br>end;<br><br>procedure KeyF2;<br>begin<br> &nbsp; keybd_event(VK_F2,mapvirtualkey(VK_F2,0),0,0);<br> &nbsp; keybd_event(VK_F2,mapvirtualkey(VK_F2,0),keyeventf_keyup,0);//按F2键<br>end;<br>procedure KeyF3;<br>begin<br> &nbsp; keybd_event(VK_F3,mapvirtualkey(VK_F3,0),0,0);<br> &nbsp; keybd_event(VK_F3,mapvirtualkey(VK_F3,0),keyeventf_keyup,0);//按F3键<br>end;<br>procedure KeyF4;<br>begin<br> &nbsp; keybd_event(VK_F4,mapvirtualkey(VK_F4,0),0,0);<br> &nbsp; keybd_event(VK_F4,mapvirtualkey(VK_F4,0),keyeventf_keyup,0);//按F4键<br>end;<br>procedure TMainForm.Button2Click(Sender: TObject);<br>begin<br> &nbsp;if h &lt;&gt; 0 then<br> &nbsp; begin<br> &nbsp; &nbsp;MessageBeep(0);<br> &nbsp; &nbsp;CloseHandle(h);<br> &nbsp; end;<br> &nbsp; close;<br>end;<br>end.<br><br>没有进游戏时,Label没有反应,<br>进入游戏了,按下按钮,当血量少于设定值时Label改变,说明Timer在运行,<br>可是游戏里不会自动加血,于是我改变了一下按键,把F3改成了F4,<br>游戏里还是没有反应,但我切到外挂窗口,按一下Alt键,外挂窗口关闭,<br>由此证明模拟键盘F4键一直进行中<br>后来我又换了一个模拟键盘的方法,<br>改变如下:<br>procedure KeyF3;<br>begin<br> &nbsp; PostMessage(Application.Handle, WM_KEYDOWN, VK_F4, 0);<br> &nbsp; PostMessage(Application.Handle, WM_KEYUP, VK_F4, 0);<br>end;<br>和<br>procedure KeyF3;<br>begin<br> &nbsp; PostMessage(h, WM_KEYDOWN, VK_F4, 0);<br> &nbsp; PostMessage(h, WM_KEYUP, VK_F4, 0);<br>end;<br>在游戏里还是没有反应,并且外挂窗口也没有反应了,但是Label标签改变<br>由是我再改成<br>procedure KeyF3;<br>begin<br> &nbsp; PostMessage(h, WM_KEYDOWN, VK_F4, 0);<br> &nbsp; PostMessage(h, WM_KEYUP, VK_F4, 0);<br> &nbsp; setcursorpos(500,400);<br> &nbsp; mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);<br> &nbsp; mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);<br>end;<br>这时鼠标在游戏里点击正常,键盘没有反应<br><br>在此麻烦大侠帮下忙,找下问题所在,<br>或再给几个模拟键盘的方法<br>非常感谢!!!!!
 
给你一点提示:<br>1.keybd_event()需要将窗口前置才起作用。<br>2.mapvirtualkey有时不好用,用另一个获得扫描码的函数。(具体是什么我忘了,回家查一下)<br>3.键盘/鼠标按下和弹起之间最好设一个延迟,如sleep(50);
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部