发表回复 
ahk引入大漠插件dll的某些函数 V1.0.1
2013-06-08, 13 : 24 (这个帖子最后修改于: 2014-12-02 13 : 11 by robertL.)
ahk引入大漠插件dll的某些函数 V1.0.1
[i=s] 本帖最后由 lsj8924 于 2013-6-9 13:26 编辑 [/i]
最近在用ahk引入大漠插件dll的某些函数时候碰到一个问题:ahk仅能够获取dll函数的返回值,不能获取dll函数中的值。说的太空洞,上图。
    [attach]2078[/attach]
如图所示,这是函数的说明。具体的用法就是dm.moveto x,y.
    [attach]2085[/attach]
这是在vbs运行的结果。
    [attach]2079[/attach]
如图一所示,ahk不支持这种写法。于是换了一种ahk支持的。
    [attach]2080[/attach]
    [attach]2081[/attach]
这种写法支持,也成功的移动了鼠标。但是这是不需要返回值的一类函数。重点在下一类函数。
    [attach]2082[/attach]
这是函数说明,意思是获得当前鼠标的位置。
    [attach]2083[/attach]

照旧不支持,所以返回失败。
    [attach]2084[/attach]
换一种写法,获取不了鼠标的x轴的位置。注意:这就是我描述的重点,ahk在引入obj的时候如果obj的函数内部有参数,是获取不到的。但是vbs就可以获取,就想第二​张图片见所显示。可能会有人说有返回值,如图。
    [attach]2086[/attach]
不错,的确有返回值。但是这个返回值是显示函数成功的返回值。不是我们需要的x,y的值。

到这里我想问题描述的很清楚了。就是对于后一类函数内的值如何获取?希望不吝赐教。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-08, 14 : 09
 
x是变参指针,你传递的是整型,类型不匹配
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢nepter
2013-06-08, 16 : 41
 
2# nepter
那具体的方法我改怎么用呢?就是像上面ahk代码改怎么改写?能不能具体指导一下?
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-08, 16 : 48
 
x改成&x
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-08, 17 : 02
 
4# nepter
我试了试,还是没有用啊。
[attach]2087[/attach]


附件 缩略图
   
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-08, 18 : 47 (这个帖子最后修改于: 2014-10-16 22 : 27 by robertL.)
 
[i=s] 本帖最后由 lsj8924 于 2013-6-8 19:59 编辑 [/i]
5# lsj8924
我也想了,可能ahk对于这类问题有自己的写法,我没有探索到,又或许是ahk的bug。不过都不重要,为什么?因为作为一种脚本语言,本来就是做的一些api函数的打包​,没有必要弄的这么复杂,需要用户自己去查变参函数,去查指针。但是我不懂c语言,查了也看不懂。我想是我方向错了,ahk不可能有这么复杂的知识背景。不支持就是不支持​,虽然我热爱它,但是我不能遮盖它的缺陷。
一句话:ahk不支持取函数过程的变量值,而是只支持获取函数的结果。
这句话其实意味着:那些想用ahk来开发游戏的用户,除了ahk的内置的一些东西外,你如果想扩展dll,国内目前的游戏dll你就不用想了。连最起码的一个获取鼠标位置​的函数都用不起,你还能做什么呢?
我无意对比什么,只是想强调ahk有着自己的弱项,如果做游戏开发调用dll,如大漠,天使,大兵什么的,歇了吧。
唯一能使我幽默一把的是:ahk为阻止中国游戏工具的开发事业做了很大的贡献。呵呵。
不过无所谓了,抱怨完了该用还是得面对实际,毕竟ahk又没收我钱,只是暂时离开一段时间吧,等有了解决方案在往回转。至少目前我想写一个游戏的工具ahk不支持,水平有​限,解决不了ahk这个缺陷(或者说对ahk了解太浅),都是自己的原因,等我编程水平深入了再回来,既然是开源的那么自己或许可以修改好呢。
谨以此来告诫一下那些想用ahk做游戏开发的人。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-08, 21 : 59
 
我用手机上的,没注意到
是用com来编程,应该把参数包装成com对象。
代码: (全选)
getcursorpos(ComObjParameter(0x4000,&x))
详情见帮助里关于comobj...的介绍
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢nepter
2013-06-08, 22 : 06
 
我想这不是AHK有缺陷,是你对编程了解的太少了。
我很难想象C不会,编程基础薄弱(指针是每个写代码的必修课),不了解COM编程的等等,能够进行比较深入的探索。
所以VB可能更适合你,因为它是弱类型、封装语言,比较适合对类型概念模糊的人。但由于其弱类型的特性导致它性能不高(因为要对每个类型进行判断)。

我用了AHK后,除了不能写驱动程序,他已经满足我所有的需求,可能是我基础比较好吧。我也希望学ahk的人能多学点编程基础,等大家水平都高了,来这里和我讨论一些高级​应用,我就不会觉得太孤独了吧。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢nepter
2013-06-08, 22 : 59
 
借着这个贴我再写点看法,可能偏题偏太远了。

很多人都说AHK是弱类型的语言,比如
代码: (全选)
x:="0x10",x:=x+0
字符串立刻变成了整数型。
但其实AHK是强类型语言,只不过一些符号运算把自动去识别变量的类型并进行了转换。
同理,当你和外部环境(比如COM,dll)进行消息传递时,你必须指定类型,因为ahk不了解外部环境,不会自动帮你转换变量类型,当然你可以自己封装函数,简化类型的​转换。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢nepter
2013-06-09, 13 : 25
 
9# nepter
nepter作为一个版主,每次都不厌其烦的回答我的问题,我在这里向你表达的不只是感谢了,其实更是一种深深的崇敬。可能是现在各种论坛风气不好吧,基本上问的问题都没​有人回答了,更别提版主亲自来回答了。这点让我很感动。
接触AHK也是不久前,主要是看了小众软件里边的一些介绍,自己认为这个小小的工具很不错,比较简单。因为之前自己开始学的第一门语言是python,喜欢省事,所以这个​工具和自己的理念比较契合吧。
没想到AHK用的比较顺手,越来越喜欢,每天都看小众软件的那些代码,真的是从心底里高兴。这么好的工具应该有很多人用吧,自然我认为AHK论坛应该很热闹吧,但是事实不​是这样的。看到论坛几个人在孤军奋战,总有些于心不忍。自然我用了AHK,我就应该为他做一点事。
自己的水平较低,不可能去修改,那就为这个工具的推广做一点贡献吧。所以就找了很多插件,做一下扩展,在用这些插件的过程中,发现他们的强项就是做游戏辅助工具吧。所以就​想依靠这些工具在AHK写一些技术含量低的关于如何用AHK来写游戏辅助工具的帖子来活跃下气氛,希望可以让别人更了解AHK比其他的工具做的更好。但是就是被卡在最基础​的地方了。其实还是很伤感,第一个计划就这样流产了。
于是自己就发了几句牢骚,可能伤害到了一些人,在这里说对不起。但是我确实没有恶意,也没有怪AHK不完善之类的。不能写了就算了,我认为根源在自己水平不够。不过前途是​光明的,道路是曲折的嘛,编程之路是要进行下去的。再说了,还有几位版主的热心解答,感觉心里热乎乎。
最后祝AHK中文论坛越来越好。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢lsj8924
2013-06-09, 14 : 42
 
其实吧,论坛不是冷清,而是ahk很能满足一般需求,一般解决了问题,也就很少逛论坛了,至少我是这样哈

版主确实很热心,说实话,我调用一些简单的C写的dll还行,多试几次就行了,但COM的那个参数,还真第一次看到,看来还需要学习哈

★作品页★
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢linpinger
2013-06-09, 16 : 13
 
11# linpinger
恩,其实问题版主人很好。不过我这个问题还是挂着。如图:
[attach]2088[/attach]


附件 缩略图
   
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2013-06-10, 17 : 54
 
代码: (全选)
x:=ComVar()
y:=ComVar()
getcursorpos(x.ref,y.ref)
msgbox % x[] "," y[]

ComVar(Type=0xC)
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; 创建含 1 个 VARIANT 类型变量的数组.  此方法可以让内部代码处理
    ; 在 VARIANT 和 AutoHotkey 内部类型之间的所有转换.
    arr := ComObjArray(Type, 1)
    ; 锁定数组并检索到 VARIANT 的指针.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; 保存可用于传递 VARIANT ByRef 的数组和对象.
    return { ref: ComObjParameter(0x4000|Type, arr_data), _: arr, base: base }
}
ComVarGet(cv, p*) { ; 当脚本访问未知字段时调用.
    if p.MaxIndex() = "" ; 没有名称/参数, 即 cv[]
        return cv._[0]
}
ComVarSet(cv, v, p*) { ; 当脚本设置未知字段时调用.
    if p.MaxIndex() = "" ; 没有名称/参数, 即 cv[]:=v
        return cv._[0] := v
}
ComVarDel(cv) { ; 当对象被释放时调用.
    ; 必须进行这样的处理以释放内部数组.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}
帮助里的例子
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢nepter
2013-06-11, 17 : 57 (这个帖子最后修改于: 2014-10-16 22 : 29 by robertL.)
 
[i=s] 本帖最后由 lsj8924 于 2013-6-14 00:46 编辑 [/i]
13# nepter
调试了很久,不行,代码就不贴了,自己放弃了。编程还是要立足于自学,总是靠别人也不是回事,况且每个人都有自己的事情。改学vc++了,教程有,资料全,懂得人比较多,​学习的成本低点,效率可能会好点。很多com编写都是用的c和vb,最关键的是com技术很多研究都是用vc++来做示例的。
就像管理员说的,一个编程基础薄弱,不懂指针,不懂com的人终究是走不远的。况且我不是那种只想用ahk编写send key,因为作为sendkey的工具比ahk简单的多多了。作为一个曾经的ahker,最后在啰嗦几句,就是ahk的资料太是问题了。不说像《Visual C++ 2008入门经典》这种专门的书籍,就连帮助的com一章自我感觉云里雾里,ahk默认每个接触者都是com高手吗?如果是这样,门槛就太高了吧?但是如果ahk想做的就​是用简单的方法做桌面开发,那为什么不把以上的问题最简单化处理呢?难道希望每一个新手在用ahk之后要学习com编程,之后发现com编程最依赖的是c,于是去学习c。​vc6.0有点过期,不得不去看看vs2010。我还没学完,没有任何发言权,但是我质疑,真正的c高手,com高手,还需要ahk吗?ahk的定位到底是啥呢?
最后感谢管理员不厌其烦的回帖。插件就放这里了,供那些喜欢测试的人测试。如果能把这些插件引入到ahk中的话,ahk肯定会吸引一大批的游戏玩家的。虚妄的事我这菜鸟就​不敢说了。呵呵,此贴到此为止.
http://pan.baidu.com/share/link?shareid=...=488579410
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢lsj8924
2013-06-11, 19 : 39
 
学完vc,回来再看ahk就觉得很简单了,要学windows编程,不学com是不行的,或者看.net,对初学者比较简单,现在win8从win32慢慢过渡到winr​t,以后整个构架都会发生变化,无论什么阶段,都会有很多人有到底学什么的困惑。

我是以前只学了c,并打了比较好的基础,学起其他语言来比较快,我真的希望喜欢学编程的人能学个比较基础的语言,了解一些计算机的基本概念,这样学起其他语言来就很快了。​

ahk本来也分autohotkey_basic和autohotkey_L/H,一个给初学者用的,另一个可以实现更多应用,ahk英语官方论坛里版主就希望用L或H的人应该有点编程基础,因为它有更多lowlevel的运用。

你用C或VB的话,复杂性不会比AHK少,这是我的经验。

AHK的帮助和案例是太少了,我有时间就写点,但光靠我一个人肯定是不够的。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢nepter
2013-06-13, 20 : 50
 
实测13楼的代码

成功调用

开头要改成ahk的调用方式。。。。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-09-17, 23 : 40 (这个帖子最后修改于: 2014-09-26 07 : 39 by angkevin.)
我写的脚本,只有键盘操作不好用
;下面是我写的采集物品的脚本代码,支持后台操作,字库搜索,鼠标操作都好用,只有键盘操作不好用,还请斑竹帮忙解决一下。
;详细代码见附件

代码: (全选)
#SingleInstance Force
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
SetTitleMatchMode, 3
SetWorkingDir,%A_Temp%

;验证是否具有管理员权限,没有则尝试用管理员权限启动
If not A_IsAdmin                
{
    Run *RunAs "%A_ScriptFullPath%"
    ExitApp
}
;必须放前面,不然不会被执行
OnExit, ExitScript

;安装使用的插件和其他各种文件
IfNotExist,dm.dll
    FileCopy, %A_ScriptDir%\Bin\dm.dll, dm.dll,1

IfNotExist,MiningLib.txt
    FileCopy, %A_ScriptDir%\Lib\MiningLib.txt,MiningLib.txt,1

;注册大漠插件
RunWait,regsvr32 /i /s "%A_WorkingDir%\dm.dll",,Hide
dm:=ComObjCreate("dm.dmsoft")

;使用字库,先设置工作目录,再设置字库文件目录
wordLibPath:=A_WorkingDir . "\MiningLib.txt"
dm.SetPath(A_WorkingDir)
dm.SetDict(0,wordLibPath)

If (dm.GetScreenDepth()<>32)
{
      dm.SetScreen(A_ScreenWidth,A_ScreenHeight,32)
}
dm.SetShowErrorMsg(0)

;热键操作开始
^CapsLock::
Sleep,2000
;设置全局变量
wHandle := dm.FindWindow("Mabinogi", "洛奇")
;wHandle := dm.FindWindow("Notepad", "MabiHelper.txt - 记事本")
dm.BindWindow(wHandle,"gdi","dx2","dx",0)
xLeft:=0
xRight:=0
yTop:=0
yBottom:=0
dmRet:=GetClientRect(wHandle,xLeft, yTop, xRight, yBottom)
winWidth:=xRight-xLeft
winHeight:=yBottom-yTop
xLocCenter := Ceil((xLeft + xRight) / 2)
yLocCenter := Ceil((yTop + yBottom) / 2)

;MsgBox,%wHandle%,%xLeft%,%yTop%,%xRight%,%yBottom%,%xLocCenter%,%yLocCenter%

Loop
{
    DoSkill(xLocCenter,yLocCenter)
    ;SkillUpdating()
    ;DoStamina()
    ;DoEat()
    ;ChangeArm()
}
Return

DoSkill(xLocCenter,yLocCenter)
{
    global dm
    ;CheckContinue()    
    ;取消现使用技能
    KeyPress("esc")
    Sleep, 500    
    MoveTo(xLocCenter, yLocCenter)    
    Sleep,500
    DoGather(xLocCenter,yLocCenter)
    Sleep,500
    DoPicks(xLocCenter,yLocCenter)
    Sleep, 800
}
DoGather(xLocCenter,yLocCenter)
{
    global dm
    xLoc:=xLocCenter
    while,20
    {
        xLoc:=xLoc+5
            MoveTo(xLoc,yLocCenter)
        Sleep,500
        CurShape:=dm.GetCursorShape()
        if(CurShape=="2A0721A9")
        {
            LeftClick(xLoc,yLocCenter)
            Break
        }
            Sleep, 200
        }
}
DoPicks(xLocCenter,yLocCenter)
{
    KeyDown("alt")
    DoPick(xLocCenter,yLocCenter,"锌","a9aeb9-050505")
    DoPick(xLocCenter,yLocCenter,"锡","fdaeb9-050505")
    DoPick(xLocCenter,yLocCenter,"镍","ebaeb9-050505")
    DoPick(xLocCenter,yLocCenter,"希|尔|文","febdcb-050505")
    KeyUp("alt")
}
DoPick(xLocCenter,yLocCenter,word,colorFormat)
{    
    Sleep, 100
    x1:=800
    y1:=400
    x2:=1200
    y2:=700
    dmRet:=FindStrings(x1,y1,x2,y2,word,colorFormat,1.0)
    Loop % dmRet.MaxIndex()
    {
        lPoint:=dmRet[A_Index]
        dmRetArray := StringSplit,dmRetArray,lPoint,",",
        LeftClick(dmRetArray[1],dmRetArray[2])
        Sleep,200
    }
    Sleep,200
    Send {Alt Up}
}
FindString(x1,y1,x2,y2,word,colorFormat,sim)
{
    global dm
    dmRet := dm.FindStrE(x1,y1,x2,y2,word,colorFormat,sim)
    dmRetArray:=StrSplit(dmRet, "|")
    return dmRetArray
}
FindStrings(x1,y1,x2,y2,word,colorFormat,sim)
{
    global dm
    dmRetArray:=StrSplit("-1|-1|-1", "|")
    dmRet := dm.FindStrEx(x1,y1,x2,y2,word,colorFormat,sim)
    If(StrLen(dmRet) > 0)
    {
        dmRetArray:=StrSplit(dmRet, "|")
    }
    return dmRetArray
}
GetCursorShape()
{
    global dm
    return dm.GetCursorShape()
}
GetClientRect(wHandle, ByRef xLoc, ByRef yLoc,ByRef rLoc, ByRef bLoc)
{
    global dm
    x1:=ComVar()
    y1:=ComVar()
    x2:=ComVar()
    y2:=ComVar()
    dmRet:=dm.GetClientRect(wHandle,x1.ref,y1.ref,x2.ref,y2.ref)
    xLoc:=x1[]
    yLoc:=y1[]
    rLoc:=x2[]
    bLoc:=y2[]
    return dmRet
}
MoveTo(xLoc,yLoc)
{
    global dm
    dm.MoveTo(xLoc,yLoc)
}
GetCursorPos(xLoc,yLoc)
{
    global dm
    x:=ComVar()
    y:=ComVar()
    dmRet:=dm.GetCursorPos(x.ref,y.ref)
    xLoc:=x[]
    yLoc:=y[]
    return dmRet
}
LeftClick(xLoc,yLoc)
{
    global dm
    MoveTo(xLoc, yLoc)
    Sleep,300
    dm.LeftClick()
}
;这三个键盘操作不好用
KeyDown(keyCode)
{
    global dm
    dm.KeyDownChar(keyCode)
}
KeyPress(keyCode)
{
    global dm
    dm.KeyPressChar(keyCode)
}
KeyUp(keyCode)
{
    global dm
    dm.KeyUpChar(keyCode)
}

; ComVar: 创建用来传递 ByRef 值的对象.
;   ComVar[] 检索值.
;   ComVar[] := Val 设置值.
;   ComVar.ref 检索 ByRef 对象用于传递到 COM 函数.
ComVar(Type=0xC)
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; 创建含 1 个 VARIANT 类型变量的数组.  此方法可以让内部代码处理
    ; 在 VARIANT 和 AutoHotkey 内部类型之间的所有转换.
    arr := ComObjArray(Type, 1)
    ; 锁定数组并检索到 VARIANT 的指针.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; 保存可用于传递 VARIANT ByRef 的数组和对象.
    return { ref: ComObjParameter(0x4000|Type, arr_data), _: arr, base: base }
}
ComVarGet(cv, p*)
{
    ; 当脚本访问未知字段时调用.
    if(p.MaxIndex() = "") ; 没有名称/参数, 即 cv[]
    {
        return cv._[0]
    }
}
ComVarSet(cv, v, p*)
{
    ; 当脚本设置未知字段时调用.
    if(p.MaxIndex() = "") ; 没有名称/参数, 即 cv[]:=v
    {
        return cv._[0] := v
    }
}
ComVarDel(cv)
{
    ; 当对象被释放时调用.
    ; 必须进行这样的处理以释放内部数组.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}

;程序退出时要做的事
;必须以ExitApp作为结束语句. 使用return或者别的结束语句,程序无法退出
ExitScript:
  dm.UnBindWindow()
  RunWait,regsvr32 /u /s "%A_WorkingDir%\dm.dll",,Hide              
  FileDelete,%A_WorkingDir%\dm.dll
  ExitApp
return
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-09-19, 08 : 56 (这个帖子最后修改于: 2014-09-19 08 : 57 by angkevin.)
Wink RE: ahk引入大漠插件dll的某些函数
版主,能否帮我解决一下,后台键盘不好用,我试了几种绑定方式,都不行

使用前台方式,都好用
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-10-16, 22 : 32
RE: ahk引入大漠插件dll的某些函数
@angkevin 把问题细分了来,看你的代码也会云里雾里的..
不过有很多可取的...
另外,不用转换大漠,貌似功能都是系统API,找到相应封装下就好,比如后台热键、找图。

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-11-16, 11 : 41
Wink RE: ahk引入大漠插件dll的某些函数
先谢谢了,对于系统API我没有怎么研究,所以,就没有考虑这方面,不知道有没有AHK的关于调用API的资料,帮助什么的。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
发表回复 


论坛跳转:


联系我们 | Autohotkey 中文站 | 回到顶部 | 回到正文区 | 精简(归档)模式 | RSS 聚合