魔兽鼠标模拟点击问题

ttktw 2011-09-15 12:30:17
背景:在Dota Imba模式中,人物的技能按键经常重复,这时,一般的改键工具就失去了效果,只能鼠标点击

设想:把人物的各个技能映射到不同的按键,如按下c键,模拟鼠标左键点击第一个技能

方案:1、获取魔兽的分辨率,得到每个技能的屏幕坐标
2、使用WH_GETMESSAGE钩子修改魔兽按键消息

已实现:1、一般的按键修改经测试,已经实现,如按下A键,魔兽处理B键
2、按下A键,鼠标模拟右键点击坐标【300,300】,移动人物

问题:按下A键,鼠标模拟左键点击第一个技能的坐标,但是没有反应。
用SPY++测试,魔兽确实接收到了这个消息,模拟按键与实际按键的消息没有任何区别,而且,经测试,只有鼠标移动这个技能坐标位置,按下A键,又有反应

关键代码:这段测试代码为钩子的回调函数,其中A键为F5键

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0 )
return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
MSG *pMsg=(MSG *)lParam;
if(pMsg->message==WM_KEYDOWN)
{
if (pMsg->wParam==0x74)
{
pMsg->message=WM_LBUTTONDOWN;
//填充新值
pMsg->wParam=1;//MK_LBUTTON
pMsg->lParam=MAKELONG(780,590);//魔兽分辨率为800×600,这里为第4个技能
}
}
return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

...全文
348 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
hudie86555 2012-04-20
  • 打赏
  • 举报
回复
好象是鼠标操作太快了,魔兽没有来得及响应。但在钩子中sleep的话魔兽也会停。
所以可以在钩子中新开一个线程,模拟鼠标点击的消息,按下和释放之间加入一定的延迟就可以了
ttktw 2011-09-19
  • 打赏
  • 举报
回复
怎么十三楼被和谐了?都没看到...
ttktw 2011-09-19
  • 打赏
  • 举报
回复
最近忙着找工作,这个项目有些延后了,先谢谢各位的回答,
结贴咯
ttktw 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 xuddk727 的回复:]

我说他游戏内部可能会像我写的那样判断鼠标位置,这样你的代码就没作用了。
CALL是一种办法。
[/Quote]
有些明白了,我试下SetCursor,呵呵
许文君 2011-09-16
  • 打赏
  • 举报
回复
我说他游戏内部可能会像我写的那样判断鼠标位置,这样你的代码就没作用了。
CALL是一种办法。
ttktw 2011-09-15
  • 打赏
  • 举报
回复
自己先顶个
ttktw 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 evi10r 的回复:]

有一种更好的方法
找到技能栏上各个点的CALL
现在VS浩方11都是这样的 不存在什么按键重复问题
[/Quote]
按键有重复问题啊,如第一个技能按键为C,第二个技能也是C,在Dota的死亡模式和IMBA模式中,这是很正常的

CALL是什么东西?
W1nds 2011-09-15
  • 打赏
  • 举报
回复
有一种更好的方法
找到技能栏上各个点的CALL
现在VS浩方11都是这样的 不存在什么按键重复问题
ttktw 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 xuddk727 的回复:]

讲的可能不清楚,但意思就是这样,要换我最简单的思路
onrbtndown(pt)
{
getcursorpos(&pt1);
if(PointInRect(pt1,战斗区域))
Move();
else if(PointInRect(pt1,技能))
Skill();
}
你这样模拟就是浮云。
这点从魔兽世界可窥一斑。所以首先你得从程序上出……
[/Quote]
我只是想把Dota的的点击4个技能过程映射为按下4个按键,
这个过程和玩游戏时鼠标坐标是多少没什么关系吧

其中Move之类的都只是测试一下而已
许文君 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ttktw 的回复:]

引用 5 楼 xuddk727 的回复:

你这种问题我无法解答。
比如说,我要对一个窗口记录鼠标点击,首先是判断鼠标是否在这个区域内,这种程序的内部逻辑我怎么可能得知。

谢谢你耐心看完这么多,
我的意思是可不可以不移动鼠标,直接发送一个鼠标点击消息,当然,这个消息中,坐标不是当前鼠标的坐标

在我的程序中,模拟点击右键就是这样实现的:直接发送WM_RBUTTONDOWN,逻辑……
[/Quote]
你这个WM_RBUTTONDOWN是上层的消息,在这之前他实在是有太多的机会可以做事了,因此,解决办法有一些,都只要在他的处理逻辑前完成就行。
许文君 2011-09-15
  • 打赏
  • 举报
回复
讲的可能不清楚,但意思就是这样,要换我最简单的思路
onrbtndown(pt)
{
getcursorpos(&pt1);
if(PointInRect(pt1,战斗区域))
Move();
else if(PointInRect(pt1,技能))
Skill();
}
你这样模拟就是浮云。
这点从魔兽世界可窥一斑。所以首先你得从程序上出发,而不是想当然
ttktw 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xuddk727 的回复:]

你这种问题我无法解答。
比如说,我要对一个窗口记录鼠标点击,首先是判断鼠标是否在这个区域内,这种程序的内部逻辑我怎么可能得知。
[/Quote]
谢谢你耐心看完这么多,
我的意思是可不可以不移动鼠标,直接发送一个鼠标点击消息,当然,这个消息中,坐标不是当前鼠标的坐标

在我的程序中,模拟点击右键就是这样实现的:直接发送WM_RBUTTONDOWN,逻辑代码和示例的代码一致,结果也正确,换成左键点击其他魔兽地图也也可以实现,但是换成点击技能就不行了,我怀疑是不是魔兽中做了特别的处理?
许文君 2011-09-15
  • 打赏
  • 举报
回复
你这种问题我无法解答。
比如说,我要对一个窗口记录鼠标点击,首先是判断鼠标是否在这个区域内,这种程序的内部逻辑我怎么可能得知。
ttktw 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xuddk727 的回复:]

模拟mouse必须得先setcursorpos,然后在setcursorpos回原处
[/Quote]
那为什么这个我能实现:
按下A键,鼠标模拟右键点击坐标【300,300】,移动人物成功
没有用到设置鼠标位置的函数
??
许文君 2011-09-15
  • 打赏
  • 举报
回复
模拟mouse必须得先setcursorpos,然后在setcursorpos回原处
ttktw 2011-09-15
  • 打赏
  • 举报
回复
都没人,55555~~~
芝麻来人

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧