发表回复 
萝卜 解读下这个函数
2014-09-24, 19 : 59 (这个帖子最后修改于: 2014-09-24 20 : 33 by kongqir.)
萝卜 解读下这个函数
代码: (全选)
#Persistent
CoordMode,ToolTip,Screen
SetTimerF("func",2000,Object(1,1),10) ;create a higher priority timer
SetTimerF("func2",1000,Object(1,2)) ;another timer with low priority
Return
func(p){
   MsgBox % "Timer number: " p
}
func2(p){
   MsgBox % "Timer number: " p
}

Escape::ExitApp

SetTimerF( Function, Period=0, ParmObject=0, Priority=0 ) {
Static current,tmrs:=Object() ;current will hold timer that is currently running
If IsFunc( Function ) {
    if IsObject(tmr:=tmrs[Function]) ;destroy timer before creating a new one
       ret := DllCall( "KillTimer", UInt,0, UInt, tmr.tmr)
       , DllCall("GlobalFree", UInt, tmr.CBA)
       , tmrs.Remove(Function)
    if (Period = 0 || Period ? "off")
       return ret ;Return as we want to turn off timer
     ; create object that will hold information for timer, it will be passed trough A_EventInfo when Timer is launched
    tmr:=tmrs[Function]:=Object("func",Function,"Period",Period="on" ? 250 : Period,"Priority",Priority
                                ,"OneTime",(Period<0),"params",IsObject(ParmObject)?ParmObject:Object()
                                ,"Tick",A_TickCount)
    tmr.CBA := RegisterCallback(A_ThisFunc,"F",4,&tmr)
    return !!(tmr.tmr  := DllCall("SetTimer", UInt,0, UInt,0, UInt
                                , (Period && Period!="On") ? Abs(Period) : (Period := 250)
                                , UInt,tmr.CBA)) ;Create Timer and return true if a timer was created
                , tmr.Tick:=A_TickCount
}
tmr := Object(A_EventInfo) ;A_Event holds object which contains timer information
if IsObject(tmr) {
     DllCall("KillTimer", UInt,0, UInt,tmr.tmr) ;deactivate timer so it does not run again while we are processing the function
     If (!tmr.active && tmr.Priority<(current.priority ? current.priority : 0)) ;Timer with higher priority is already current so return
         Return (tmr.tmr:=DllCall("SetTimer", UInt,0, UInt,0, UInt, 100, UInt,tmr.CBA)) ;call timer again asap
     current:=tmr
     tmr.tick:=ErrorLevel :=Priority ;update tick to launch function on time
     tmr.func(tmr.params*) ;call function
     current= ;reset timer
    if (tmr.OneTime) ;One time timer, deactivate and delete it
       return DllCall("GlobalFree", UInt,tmr.CBA)
                 ,tmrs.Remove(tmr.func)
     tmr.tmr:= DllCall("SetTimer", UInt,0, UInt,0, UInt ;reset timer
                ,((A_TickCount-tmr.Tick) > tmr.Period) ? 0 : (tmr.Period-(A_TickCount-tmr.Tick)), UInt,tmr.CBA)
}
}

我一直找不出 tmr.active 是从哪里冒出来的
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-09-24, 21 : 12 (这个帖子最后修改于: 2014-09-24 21 : 16 by robertL.)
RE: 萝卜 解读下这个函数
  • if (Period = 0 || Period ? "off")这句能运行吗?(V1下跳过,V2下报错)
    感觉是比较早的版本了,旧语法?,都还是通过Object(..)来建立对象的。
  • tmr.active确实没出现过,不过!tmr.active为真,不阻止条件就是。
  • 旧 提到:tmr.tick:=ErrorLevel :=Prioritytmr.active没看懂。Priority是哪来的,已经在回调函数中了,应该没有别的参数,则其值为默认值吧?
    上面这个赋值不会是从左向右的吧?
    在回调函数中,此第四个参数可能为A_TickCount
    Func()中观察ErrorLevel,值应该是A_TickCount
  • RegisterCallback指定函数,传递对象的地址值做参数,需要GlobalFree释放。
    学习了。
  • 使用Win32 SetTimer替代AHK自带SetTimer(串行定时器),通过回调实现并行定时器
  • 参见:SetTimerEx(Period, Func, Params*)(英文官网)

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-09-24, 21 : 31 (这个帖子最后修改于: 2014-09-24 21 : 45 by kongqir.)
RE: 萝卜 解读下这个函数
H测试的时候发现BUG,所以暂时写到这里。

代码: (全选)
#Persistent
FTimer(300, "t",2)
return


FTimer(Period:=0,Function:="",params*){
Static h:=[]
    if A_EventInfo
    {
        f:=Object(A_EventInfo)
        if IsObject(f)
        {
        if (f.Period<0)
            DllCall("KillTimer", UInt,0, UInt,f.ft),DllCall("GlobalFree", UInt,f.rc),h.Remove(f.func)
        func := f.func.(f.params*)
        }

    }
    else
    {
        if IsFunc(Function)
        {
        IsObject(f[Function])?"":f[Function]:=[]
        f:={"func":Function,"Period":Period,"Priority":Priority,"params":params,"Tick":A_TickCount}
        h[Function][&f]:=h[&f]:=f
        f.rc:=RegisterCallback(A_ThisFunc,"F",3,&f)
        f.ft:=DllCall("SetTimer", UInt,0, UInt,0, UInt, Abs(Period),UInt,f.rc)
        return f
        }
    }
}

t(a){
ToolTip,% a
}

我反复记录了 tmr 对象,它甚至一直没有 active 键。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-09-24, 22 : 39
RE: 萝卜 解读下这个函数
本来想加上暂停/开始的,但那样不如直接用类了,反正我用不到。

代码: (全选)
#Persistent
a:=FTimer(100, "t",1)
b:=FTimer(200, "t",2)
FTimer(a, -1000)     ;修改
FTimer(a)         ;结束,并得到定时器期间函数运行所返回的所有结果。
FTimer(a,0)         ;结束所有同一函数的定时(B也会停止),同样得到结果。
return


FTimer(Period:=0,Func:="",params*){
    Static h:=[]
    if A_EventInfo
    {
        f:=Object(A_EventInfo)
        if IsObject(f) and h[&f]
        {
            if (f.Period<0)
                DllCall("KillTimer", UInt,0, UInt,f.ft),DllCall("GlobalFree", UInt,f.rc),h.Remove(&f,"")
            f.results.Insert(f.func.(f.params*))
        }
    }
    else
    {
        if IsObject(f:=Period)
        {
            if Func
            {
                DllCall("KillTimer", UInt,0, UInt,f.ft)
                if (Func="End")
                    return f.results,DllCall("GlobalFree", UInt,f.rc),h.Remove(&f,"")
                else
                    f.ft:=DllCall("SetTimer", UInt,0, UInt,0, UInt, Abs(f.Period:=Func),UInt,f.rc)
            }
            else if (Func=0)
            {
                b:=[]
                for i,n in h
                (n.func=f.func)?b.Insert(FTimer(n,"End")):""
                return b
            }
            else
                return FTimer(f,"End")

        }
        else if IsFunc(Func)
        {
            f:={"func":Func,"Period":Period,"Priority":Priority,"params":params,"Tick":A_TickCount,results:[]}
            h[&f]:=f
            f.rc:=RegisterCallback(A_ThisFunc,"F",3,&f)
            f.ft:=DllCall("SetTimer", UInt,0, UInt,0, UInt, Abs(Period),UInt,f.rc)
            return f
        }
    }
}

t(a){
    ToolTip,% a
}
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢kongqir
2014-09-24, 22 : 50 (这个帖子最后修改于: 2014-09-24 22 : 50 by robertL.)
RE: 萝卜 解读下这个函数
清晰不少,回头再学习..
能独立控制,应该更具灵活性了。

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
发表回复 


论坛跳转:


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