怎样通过键盘输入打破循环?

songqicpp 2003-08-26 08:58:17
大家好:

我有一个问题,我在主窗体中间放置了一个TLabel控件Label1,在它上面有一个小菜单项ok,每当我点击ok菜单时,其菜单处理程序便执行以下程序:
void __fastcall TForm1::ok1Click(TObject *Sender)
{

int i=1;
while(true)
{
Form1->Label1->Caption=IntToStr(i++);
Form1->Label1->Refresh();
Sleep(150);
}

}

即Label1的Caption会从1开始一直显示数字,如果我希望这时我按一下光标键Down,就让这个显示数字过程结束,我应该怎么做呢?

我的初始想法是在OnKeyDown里进行判断,但是突然想起来当程序进入while(true)后,onkeydown是不能让它break的,如果在TForm1中加入一个标志位state(bool型),将while(true)变为while(state),然后在onkeydown中将state设为false,可是主程序一进入while循环后,onkeydown就拿不到控制权了。于是,我想到了用多线程的方法,以下是我用多线程的方法实现的程序。
//mainprog.h 主程序头文件

//---------------------------------------------------------------------------

#ifndef mainprgH
#define mainprgH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TMainMenu *MainMenu1;
TMenuItem *hello1;
TMenuItem *ok1;
void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift);
void __fastcall ok1Click(TObject *Sender);
private:
// User declarations
public:
bool state;//按理说这个state应放在private段里,但临时使用,所以...
// User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

//mainprog.cpp 主程序实现文件

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "mainprg.h"
#include "mythread.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
state=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if(Key==VK_DOWN)
state=false;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::ok1Click(TObject *Sender)
{
Mythread *thread=new Mythread(false);
}
//---------------------------------------------------------------------------


//mythread.h 线程类头文件
#ifndef mythreadH
#define mythreadH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class Mythread : public TThread
{
private:
protected:
void __fastcall Execute();
public:
__fastcall Mythread(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif

//mythread.cpp 线程类实现文件

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "mythread.h"
#include "Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall Mythread::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------

__fastcall Mythread::Mythread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall Mythread::Execute()
{
int i=1;
while(Form1->state)
{
Form1->Label1->Caption=IntToStr(i++);
Form1->Label1->Refresh();
Sleep(150);
}
Form1->Label1->Caption="I'll be back!";
Form1->state=true;
}
//---------------------------------------------------------------------------


我不知道这是不是解决这种问题的唯一方法,因为我最近看一些多线程的东西,所以想到了这招,但应该还有别的方法,请大家指教。

谢谢。
...全文
70 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
songqicpp 2003-08-26
  • 打赏
  • 举报
回复
除了上面4位之外,还有没有别的方法呢,再等等,分数一定全额送上。

netsys2 2003-08-26
  • 打赏
  • 举报
回复

在死循环中加下面的语句,可以响应外面的消息
while(true)
{
Application->ProcessMessages();
//...
}

zjqyb 2003-08-26
  • 打赏
  • 举报
回复
QUIT=false
while(!QUIT)
{
Form1->Label1->Caption=IntToStr(i++);
Application->ProcessMessages();
}


//
Form1->KeyPreview=true;
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
QUIT=(Key==VK_DOWN);

}


CityHost 2003-08-26
  • 打赏
  • 举报
回复
楼上说的非常正确,可惜我来晚了
sczyq 2003-08-26
  • 打赏
  • 举报
回复
你应该将循环放在线程里运行,选择ok菜单后,启动线程,

再做一个Cancel菜单, 选中后结束线程即可。
songqicpp 2003-08-26
  • 打赏
  • 举报
回复
呵呵,谢谢楼上的各位,都很有帮助,再次表示感谢。
starstargao 2003-08-26
  • 打赏
  • 举报
回复
Application->ProcessMessages();
Sumie@Sam 2003-08-26
  • 打赏
  • 举报
回复
还是建议将循环代码放入线程中,这样会比较好控制。

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧