如何在多线程下使用
多线程下使用插件是一个很复杂的问题.
一般来说使用多线程的目的,有2种目的。
情况1 用多个线程控制多个窗口的脚本运行(最常见的情况,通常用于多开).
情况2 用多个线程控制同一个窗口的脚本运行(通常用于 监控信息,比如验证信息,或其他一些突发性的情况).
下面就对上面列出的各种情况,讲解如何在这些情况下,使用大漠插件
一 按键的多线程 (示例代码可以参考这里)
情况1
- 这种情况是最常见的情况,用大漠插件不用特别注意什么,每个窗口对应绑定一个大漠对象即可.
- 这种情况下用多线程,其实和按键的重复多开一样的效果。
情况2
-
这种情况就比较特殊了。要支持这种情况,必须使用插件(2.1117之后的版本).
-
每个线程中,还是创建一个大漠对象,并绑定同一个窗口. 另外,特别要注意,绑定的同个窗口的绑定模式必须完全一样。第一个绑定的大漠对象称做主绑定,后面的都叫做副绑定,副绑定不用解绑也可以,但是一旦主绑定接绑,那么所有的绑定都会失效.
-
这种模式下,还有个问题要注意,因为毕竟是多线程,键鼠的操作都是异步的,那么很可能出现键鼠在多个线程中冲突的可能,这个问题没法解决,多线程势必会有这样的问题。只能建议少在子线程中做键鼠的操作.
-
另外要注意的是,子线程的绑定操作一定要在主线程之后,也就是说BeginThread的调用一定要在主线程的BindWindow或者BindWindowEx之后进行.
二 其他高级语言的多线程 (高级语言模版大漠插件网站有下载)
首先,要注意的是,大漠插件是支持com的STA和MTA线程模型,高级语言中使用大漠插件,建议使用MTA模型。这样效率最高. 当然,STA也可以,但会限制插件的函数调用都在一个线程套间内,会影响效率.
情况1
- 这种情况是最常见的情况,用大漠插件不用特别注意什么,每个窗口对应绑定一个大 漠对象即可.
情况2
-
这种情况就比较特殊了。要支持这种情况,必须使用插件(2.1117之后的版本).
-
每个线程中,还是创建一个大漠对象,并绑定同一个窗口. 另外,特别要注意,绑定的同个窗口的绑定模式必须完全一样。第一个绑定的大漠对象称做主绑定,后面的都叫做副绑定,副绑定不用解绑也可以,但是一旦主绑定接绑,那么所有的绑定都会失效..
-
这种模式下,还有个问题要注意,因为毕竟是多线程,键鼠的操作都是异步的,那么很可能出现键鼠在多个线程中冲突的可能,这个问题没法解决,多线程势必会有这样的问题。只能建议少在子线程中做键鼠的操作.
-
另外,子线程在绑定时,一定要等到主线程绑定结束之后,再执行绑定,否则会引发不可预知的异常.
比如vc如何设置当前线程模型为MTA,只要在线程开始调用CoInitializeEx(NULL,0)
一次即可. 其他语言可能略有不同.
下面是一个按键8,使用大漠多线程的一个例子,必须使用大漠插件v2.1129之后的版本
Set dm = createobject("dm.dmsoft")
TracePrint dm.Ver()
DimEnv hwnd
hwnd = dm.GetMousePointWindow()
// 主绑定一定要先绑定,后启动线程
dm_ret = dm.BindWindow(hwnd,"dx","dx","dx",0)
TracePrint dm_ret
// 开启3个线程
BeginThread 线程函数()
BeginThread 线程函数()
BeginThread 线程函数()
Do
// 这里做主线程的事情
Delay 1000
Loop
Sub OnScriptExit()
// 这句只会在主线程结束时被调用到
dm_ret = dm.UnBindWindow()
End Sub
Sub 线程函数()
Set dm = createobject("dm.dmsoft")
dm_ret = dm.BindWindow(hwnd,"dx","dx","dx",0)
TracePrint "线程绑定结果:"&dm_ret
Do
// 这里做线程里需要做的事情
Delay 1000
Loop
End Sub
注意,mta版本的COM组件初始化,必须使用CoInitializeEx
函数,参数必须是两个0
sta版本的COM组件初始化,必须使用CoInitialize
函数,参数是一个0.
每个线程开头,都必须要初始化COM,否则函数调用会异常.