我目前正在构建一个Windows窗体应用程序,我有下一个问题, 我不能声明一个全局变量,因为我使用win的语法允许我这样做,而且,我需要在方法中声明变量,最后,它必须循环以便它能够计数。这是我到目前为止所得到的:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
int i;
m_bIsTimerOn = true;
while (m_bIsTimerOn)
{
i++;
label1->Text = (i.ToString());
}
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
m_bIsTimerOn = false;
timer1->Enabled = false;
}
m_bIsTimerOn是一个全局布尔值。你可能会在这里看到我的问题是,如果按下button1,程序就会停留在while循环中。我想知道,当你按下button2时,while循环停止,我也想知道这是否可能。如果你能用c ++做出反应,那也没关系。
提前谢谢。
答案 0 :(得分:1)
我想你想在计时器开启时增加i
。如果你需要为每个计时器刻度更新i
,那么它非常简单,删除该循环(以及该变量BTW)并简单地在计时器Tick
事件内进行更新:
private:
int _i;
void button1_Click(Object^ sender, EventArgs^ e) {
_i = 0;
timer1->Enabled = true;
}
void _timer1_Tick(Object^ sender, EventArgs^ e) {
label1->Text = (i++).ToString();
}
void button2_Click(Object^ sender, EventArgs^ e) {
timer1->Enabled = false;
}
如果我必须独立于计时器滴答更新,那么您必须将其移至BackgroundWorker
或仅在Application::Idle:
void OnIdle(Object^ sender, EventArgs^ e) {
label1->Text = (_i++).ToString();
}
void button1_Click(Object^ sender, EventArgs^ e) {
_i = 0;
Application::Idle += gcnew EventHandler(this, Form1::OnIdle);
timer1->Enabled = true;
}
void button2_Click(Object^ sender, EventArgs^ e) {
Application::Idle -= gcnew EventHandler(this, Form1::OnIdle);
timer1->Enabled = false;
}
最后说明:您甚至可以按原样保持循环,并在Application::DoEvents()
之后调用label1->Text = (i.ToString());
,但这可能会消耗大量CPU,减慢您的应用程序并打开您的代码重入,我真的避免这样的事情......
答案 1 :(得分:0)
你的程序处于无限循环中,因为while循环可以防止消息被处理,因此你的button2_Click不会被调用。要使应用程序能够处理发生的消息,请在循环中添加Application.DoEvents():
while (m_bIsTimerOn)
{
i++;
label1->Text = (i.ToString());
Application.DoEvents(); // causes the application to handle pending events
}
现在,如果你按下第二个按钮,m_bIsTimerOn将变为false,你的循环将终止。