用按键精灵点一点怎么用Begin Thread多线程,线程里有很多子程序,调试就会有子程序找不到目标,什么原因

按键精灵如何通过一个多选框启动关闭一个多线程中的一个单线程_百度知道
按键精灵如何通过一个多选框启动关闭一个多线程中的一个单线程
RT意思,希望在界面中勾选多选框来开启和关闭某个线程,往大神告知如何处理这样的问题框体Form1多选框1CheckBox1多选框2CheckBox2BeginThreadADelay10BeginThreadBSubA()Whiletrue//按...
RT 意思,希望在界面中勾选多选框来开启和关闭某个线程,往大神告知如何处理这样的问题框体 Form1 多选框1 CheckBox1 多选框2 CheckBox2BeginThread ADelay 10BeginThread BSub A()While true//按e
5秒KeyPress &E&, 1For 10Delay 500NextWendEnd SubSub B()While true//按Q 0.1秒KeyPress &Q&, 1For 10Delay 10NextWendEnd Sub
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
<span class="wgt-replyer-all-uname
" data-href="https://zhidao.baidu.com/usercenter?uid=cbd05e6916486
<span class="wgt-replyer-all-card-name3 wgt-replyer-all-card-names" data-href="https://zhidao.baidu.com/usercenter?uid=cbd05e6916486
采纳数:3718
获赞数:7778
擅长:暂未定制
代码如下:Event Form1.CheckBox1.Click
If KeyPressE = && And Form1.CheckBox1.Value = 1 Then
KeyPressE = BeginThread(KeyPressKey(69, 5000)) Else
StopThread KeyPressE
KeyPressE = && End IfEnd EventEvent Form1.CheckBox2.Click
If KeyPressQ = && And Form1.CheckBox2.Value = 1 Then
KeyPressQ = BeginThread(KeyPressKey(81, 100)) Else
StopThread KeyPressQ
KeyPressQ = && End IfEnd EventSub KeyPressKey(Key, t) While True
KeyPress Key, 1
Delay t WendEnd Sub
之前我少复制一部分,完整复制之后 导出试运行发现一个问题,在我勾选之后,按F10启动 并不能按q和e 必须在F10启动后勾选多选框才能自动按键这并不是我要的效果,我需要是在启动前勾选好,而且好像你把我代码改的有点多,我这个初学者理解起来实在困难
DimEnv Start& //定义环境变量,判断是否按F10启动Dimenv ID1, ID2& //线程ID变量//界面还要放一个定时器,用于控制线程//界面载人事件,初始化环境变量Event Form1.LoadOver&Start = 0&ID1 = 0&ID2 = 0&Form1.Timer1.Enabled = 1&& //定时器是启动状态&&&& Form1.Timer1.Interval = 50&&& //设置定时器循环的间隔时间(单位:毫秒)&&End Event//定义按键进行Sub KeyPressKey(Key, t)&While True&&KeyPress Key, 1&&Delay t&WendEnd Sub&//定时器控件线程Event Form1.Timer1.Timer&If ID1 = 0 And Form1.CheckBox1.Value = 1 And Start = 1 Then&&ID1 = BeginThread(KeyPressKey(69, 5000))&End If&If Form1.CheckBox1.Value = 0 Or Start = 0 Then&&StopThread ID1&&ID1 = 0&End If&If ID2 = 0 And Form1.CheckBox2.Value = 1 And Start = 1 Then&&ID2 = BeginThread(KeyPressKey(81, 100))&End If&If Form1.CheckBox2.Value = 0 Or Start = 0 Then&&StopThread ID2&&ID2 = 0&End IfEnd Event//主程序(F10按下后执行的代码)Start = 1//下面写你要执行的其他代码//这一段代码是防止脚本结束使Start = 0而停止线程While True&Delay 1000Wend//程序结束前(按F12后执行的)代码Sub OnScriptExit()&&& Start = 0End Sub当然,有更简单的方法,但都不需要按F10的,你这里非要求按F10,那就没办法了
大哥非常感谢您耐心的解答,怪我之前叙述不明。目的确实是需要通过勾选多选框之后,再通过F10启动我并不是说你代码不好,只是因为实在是初学者,不太能理解您之前的代码,在此非常感谢你
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个结构体,传递给子线程,然后释放的工作交给了子线程,这样不可避免会有内存泄漏的危险,例如线程关闭的问题,我们一般用WaitForSingleObject来完成线程关闭工作,但是这个函数并不一定保证线程能收到要关闭的信号,这样父亲已经退出工作了,子线程还在工作,程序也会有潜在的危险。
所以我已经慢慢不再用这套线程机制了,boost标准stl库的出现,让我眼前一亮,boost所推行的简洁代码概念和模板概念,让我有了清风扑面的感觉,本文将介绍如何使用boost::thread来取代不太安全的MFC线程编程。
本文所牵涉到的源码下载地址:
/source/618903
基础篇主要是汇集和转载一些已有网文,让初学者入门boost::thread.
一. 安装 原地址
1.下载boost_1_34_1压缩文件,解压缩到d:/boost_1_34_1/目录下
  2.编译bjam
  从vs2005的工具菜单进入命令提示窗口(一定要从这进),cd到d:/boost_1_34_1/tools/jam/src下执行build.bat,会在d:/boost_1_34_1/tools/jam/src/bin.ntx86/產生bjam.exe,將bjam.exe複製到d:/boost_1_34_1/下。
  3.设定编译环境
  修改user-config.jam (d:/boost_1_34_1/tools/build/v2/user-config.jam) 的MSVC configuration
  # MSVC configuration
  # Configure msvc (default version, searched in standard location
  # and PATH).
  using msvc : 8.0 : : &compileflags&/wd4819 &compileflags&/D_CRT_SECURE_NO_DEPRECATE &compileflags&/D_SCL_SECURE_NO_DEPRECATE &compileflags&/D_SECURE_SCL=0 ;
  4.编译boost
  將目錄移至d:/boost_1_34_1/下執行
   bjam --without-python --toolset=msvc-8.0 --prefix=d:/boost install
  參數說明
  --without-python 表示不使用 python
  --toolset : 所使用compiler,Visual Studio 2005為msvc-8.0
  --prefix:指定編譯後library的安裝目錄
  这一步要花很长时间(大约50分钟)
  5.设定vs2005环境
  Tools -& Options -& Projects and Solutions -& VC++ Directories
  在Library files加上d:/boost/lib
  在Include files加上d:/boost/include/boost-1_34_1
二.boost::thread入门 原文
1 创建线程
就像std::fstream类就代表一个文件一样,boost::thread类就代表一个可执行的线程。缺省构造函数创建一个代表当前执行线程的实例。一个重载的构造函数以一个不需任何参数的函数对象作为参数,并且没有返回值。这个构造函数创建一个新的可执行线程,它调用了那个函数对象。
起先,大家认为传统C创建线程的方法似乎比这样的设计更有用,因为C创建线程的时候会传入一个void*指针,通过这种方法就可以传入数据。然而,由于Boost线程库是使用函数对象来代替函数指针,那么函数对象本身就可以携带线程所需的数据。这种方法更具灵活性,也是类型安全(type-safe)的。当和Boost.Bind这样的功能库一起使用时,这样的方法就可以让你传递任意数量的数据给新建的线程。
目前,由Boost线程库创建的线程对象功能还不是很强大。事实上它只能做两项操作。线程对象可以方便使用==和!=进行比较来确定它们是否是代表同一个线程;你还可以调用boost::thread::join来等待线程执行完毕。其他一些线程库可以让你对线程做一些其他操作(比如设置优先级,甚至是取消线程)。然而,由于要在普遍适用(portable)的接口中加入这些操作不是简单的事,目前仍在讨论如何将这些操组加入到Boost线程库中。
Listing1展示了boost::thread类的一个最简单的用法。 新建的线程只是简单的在std::out上打印“hello,world”,main函数在它执行完毕之后结束。
#include &boost/thread/thread.hpp&
#include &iostream&
void hello()
std::cout &&
"Hello world, I'm a thread!"
int main(int argc, char* argv[])
boost::thread thrd(&hello);
thrd.join();
任何写过多线程程序的人都知道避免不同线程同时访问共享区域的重要性。如果一个线程要改变共享区域中某个数据,而与此同时另一线程正在读这个数据,那么结果将是未定义的。为了避免这种情况的发生就要使用一些特殊的原始类型和操作。其中最基本的就是互斥体(mutex,mutual exclusion的缩写)。一个互斥体一次只允许一个线程访问共享区。当一个线程想要访问共享区时,首先要做的就是锁住(lock)互斥体。如果其他的线程已经锁住了互斥体,那么就必须先等那个线程将互斥体解锁,这样就保证了同一时刻只有一个线程能访问共享区域。
互斥体的概念有不少变种。Boost线程库支持两大类互斥体,包括简单互斥体(simple mutex)和递归互斥体(recursive mutex)。如果同一个线程对互斥体上了两次锁,就会发生死锁(deadlock),也就是说所有的等待解锁的线程将一直等下去。有了递归互斥体,单个线程就可以对互斥体多次上锁,当然也必须解锁同样次数来保证其他线程可以对这个互斥体上锁。
在这两大类互斥体中,对于线程如何上锁还有多个变种。一个线程可以有三种方法来对一个互斥体加锁:
一直等到没有其他线程对互斥体加锁。如果有其他互斥体已经对互斥体加锁就立即返回。一直等到没有其他线程互斥体加锁,直到超时。似乎最佳的互斥体类型是递归互斥体,它可以使用所有三种上锁形式。然而每一个变种都是有代价的。所以Boost线程库允许你根据不同的需要使用最有效率的互斥体类型。Boost线程库提供了6中互斥体类型,下面是按照效率进行排序:
boost::mutex,
boost::try_mutex,
boost::timed_mutex,
boost::recursive_mutex,
boost::recursive_try_mutex,
boost::recursive_timed_mutex
如果互斥体上锁之后没有解锁就会发生死锁。这是一个很普遍的错误,Boost线程库就是要将其变成不可能(至少时很困难)。直接对互斥体上锁和解锁对于Boost线程库的用户来说是不可能的。mutex类通过teypdef定义在RAII中实现的类型来实现互斥体的上锁和解锁。这也就是大家知道的Scope Lock模式。为了构造这些类型,要传入一个互斥体的引用。构造函数对互斥体加锁,析构函数对互斥体解锁。C++保证了析构函数一定会被调用,所以即使是有异常抛出,互斥体也总是会被正确的解锁。
这种方法保证正确的使用互斥体。然而,有一点必须注意:尽管Scope Lock模式可以保证互斥体被解锁,但是它并没有保证在异常抛出之后贡献资源仍是可用的。所以就像执行单线程程序一样,必须保证异常不会导致程序状态异常。另外,这个已经上锁的对象不能传递给另一个线程,因为它们维护的状态并没有禁止这样做。
List2给出了一个使用boost::mutex的最简单的例子。例子中共创建了两个新的线程,每个线程都有10次循环,在std::cout上打印出线程id和当前循环的次数,而main函数等待这两个线程执行完才结束。std::cout就是共享资源,所以每一个线程都使用一个全局互斥体来保证同时只有一个线程能向它写入。
许多读者可能已经注意到List2中传递数据给线程还必须的手工写一个函数。尽管这个例子很简单,如果每一次都要写这样的代码实在是让人厌烦的事。别急,有一种简单的解决办法。函数库允许你通过将另一个函数绑定,并传入调用时需要的数据来创建一个新的函数。 List3向你展示了如何使用Boost.Bind库来简化List2中的代码,这样就不必手工写这些函数对象了。
#include &boost/thread/thread.hpp&
#include &boost/thread/mutex.hpp&
#include &iostream&
boost::mutex io_
struct count
count(int id) : id(id) { }
void operator()()
for (int i = 0; i & 10; ++i)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout && id && ": "
&& i && std::
int main(int argc, char* argv[])
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();
除了使用Boost.Bind来简化创建线程携带数据,避免使用函数对象
#include &boost/thread/thread.hpp&
#include &boost/thread/mutex.hpp&
#include &boost/bind.hpp&
#include &iostream&
boost::mutex io_
void count(int id)
for (int i = 0; i & 10; ++i)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout && id && ": " &&
i && std::
int main(int argc, char* argv[])
boost::thread thrd1(
boost::bind(&count, 1));
boost::thread thrd2(
boost::bind(&count, 2));
thrd1.join();
thrd2.join();
3 条件变量
有的时候仅仅依靠锁住共享资源来使用它是不够的。有时候共享资源只有某些状态的时候才能够使用。比方说,某个线程如果要从堆栈中读取数据,那么如果栈中没有数据就必须等待数据被压栈。这种情况下的同步使用互斥体是不够的。另一种同步的方式--条件变量,就可以使用在这种情况下。
条件变量的使用总是和互斥体及共享资源联系在一起的。线程首先锁住互斥体,然后检验共享资源的状态是否处于可使用的状态。如果不是,那么线程就要等待条件变量。要指向这样的操作就必须在等待的时候将互斥体解锁,以便其他线程可以访问共享资源并改变其状态。它还得保证从等到得线程返回时互斥体是被上锁得。当另一个线程改变了共享资源的状态时,它就要通知正在等待条件变量得线程,并将之返回等待的线程。
List4是一个使用了boost::condition的简单例子。有一个实现了有界缓存区的类和一个固定大小的先进先出的容器。由于使用了互斥体boost::mutex,这个缓存区是线程安全的。put和get使用条件变量来保证线程等待完成操作所必须的状态。有两个线程被创建,一个在buffer中放入100个整数,另一个将它们从buffer中取出。这个有界的缓存一次只能存放10个整数,所以这两个线程必须周期性的等待另一个线程。为了验证这一点,put和get在std::cout中输出诊断语句。最后,当两个线程结束后,main函数也就执行完毕了。
#include &boost/thread/thread.hpp&
#include &boost/thread/mutex.hpp&
#include &boost/thread/condition.hpp&
#include &iostream&
const int BUF_SIZE = 10;
const int ITERS = 100;
boost::mutex io_
class buffer
typedef boost::mutex::scoped_lock
: p(0), c(0), full(0)
void put(int m)
scoped_lock lock(mutex);
if (full == BUF_SIZE)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout &&
"Buffer is full. Waiting..."
while (full == BUF_SIZE)
cond.wait(lock);
p = (p+1) % BUF_SIZE;
cond.notify_one();
scoped_lock lk(mutex);
if (full == 0)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout &&
"Buffer is empty. Waiting..."
while (full == 0)
cond.wait(lk);
int i = buf[c];
c = (c+1) % BUF_SIZE;
cond.notify_one();
unsigned int p, c,
int buf[BUF_SIZE];
void writer()
for (int n = 0; n & ITERS; ++n)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout && "sending: "
&& n && std::
buf.put(n);
void reader()
for (int x = 0; x & ITERS; ++x)
int n = buf.get();
boost::mutex::scoped_lock
lock(io_mutex);
std::cout && "received: "
&& n && std::
int main(int argc, char* argv[])
boost::thread thrd1(&reader);
boost::thread thrd2(&writer);
thrd1.join();
thrd2.join();
线程局部存储
大多数函数都不是可重入的。这也就是说在某一个线程已经调用了一个函数时,如果你再调用同一个函数,那么这样是不安全的。一个不可重入的函数通过连续的调用来保存静态变量或者是返回一个指向静态数据的指针。 举例来说,std::strtok就是不可重入的,因为它使用静态变量来保存要被分割成符号的字符串。
有两种方法可以让不可重用的函数变成可重用的函数。第一种方法就是改变接口,用指针或引用代替原先使用静态数据的地方。比方说,POSIX定义了strok_r,std::strtok中的一个可重入的变量,它用一个额外的char**参数来代替静态数据。这种方法很简单,而且提供了可能的最佳效果。但是这样必须改变公共接口,也就意味着必须改代码。另一种方法不用改变公有接口,而是用本地存储线程(thread
local storage)来代替静态数据(有时也被成为特殊线程存储,thread-specific storage)。
Boost线程库提供了智能指针boost::thread_specific_ptr来访问本地存储线程。每一个线程第一次使用这个智能指针的实例时,它的初值是NULL,所以必须要先检查这个它的只是否为空,并且为它赋值。Boost线程库保证本地存储线程中保存的数据会在线程结束后被清除。
List5是一个使用boost::thread_specific_ptr的简单例子。其中创建了两个线程来初始化本地存储线程,并有10次循环,每一次都会增加智能指针指向的值,并将其输出到std::cout上(由于std::cout是一个共享资源,所以通过互斥体进行同步)。main线程等待这两个线程结束后就退出。从这个例子输出可以明白的看出每个线程都处理属于自己的数据实例,尽管它们都是使用同一个boost::thread_specific_ptr。
include &boost/thread/thread.hpp&
#include &boost/thread/mutex.hpp&
#include &boost/thread/tss.hpp&
#include &iostream&
boost::mutex io_
boost::thread_specific_ptr&int&
struct count
count(int id) : id(id) { }
void operator()()
if (ptr.get() == 0)
ptr.reset(new int(0));
for (int i = 0; i & 10; ++i)
boost::mutex::scoped_lock
lock(io_mutex);
std::cout && id && ": "
&& *ptr && std::
int main(int argc, char* argv[])
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();
5 仅运行一次的例程
还有一个问题没有解决:如何使得初始化工作(比如说构造函数)也是线程安全的。比方说,如果一个引用程序要产生唯一的全局的对象,由于实例化顺序的问题,某个函数会被调用来返回一个静态的对象,它必须保证第一次被调用时就产生这个静态的对象。这里的问题就是如果多个线程同时调用了这个函数,那么这个静态对象的构造函数就会被调用多次,这样错误产生了。
解决这个问题的方法就是所谓的“一次实现”(once routine)。“一次实现”在一个应用程序只能执行一次。如果多个线程想同时执行这个操作,那么真正执行的只有一个,而其他线程必须等这个操作结束。为了保证它只被执行一次,这个routine由另一个函数间接的调用,而这个函数传给它一个指针以及一个标志着这个routine是否已经被调用的特殊标志。这个标志是以静态的方式初始化的,这也就保证了它在编译期间就被初始化而不是运行时。因此也就没有多个线程同时将它初始化的问题了。Boost线程库提供了boost::call_once来支持“一次实现”,并且定义了一个标志boost::once_flag及一个初始化这个标志的宏BOOST_ONCE_INIT。
List6是一个使用了boost::call_once的例子。其中定义了一个静态的全局整数,初始值为0;还有一个由BOOST_ONCE_INIT初始化的静态boost::once_flag实例。main函数创建了两个线程,它们都想通过传入一个函数调用boost::call_once来初始化这个全局的整数,这个函数是将它加1。main函数等待着两个线程结束,并将最后的结果输出的到std::cout。由最后的结果可以看出这个操作确实只被执行了一次,因为它的值是1。
#include &boost/thread/thread.hpp&
#include &boost/thread/once.hpp&
#include &iostream&
int i = 0;
boost::once_flag flag =
BOOST_ONCE_INIT;
void init()
void thread()
boost::call_once(&init, flag);
int main(int argc, char* argv[])
boost::thread thrd1(thread);
boost::thread thrd2(thread);
thrd1.join();
thrd2.join();
std::cout && i && std::
6 Boost线程库的未来
Boost线程库正在计划加入一些新特性。其中包括boost::read_write_mutex,它可以让多个线程同时从共享区中读取数据,但是一次只可能有一个线程向共享区写入数据;boost::thread_barrier,它使得一组线程处于等待状态,知道所有得线程都都进入了屏障区;boost::thread_pool,他允许执行一些小的routine而不必每一都要创建或是销毁一个线程。
Boost线程库已经作为标准中的类库技术报告中的附件提交给C++标准委员会,它的出现也为下一版C++标准吹响了第一声号角。委员会成员对Boost线程库的初稿给予了很高的评价,当然他们还会考虑其他的多线程库。他们对在C++标准中加入对多线程的支持非常感兴趣。从这一点上也可以看出,多线程在C++中的前途一片光明。
7 参考资料:
The Boost.Threads Library by Bill KempfVisit the Boost website at &http://www.boost.org&.
C++ Boost库初次尝试
Boost库被称为C++的准标准库,功能非常强大,最近准备学习这个库。下面是一个示例程序
// ProtocolBufferTEST.cpp
#include &stdafx.h&
c++的boost库学习笔记
c++的boost库学习
boost和stlport编译,编译过程好麻烦,根据网上教程和boost完全开发指南,加自己摸索才勉强编译完成,做个笔记总结一下,具体编译方法,暂且不写
1,time...
C++ Boost 多线程(二),线程的参数传递
#include &iostream&
#include &boost/thread.hpp&
Boost::Thread使用示例
源地址:http://blog.csdn.net/zhuxiaoyang2000/article/details/6588031/
Boost::Thread的实现总体上是比较简单的,前面已...
boost thread使用方法
一、创建一个线程
boost::thread myThread(threadFun);
需要注意的是:参数可以是函数对象或者函数指针。并且这个函数无参数,并返回void类型...
*版权证明: 只允许上传png/jpeg/jpg/gif格式的图片,且小于3M
*详细原因:
交 C++ &em&Boost&/em& &em&Thread&/em& 编程指南 10积分 立即下载 ...
详细讲述了&em&boost&/em&::&em&thread&/em&的用法... 详细讲述了&em&boost&/em&::&em&thread&/em&的用法 综合评分:0 收藏评论举报 所需: 0积分/C币 开通VIP 立即下载 评论共有0条 C++ &em&Boost&/em& &em&Thread&/em& ...
Boost.Thread允许在可移植的C
++代码中使用共享数据的多个执行线程。它提供了用于管理线程本身的类和函数,以及用于在线程之间同步数据或为单独线程提供单独数据副本的其他类。...
编译遇到的的问题
http://blog.csdn.net/ivan_ljf/article/details/
C++多线程-第六篇-C++11与Boost
本例讲述C++11中实现的Boost线程部分
Atomic、mutex、thread、condition_variable等基本一致,
只不过名称空间在std中,使用时分别需要加上,,,。
没有更多推荐了,广告信息(免费广告联系)
中文版MSDN:你的位置:
命令名称:
BeginThread 同时运行过程
命令功能:
新开一个线程运行当前脚本,从指定的过程开始运行
命令参数:
参数字符串型,过程名
返 回 值:
整数型,线程ID [注:8.20版新增返回值参数]
脚本例子:
按键精灵8及以上语法
MessageBox "多线程命令还在测试当中,并不稳定,请谨慎使用"&&
//下面这个例子会打开一个记事本,用2个线程向其中模拟按键&&
Call RunApp("notepad")&&
Delay 1000&&
DimEnv Key&&
BeginThread Thread1&&
While True&&
& & Call PressKey()&&
& & key=key+1&&
& & If (key>90)&&
& && &&&key=65&&
& & EndIf& &
EndScript& &
Sub Thread1()&&
& & For 10&&
& && &&&Call PressKey()&&
& & Next& &
& & KeyPress 13,1&&
& & SayString "线程1已经结束"&&
& & KeyPress 13,1&&
Sub PressKey()&&
& & KeyPress key,1&&
& & Delay 200&&
-----------------------------------------------------------------&&
以下为新增功能(版本未发布请勿使用) [注:8.20版新增返回值参数]&&
MessageBox "多线程命令还在测试当中,并不稳定,请谨慎使用"&&
线程ID=BeginThread(测试)
//启动“测试”线程的运行,并返回线程ID编号&&
& & Delay 1000&&
StopThread 线程ID
//3秒后停止“测试”线程的运行&&
Sub 测试()&&
& && &&&Call Plugin.Msg.ShowScrTXT(0, 0, , "屏幕内容填写"&i, "0000FF")& &
& && &&&Delay 1000&&
& && &&&i=i+1&&
& & Loop& &
脚本例子:
按键精灵7及以下语法
MessageBox "多线程命令还在测试当中,并不稳定,请谨慎使用"&&
//下面这个例子会打开一个记事本,用2个线程向其中模拟按键&&
VBSCall RunApp("notepad")&&
Delay 1000&&
SetEnv "Key","65"&&
BeginThread "Thread1"&&
& & Gosub PressKey&&
& & key=key+1&&
& & If key>90&&
& && &&&key=65&&
& & EndIf& &
& & SetEnv "Key",CStr(key)&&
EndWhile& &
EndScript& &
Sub Thread1&&
& & For 10&&
& && &&&Gosub PressKey&&
& & EndFor& &
& & KeyPress 13,1&&
& & SayString "线程1已经结束"&&
& & KeyPress 13,1&&
Sub PressKey&&
& & key=GetEnv("Key")&&
& & KeyPress key,1&&
& & Delay 200&&

我要回帖

更多关于 按键精灵子程序和调用 的文章

 

随机推荐