背景:在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);
}

解决方案 »

  1.   

    模拟mouse必须得先setcursorpos,然后在setcursorpos回原处
      

  2.   

    谢谢你耐心看完这么多,
    我的意思是可不可以不移动鼠标,直接发送一个鼠标点击消息,当然,这个消息中,坐标不是当前鼠标的坐标在我的程序中,模拟点击右键就是这样实现的:直接发送WM_RBUTTONDOWN,逻辑代码和示例的代码一致,结果也正确,换成左键点击其他魔兽地图也也可以实现,但是换成点击技能就不行了,我怀疑是不是魔兽中做了特别的处理?
      

  3.   

    讲的可能不清楚,但意思就是这样,要换我最简单的思路
    onrbtndown(pt)
    {
      getcursorpos(&pt1);
      if(PointInRect(pt1,战斗区域))
        Move();
      else if(PointInRect(pt1,技能))
        Skill();
    }
    你这样模拟就是浮云。
    这点从魔兽世界可窥一斑。所以首先你得从程序上出发,而不是想当然
      

  4.   

    你这个WM_RBUTTONDOWN是上层的消息,在这之前他实在是有太多的机会可以做事了,因此,解决办法有一些,都只要在他的处理逻辑前完成就行。
      

  5.   

    我只是想把Dota的的点击4个技能过程映射为按下4个按键,
    这个过程和玩游戏时鼠标坐标是多少没什么关系吧其中Move之类的都只是测试一下而已
      

  6.   

    有一种更好的方法
    找到技能栏上各个点的CALL
    现在VS浩方11都是这样的 不存在什么按键重复问题
      

  7.   

    按键有重复问题啊,如第一个技能按键为C,第二个技能也是C,在Dota的死亡模式和IMBA模式中,这是很正常的CALL是什么东西?
      

  8.   

    我说他游戏内部可能会像我写的那样判断鼠标位置,这样你的代码就没作用了。
    CALL是一种办法。
      

  9.   

    有些明白了,我试下SetCursor,呵呵
      

  10.   

    好象是鼠标操作太快了,魔兽没有来得及响应。但在钩子中sleep的话魔兽也会停。
    所以可以在钩子中新开一个线程,模拟鼠标点击的消息,按下和释放之间加入一定的延迟就可以了