跳到主要内容

如何在多线程下使用

多线程下使用插件是一个很复杂的问题.

一般来说使用多线程的目的,有2种目的。

情况1 用多个线程控制多个窗口的脚本运行(最常见的情况,通常用于多开).

情况2 用多个线程控制同一个窗口的脚本运行(通常用于监控信息,比如验证信息,或其他一些突发性的情况).

下面就对上面列出的各种情况,讲解如何在这些情况下,使用大漠插件

一 按键的多线程 (示例代码可以参考这里)

情况1

  1. 这种情况是最常见的情况,用大漠插件不用特别注意什么,每个窗口对应绑定一个大漠对象即可.
  2. 这种情况下用多线程,其实和按键的重复多开一样的效果。

情况2

  1. 这种情况就比较特殊了。要支持这种情况,必须使用插件(2.1117之后的版本).

  2. 每个线程中,还是创建一个大漠对象,并绑定同一个窗口. 另外,特别要注意,绑定的同个窗口的绑定模式必须完全一样。第一个绑定的大漠对象称做主绑定,后面的都叫做副绑定,副绑定不用解绑也可以,但是一旦主绑定接绑,那么所有的绑定都会失效.

  3. 这种模式下,还有个问题要注意,因为毕竟是多线程,键鼠的操作都是异步的,那么很可能出现键鼠在多个线程中冲突的可能,这个问题没法解决,多线程势必会有这样的问题。只能建议少在子线程中做键鼠的操作.

  4. 另外要注意的是,子线程的绑定操作一定要在主线程之后,也就是说BeginThread的调用一定要在主线程的BindWindow或者BindWindowEx之后进行.

二 其他高级语言的多线程 (高级语言模版大漠插件网站有下载)

首先,要注意的是,大漠插件是支持com的STA和MTA线程模型,高级语言中使用大漠插件,建议使用MTA模型。这样效率最高. 当然,STA也可以,但会限制插件的函数调用都在一个线程套间内,会影响效率.

情况1

  1. 这种情况是最常见的情况,用大漠插件不用特别注意什么,每个窗口对应绑定一个大漠对象即可.

情况2

  1. 这种情况就比较特殊了。要支持这种情况,必须使用插件(2.1117之后的版本).

  2. 每个线程中,还是创建一个大漠对象,并绑定同一个窗口. 另外,特别要注意,绑定的同个窗口的绑定模式必须完全一样。第一个绑定的大漠对象称做主绑定,后面的都叫做副绑定,副绑定不用解绑也可以,但是一旦主绑定接绑,那么所有的绑定都会失效..

  3. 这种模式下,还有个问题要注意,因为毕竟是多线程,键鼠的操作都是异步的,那么很可能出现键鼠在多个线程中冲突的可能,这个问题没法解决,多线程势必会有这样的问题。只能建议少在子线程中做键鼠的操作.

  4. 另外,子线程在绑定时,一定要等到主线程绑定结束之后,再执行绑定,否则会引发不可预知的异常.

比如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,否则函数调用会异常.