我该怎么解决这个循环?

时间:2014-05-15 13:40:18

标签: winforms c++-cli

我目前正在构建一个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 ++做出反应,那也没关系。

提前谢谢。

2 个答案:

答案 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,你的循环将终止。