一个button内调用了一个需要执行较长时间的函数,点击后要等很长时间,按纽才能再次点,怎么办?
一个button内调用了一个需要执行较长时间的函数,点击后要等很长时间,按纽才能再次点,怎么办?
那个函数是在等待一个硬件反应,他有时间限制,过了时间,也会执行完,太时间太长.
我希望button 可以不停的点,点一次就重头开始.请问怎么做好呢?
问题点数:50、回复次数:25Top
1 楼lurel(城市陌生人)回复于 2006-03-20 14:30:23 得分 0
用线程来控制,然后利用加锁和解锁来控制资源的访问.Top
2 楼jone7319(舍我其谁)回复于 2006-03-20 14:32:55 得分 0
在循环中加入 Application->ProcessMessages()Top
3 楼uhian(豆豆鸟)回复于 2006-03-20 14:38:23 得分 0
Application->ProcessMessages();Top
4 楼uhian(豆豆鸟)回复于 2006-03-20 14:39:44 得分 0
到底怎么停止并从头来,在循环中判断就可以了。Top
5 楼liskman(流云)回复于 2006-03-20 14:40:10 得分 0
当我第一次用Application->ProcessMessages()时,激动的热泪盈眶,本来一个很简单的程序,非要写个线程,用这个太方便了。
不过要小心,你的处理函数要小心变量在程序ProcessMessages()时被更改。Top
6 楼liuxinzhi1982(大头)回复于 2006-03-20 14:42:33 得分 0
magiccard_insert(3,&nLen);执行时间长
{
BitBtn1->Glyph->LoadFromFile("D:\\new task\\samples\\应用2\\001.bmp");
///////////////////////////
HINSTANCE h1;
int nLen=0;
int rc=1;
int (*magiccard_position)( int *position );
int (*magiccard_insert)(int delaytime,int *magiccardinserted);
h1=LoadLibrary("D:\\new task\\samples\\应用2\\magiccardreader.dll");
(FARPROC &)magiccard_position=GetProcAddress(h1,"magiccard_position");
(FARPROC &)magiccard_insert=GetProcAddress(h1,"magiccard_insert");
try
{
rc=magiccard_insert(3,&nLen);
}
catch(Exception &e)
{
ShowMessage(e.Message);
}
//////////////////////////
if(rc==0&&nLen==1)
{
Form3 = new TForm3(this);
Graphics::TBitmap *BkgndBitmap =new Graphics::TBitmap();
BkgndBitmap->LoadFromFile("D:\\new task\\samples\\应用2\\back02.bmp");
Form3->Brush->Bitmap=BkgndBitmap;
Form3->Show();
}Top
7 楼lurel(城市陌生人)回复于 2006-03-20 14:48:53 得分 0
还是推荐不要强行中断,因为有些资源你调用dll的,如果你终止调用,但dll中处理过程的无法正常退出.最好还是用线程在执行的时候Lock,执行完UnlockTop
8 楼setdefault(山转水也转)回复于 2006-03-20 14:55:10 得分 0
1、如果需要用户等待,则出现一个对话框要求等待。
2、如果允许用户干别的事,则调用线程或ProcessMessages()
2.1、如果不希望用户再点击该button本身,应在onbuttonclick中加入防止重入的代码。比如
if (btn->Tag!=1){
...
}
btn->Tag = 0;Top
9 楼liuxinzhi1982(大头)回复于 2006-03-20 15:13:34 得分 0
我不是循环花了时间,而是函数magiccard_insert(3,&nLen)的第一个参数是花3秒等待硬件Top
10 楼yz20050510(小)回复于 2006-03-20 15:33:54 得分 0
是否可以在执行代码中加入控制按钮状态的代码,如置灰等操作,也可以达到目的
可以试试Top
11 楼cfs1979(学无止境)回复于 2006-03-20 15:47:14 得分 0
还是用线程比较好Top
12 楼keiy()回复于 2006-03-20 15:50:19 得分 0
如果是在magiccard_insert(3,&nLen)中有延时,除了用线程外,应该没有特别的办法,另外你的 h1=LoadLibrary("D:\\new task\\samples\\应用2\\magiccardreader.dll");
最好不要写在button的onclick中Top
13 楼pp616(坏蛋)回复于 2006-03-20 17:09:27 得分 10
开线程做Top
14 楼liuxinzhi1982(大头)回复于 2006-03-21 15:58:13 得分 0
第一次用C++builder,具体能说说怎么在主窗口中建立和使用一个线程步骤吗?我有点无法下手。Top
15 楼keiy()回复于 2006-03-21 17:57:07 得分 40
在菜单中file->new->other->Thread objects给一个线程的类名如ttt
在ttt的Execute()中写你要执行的程序
在程序中写
#include "unit2.h" //线程单元名
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ttt *t;
t=new ttt(true); //建线程,暂不执行
...
t->Resume(); //执行线程
}
Top
16 楼liuxinzhi1982(大头)回复于 2006-03-26 11:22:57 得分 0
我在线程里面想做
if(positions==2)
{
Form3 = new TForm3(this);
Graphics::TBitmap *BkgndBitmap =new Graphics::TBitmap();
BkgndBitmap->LoadFromFile("D:\\new task\\samples\\应用6\\back02.bmp");
Form3->Brush->Bitmap=BkgndBitmap;
Form3->Show();
}
会出现could not find match for TForm3::TForm(New Thread*const)
错误,我已经加了Form3的头文件,不用线程时候是没错误的啊Top
17 楼keiy()回复于 2006-03-26 14:39:52 得分 0
尽量不要在线程中调FORM(最好在FORM中调线程)
实在要在线程中调用FORM,应该写
Form3 = new TForm3(NULL); //线程类不能作FORM的父类Top
18 楼zyyoung(倡导开源)回复于 2006-03-27 15:57:55 得分 0
创建线程,好注意啊Top
19 楼jiangshx(寻平阳)回复于 2006-03-28 09:13:41 得分 0
星星们都说用线程了,那就用线程,就这么定了.Top
20 楼liuxinzhi1982(大头)回复于 2006-03-29 20:06:18 得分 0
用了感觉不错Top
21 楼paste(invoke)回复于 2006-03-30 06:22:53 得分 0
我也遇到过这个问题,最后用线程解决效果不错Top
22 楼tianshu888(CC)回复于 2006-03-30 10:20:46 得分 0
看来问题已经解决了。
Top
23 楼liuxinzhi1982(大头)回复于 2006-03-30 21:31:53 得分 0
关于抢夺界面时候的代码还要放到Synchronize的函数中去才不会出错Top
24 楼yyszh(追求完美)回复于 2006-03-30 21:52:16 得分 0
线程是强大的武器。Top
25 楼stevenjscn(小胖)回复于 2006-03-30 22:42:38 得分 0
强烈SUGGEST用THREAD
Top




