退出时自动执行代码

许多实用脚本和封装函数, 可以让您编写脚本更加便捷高效

Moderators: tmplinshi, arcticir

tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

退出时自动执行代码

10 Sep 2014, 13:13

OnExitF() 中学到的。

方法一:

Code: Select all

OnExit() {
	static handler := {__Delete: "OnExit"}
	static _ := new handler
	MsgBox, bye
}

MsgBox, hi
方法二:

Code: Select all

class test
{
	__Delete() {
		static _ := new test
		MsgBox, bye
	}
}

MsgBox, hi
退出时自动执行代码有什么用呢?其中一个用处是自动释放DLL,示例:

Code: Select all

; xd2txlib.dll 下载地址: http://www31.ocn.ne.jp/~h_ishida/xdoc2txt.html

MsgBox, % xdoc2txt("test.doc")

xdoc2txt(fileName) {
	; 脚本启动时自动载入 dll
	static hModule := DllCall("LoadLibrary", "Str", "xd2txlib.dll")

	; 脚本退出时自动释放 dll
	static handler := {__Delete: "xdoc2txt"}
	static _______ := new handler
	If A_ExitReason {
		DllCall("FreeLibrary", "Ptr", hModule)
		Return
	}

	; 这里是函数的功能代码
	fileLength := DllCall("xd2txlib\ExtractText", "Str", fileName, "Int", False, "Int*", fileText)
    Return StrGet( fileText, fileLength / 2 )
}
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: 退出时自动执行代码

03 Oct 2014, 10:22

可以:(不用实例化,也无类概念,只要是对象就行)

Code: Select all

OnExit() {
    static _ := {base:{__Delete: "OnExit"}}
    MsgBox, bye
}
MsgBox, hi
ExitApp
A_ExitReason是个判断的好方法。
我为人人,人人为己?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

03 Oct 2014, 10:23

学到了,多谢 :mrgreen:
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: 退出时自动执行代码

03 Oct 2014, 10:26

A_ExitReason wrote:除非脚本含有 OnExit 子程序并且此子程序当前正在运行被退出尝试至少调用过一次, 否则此变量为.
还是不明白上面的条件...怕A_ExitReason失效了..
我为人人,人人为己?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

03 Oct 2014, 10:52

运行良好
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

03 Oct 2014, 11:47

发现这样也可以:

Code: Select all

test() {
	static _ := { base: {__Delete: "test"} }
	If !IsObject(_) {
		MsgBox, bye
		Return
	}

	MsgBox, % IsObject(_)
}

test()
ExitApp
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: 退出方法

04 Oct 2014, 09:37

A_ExitReason不够可靠。
有,被退出尝试至少调用过一次,则A_ExitReason有效,若作为条件会导致释放,即便退出被取消。
以下会造成两次释放,因为第一次退出被取消。

Code: Select all

SetTimer,T,1000
OnExit,L
return
T:
    x()
    ExitApp
L:
    if(!i){
        i:=true
        return
    }else
        ExitApp
x() {
    static _ := {base:{__Delete: "x"}}
	if(A_ExitReason)
		MsgBox, bye
}
!IsObject(_)最可靠,说明被真正释放了。
考虑(每次调用函数IsObject的)效率,可以:

Code: Select all

x(p:="") {
    static _ := {base:{__Delete: "x"}}
	if(!_)
		MsgBox Release
}
我为人人,人人为己?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

04 Oct 2014, 09:48

你成功的证实了 A_ExitReason不够可靠...那我也用 !IsObject(_)。3q!
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出方法

04 Oct 2014, 09:51

RobertL wrote: 考虑(每次调用函数IsObject的)效率,可以:

Code: Select all

x(p:="") {
    static _ := {base:{__Delete: "x"}}
	if(!_)
		MsgBox Release
}
不可以吧,对象不会返回一个值。
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: 退出时自动执行代码

04 Oct 2014, 10:02

你试试...
!IsObject中他不是对象是什么?是空字符串了 。
Last edited by RobertL on 04 Oct 2014, 22:00, edited 1 time in total.
我为人人,人人为己?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

04 Oct 2014, 10:05

试过的,对象不会返回一个值。

Code: Select all

obj := {}
MsgBox, % obj
用 QPX 测试了下 IsObject,并没有效率问题。判断一次 IsObject,耗时千分之6毫秒(离 1 毫秒还差千分之 994 毫秒)。

Code: Select all

_ := {}

QPX( True )
	IsObject(_)
T1 := QPX( False ) ; 0.000006

QPX( True )
	str := "test"
T2 := QPX( False ) ; 0.000003

MsgBox, % T1 "`n" T2

QPX( N=0 ) { ; Wrapper for QueryPerformanceCounter()by SKAN | CD: 06/Dec/2009
	Static F,A,Q,P,X ; www.autohotkey.com/forum/viewtopic.php?t=52083 | LM: 10/Dec/2009
	If	( N && !P )
		Return	DllCall("QueryPerformanceFrequency",Int64P,F) + (X:=A:=0) + DllCall("QueryPerformanceCounter",Int64P,P)
	DllCall("QueryPerformanceCounter",Int64P,Q), A:=A+Q-P, P:=Q, X:=X+1
	Return	( N && X=N ) ? (X:=X-1)<<64 : ( N=0 && (R:=A/X/F) ) ? ( R + (A:=P:=X:=0) ) : 1
}
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 退出时自动执行代码

04 Oct 2014, 10:13

额,你是对的...

Code: Select all

_ := {base:{__Delete: "x"}}
If !_
	MsgBox, Release
Else
	MsgBox, hi

MsgBox, % _
Return
好神奇,MsgBox, % _显示是空的,但用 If _ 判断却是成立的。。
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: 退出时自动执行代码

04 Oct 2014, 22:00

tmplinshi wrote:IsObject,并没有效率问题
我指相对效率。以上测试中,IsObject(_)!_能差近1倍。

对象作为布尔值总是为真。

函数QPX不错,收下了。
我为人人,人人为己?
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

初始化 & 释放

06 Oct 2014, 08:29

写了个示例,有助于理解静态声明的静态变量的初始化及退出过程中释放的顺序。

Code: Select all

base:={__New:Func("f"),__Delete:Func("f")}
global g1:=new base("g1")
global g2:=new base("g2")
ExitApp
f(this,s:=""){
    static base:={__New:Func("f"),__Delete:Func("f")}
    static s1:=new base("s1")
    static s2:=new base("s2")
    if(s)
        this.s:=s
    MsgBox % 
        (Join
            (s?"New":"Delete") ":" this.s ".`n" 
            (A_ExitReason?"A_ExitReason:" A_ExitReason "`n":"")
            s1.s "," s2.s "," g1.s "," g2.s "."    
        )
    ;    New:s1→s2→g1→g2
    ;    Delete:g1→g2→s1→s2
}
出自:于类初始化时执行函数 - 代码初始化顺序(AHK8,帖子不完善..)
我为人人,人人为己?

Return to “脚本函数”

Who is online

Users browsing this forum: No registered users and 50 guests