TC官方合作论坛

 找回密码
 立即注册
查看: 24281|回复: 466
打印 上一主题 下一主题

【基础篇】9、2013线程的使用及巧妙设计

  [复制链接]
跳转到指定楼层
楼主
发表于 2012-10-31 11:28:38 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
   在我们学习写脚本的时候必然就离不开线程,因为我们写脚本的目的大部分都是源于替代手工重复的动作,而这些动作会显得比较轻松不会太复杂。那么由于它是一个重复的动作,所以它离不开循环语句的使用,而循环语句的使用又离不开线程,那么我们这一章就学习线程的使用,因为它就是循环语句的开关,有了这个开关我们就可以随时对循环语句进行关闭或者打开,这样就不会造成脚本被关闭了程序还在运行或者游戏奔溃等问题的出现。

  根据上面的介绍,我们可以知道线程用于启动循环的开始和结束,那么我们需要考虑到启动和停止,假如你写的脚本是一个前台的脚本,它完成的是无限循环的为你查看游戏中拍卖的价格,直到价格低于你设置的价格的时候就报警的功能。这个时候如果我们用一个按钮来停止脚本,那么就显得不可行,因为鼠标它一直在为你工作,你现在需要用鼠标去点击停止脚本,肯定会出现当你移动到脚本的停止热键的瞬间鼠标就被很快的移动到了你正在扫物品的地方去了,所以我们考虑到这点,涉及到了前台的脚本我们需要采用热键来启动和停止。那么在这章中,我将教会大家如何使用热键来启动和停止脚本。


第一步、首先我们在TC软件下新建一个项目,在名称处键入线程的使用,然后确定,若按照步骤的话,应该是如下结果:


第二步、这样一个项目就新建好了,下面我们将界面上的开始和退出按钮删除掉,  鼠标选中开始/退出按钮,按下键盘的Del键或者选中右键弹出的页面后点击删除。随后我们将这个页面进行缩小,鼠标放在界面设计的右下角处,这个时候会出现一个斜方向的箭头,然后我们鼠标按下往上拉,界面就被我们缩小了。若按照步骤操作,应该是如下结果:


第三步、在TC软件的右边处点击工具箱,然后找标签,点击标签,然后将鼠标移动到设计界面处再次点击鼠标,这个时候标签就被加入到了界面中,本次我们需要用到2个标签,所以我们以同样的方法再次添加一个标签。添加好了标签之后我们首先选中一个标签,然后右键,会出现一个页面,选择属性,这个时候右边的属性框就被激活,会陈列出该标签的相关属性,这个时候我们在文本处,键入“启动热键:”,然后回车。这个时候标签上就会改为启动热键,但是这个标签尺寸太小,我们选中它将它拉大为适合的宽度。而另外一个标签我们将它以同样的方法键入“停止热键:”。若按照步骤操作,应该是如下结果:



第四步、根据上面的方法,我们在工具箱中找到热键,然后向界面拖入2个热键,分别在启动热键和停止热键的后面。我们随后在其热键的属性中分别更改名称为启动热键和停止热键。在启动热键键值处点击然后按下F9,在停止热键键值处点击然后按下F10。最后我们在其有效处选择false,这样热键框就变成了灰色。若按照步骤操作,应该是如下结果:


第五步、这样我们就将界面做好了,下面我们开始进入代码的编写区,我们在项目的左边,激活项目管理页面,然后找到项目管理-线程的使用展开,然后鼠标双击线程的使用.t这个文件,这个使用我们就进入了代码区域,然后我们将开始函数和退出函数删除,经过整理后,我们在TC软件正上方找到显示主窗口按钮,然后点击,这是我们来了我们设计的界面上,选中热键按键,激活它的属性页面,随之我们点击属性页面的事件下的热键,然后添加<线程的使用>,这样启动热键的函数就被我们添加到了代码区域中,我们以同样的方法进行添加停止函数到代码中,请在页面上添加这2个函数,切勿自动编写这2个函数,否则他们就不起任何作用无法达成与界面的热键产生关联。若按照步骤操作,应该是如下结果:


第六步、因为有的时候我们可能会意外的关闭程序,比如不小心 file:///C:/Users/DELL/AppData/Local/Temp/SGTpbq/3172/00B50715.png 掉了程序,所以我们应该加入一个销毁事件, 点击显示主窗口,然后点击界面设计的空白处,这个时候右边的属性事件处会出现初始化、销毁、窗口关闭,这里我们只需要用到销毁函数,所以直接将销毁这个函数添加入代码中。若按照步骤操作,应该是如下结果:


第七步、前提步骤我们做好了,下面我们开始编写代码。因为这次主要是为了学习线程的使用,所以我们就编写一个比较简单的功能,实现锁鼠标。
首先我们知道启动热键函数和停止热键函数、销毁函数都是独立的函数,但是他们会共用到一个线程句柄,为什么这么说呢,我们在帮助文档中找到,线程开启和线程关闭的函数说明,上面说明了线程的开启需要一个线程的句柄来接受它,而线程的关闭正好就用到了这个线程句柄,但是他们不在一个函数中,那么我们就应该知道这个线程句柄必须是全局的变量,自然而然我们在启动热键函数的外面定义一个整型的线程句柄,为什么是整型,我们可以根据线程开启这个命令的数据类型决定,它返回的是整型,根据上一章中说到了数据类型配对问题我们知道是整型的。然后我们找到线程开启这个命令,查看它的命令说明:

中文函数原型: 整型 开启(字符型 funcname,字符型 param)
英文函数原型: int beginthread(string funcname, string param)
参数:
funcname: 函数名的字符串(当前程序空间名 + 函数名)
param: 线程传参,如果不需要参数,可填空字符串
返回值: 函数执行成功,返回线程句柄,否则为0
从说明中我们得知它里面有2个参数,一个是函数名的字符串一个是传递的参数,那么我们下面应该编写一个自己定义的函数来给它使用,那么这个自定义的函数就应该写我们要锁鼠标的内容。所以我们在启动热键函数的前面定义一个函数,这个函数为返回值为逻辑型的锁鼠标命名的函数。然后我们在锁鼠标里面编写上代码。因为锁鼠标的原理就是将该鼠标不停的至于一个点上,无法对它进行移动。那么它需要用到一个循环语句,这个循环语句是一个死循环,没有任何条件让它跳出,直到你线程关闭它才会停止。然后我们就在启动热键中线程开启的参数加入该名称,因为是在本空间没有任何跨空间,所以用线程的使用点上这个函数名。而后面的那个参数我们没有用到所以为空字符。并且用线程句柄来接受它。若按照步骤操作,应该是如下结果:



第八步、我们一个线程的打开已经做好了,这个时候我们还不能直接生成EXE使用,因为我们只做了打开还没有对它进行关闭,所以下面我们将进行线程的关闭操作,我们在停止热键函数中添加上线程关闭的函数,并弹出消息框提示线程已经关闭。而在销毁函数中我们只需要添加线程关闭即可。若按照步骤操作,应该是如下结果:



第九步、到了这一步很多人,都认为是大功告成了,编译生成后就可以使用了。是的到了这一步的确点击生成后,在TC软件正上方找到打开这个按钮,打开之后我们就可以使用这个EXE了,但是我却认为它还有一些毛病,假设,我在按热键的时候不小心按了2次或者3次,那么是不是就开始了2个或者更多个线程呢?虽然我们可以多按几次来关闭这个线程,但是对于客户可能就不知道,他认为程序为什么不会停止,我们明明按了停止啊!面对这个问题,我们在这里应该得到一个合理的解决方案。
我们在每次开启线程之前加入一个判断语句,因为我们定义线程句柄的时候是为0,而当我们开启了线程之后线程句柄肯定不为0,那么我们就根据这个做出相应的解决方。而停止和销毁也同样进行处理。这样一个完美的程序就可以正常运行了。若按照步骤操作,应该是如下结果:


源码及项目下载需回复可见:
游客,如果您要查看本帖隐藏内容请回复

总结:根据以上的代码,大家可以思考一下,我为什么要这样写,这样写有什么好处,对于以后大家写脚本很有帮助。不在为线程关闭不了或者线程开启多个而没有进行提示烦恼。
更新完毕!


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

468#
发表于 2018-1-27 20:40:49 | 只看该作者
6666666666666
回复 支持 反对

使用道具 举报

467#
发表于 2018-1-26 22:43:38 | 只看该作者
tyrteyyert
回复 支持 反对

使用道具 举报

466#
发表于 2017-10-27 20:51:46 | 只看该作者
调用:
功能 初始化()
    //------第一步:初始化注册插件
    // 首先打包dm.dll和RegDll.dll到附件,当然如果你还有其它资源(字库,图片等)也可以一并打包
    // 这个 插件版本 作为本脚本需要使用的插件版本. 如果要换插件时,记得更改这个值.
    插件版本 = "3.1233"
    dm=大漠多开单停.注册大漠插件(辅助.获取资源路径("rc:"),插件版本)
    ver = dm.Ver()
    调试输出(ver)
功能结束
源码:

//一个标准的注册大漠插件的例子
功能 注册大漠插件(插件路径,插件版本)
   
    // 插件需要用到atl系统库,有些XP精简系统会把atl.dll精简掉. 为了防止注册失败,这里手动注册一下atl.dll
    //ws=com("Wscript.Shell")
    //ws.run("regsvr32 atl.dll /s")
    //ws=null
    //上面的代码在TC里面调用貌似没什么反应 所以我们更改为下面代码
    辅助.命令("regsvr32 atl.dll /s",false)
   
    // 插件注册开始>>>>>>>>>>>>>>>>>>>
    // 下面开始注册插件,先尝试用TC来注册.这里注意请勿把dm.dll释放在系统目录.以免造成版本错误.
    辅助.注册插件(插件路径&"dm.dll",真)
   
    // 这里判断是否注册成功
    dm=com("dm.dmsoft")
    如果(类型.获得类型(dm)!="插件")
        dm = null
        //如果上面的方法注册失败那么使用下面的方法进行注册
        //再尝试用regsvr32 来注册. 这里注意请勿把dm.dll释放在系统目录.以免造成版本错误.
        //ws=com("Wscript.Shell")
        //ws.run("regsvr32 "&插件路径&"dm.dll /s")
        //ws=null
        
        //同样的 上面的代码木有反应我们改成下面的代码进行注册
        是否成功=辅助.命令("regsvr32 "&插件路径&"dm.dll",false)
        辅助.等待(500)
        辅助.命令("taskkill /f /im regsvr32.exe",false)//注册成功后会弹出一个对话框,为了不影响后面的操作 我们直接调用命令结束掉这个对话框
    如果结束
   
    // 再判断插件是否注册成功
    dm=com("dm.dmsoft")
    如果(类型.获得类型(dm)=="插件")
        ver = dm.Ver()
        如果(ver != 插件版本)
            //这时,已经确认插件注册失败了。 弹出一些调试信息,以供分析.
            辅助.消息框("插件版本错误,当前使用的版本是:"&ver&",插件所在目录是:"&dm.GetBasePath()&"\n请关闭程序,重新打开本程序再尝试")
            辅助.退出()
        否则
            //注册成功 并且版本 匹配 返回大漠插件对象
            返回 dm
        如果结束
    否则
        辅助.消息框("插件注册失败,重新打开本程序再尝试")
        辅助.退出()
    如果结束
功能结束
回复 支持 反对

使用道具 举报

465#
发表于 2016-10-16 20:04:17 | 只看该作者
学习一下。
回复

使用道具 举报

464#
发表于 2016-9-12 13:54:38 来自手机 | 只看该作者
求看隐藏内容,谢谢
回复 支持 反对

使用道具 举报

463#
发表于 2016-9-3 14:32:23 | 只看该作者
看看
回复

使用道具 举报

462#
发表于 2016-5-29 00:24:13 | 只看该作者
们在每次开启线程之前加入一个判断语句,因为我们定义线程句柄的时候是为0,而当我们开启了线程之后线程句柄肯定不为0,那么我们就根据这个做出相应的解决方。而停止和销毁也同样进行处理。这样一个完美的程序就可以正常运行了。若按照步骤操作,应该是如下结果:
回复 支持 反对

使用道具 举报

461#
发表于 2015-6-30 20:58:38 | 只看该作者
学习学习哈
回复 支持 反对

使用道具 举报

460#
发表于 2015-6-30 16:03:45 | 只看该作者
地地道道的
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18043773号

GMT+8, 2025-9-19 06:51 , Processed in 0.330748 second(s), 23 queries .

Powered by 海安天坑软件科技有限公司

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表