none
Form上のTextBoxのTextを変化させたいのですが RRS feed

  • 質問

  • こんにちは。

    VisualStudio.NET 2003で開発をしています。

    プロジェクトとして「Windowsフォームアプリケーション(.NET)」を選んで出てきたForm上にPanelを乗せ、その上にTextBoxとボタンを乗せています。

    そしてボタンを押すとTextBoxの文字列を一定時間ごとに書き換える。

    もう一度同じボタンを押すと書き換えがストップ、というような機能をつけたいのですがそこで詰まっています。

    Thredを生成してそこで書き換えれば良いのだろうと思っていますがFormのソースの方にThredの関数を書きますと「staticの関数にしろ」といわれ、関数にstatic属性をつけますとTextBoxの参照が出来なくなります。

    どうかお助けください。

    情報が足りなければ追記させていただきますので恐れ入りますがご指摘お願いいたします。

    2007年2月8日 7:56

回答

  • スレッドではなく、タイマーコントロールを使うのはどうでしょうか?


    スレッドでやる場合、デリゲートを渡せばよさそうです。
    C#,VB.NETですが参考にどうぞ。
    http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html
    2007年2月8日 8:19
  • お返事ありがとうございます。

    実は教えていただいたページを元にしてやってみたのですが上手くいかないのです。

    下記の様にしますとThred生成行で「worker()関数が静的でない」とエラーになります。

    で、workerをstatic void worker(void)にすると今度は「Testtt()関数が静的でない」となるので同じくstaticにしますとTesttt()のなかでテキストボックスのthis->text_Data01が参照できなくなってしまうのです。

    #pragma once

    namespace TestMonitor
    {
     using namespace System;
     using namespace System::ComponentModel;
     using namespace System::Collections;
     using namespace System::Windows::Forms;
     using namespace System::Data;
     using namespace System::Drawing;
     using namespace System::Threading;

     public __gc class Form1 : public System::Windows::Forms::Form
     { 
     public:
      Form1(void)
      {
       InitializeComponent();
      }

     ・
     ・
     ・

    public:
     __delegate void TestttDelegate(int);

    void worker(void)
    {
      Testtt(0);
    }

    void Testtt(int a)
    {
      if (InvokeRequired)
       {
        // 別スレッドから呼び出された場合
        Invoke(new TestttDelegate(0,Testtt));
        return;
      }
     this->text_Data01->Text = "test";
    }

    private: System::Void button_Start_Click(System::Object *  sender, System::EventArgs *  e)
    {
     if(0 == button_Start->get_Text()->CompareTo("START"))
     {
      button_Start->set_Text("STOP");

      Thread *oThread = new Thread(new ThreadStart(0,worker));
      oThread->Start();

     }
     else
     {
      button_Start->set_Text("START");
     }
    }


    };
    }
     

     

    2007年2月8日 8:46
  • 書き忘れていましたがタイマーコントロールは制御上の問題で使用できません。

    2007年2月8日 8:54
  •  はね太 さんからの引用
       Thread *oThread = new Thread(new ThreadStart(0,worker));

    が違うのでは?staticメソッドにせずに

    Thread* oThread = new Thread(new ThreadStart(this, &Form1::worker));

    としたらどうでしょうか?
    2007年2月8日 8:56
  • ありがとうございます!

    コンパイルが通りました。

    本当に助かりました、ありがとうございます。

    2007年2月8日 9:06

すべての返信

  • スレッドではなく、タイマーコントロールを使うのはどうでしょうか?


    スレッドでやる場合、デリゲートを渡せばよさそうです。
    C#,VB.NETですが参考にどうぞ。
    http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html
    2007年2月8日 8:19
  • お返事ありがとうございます。

    実は教えていただいたページを元にしてやってみたのですが上手くいかないのです。

    下記の様にしますとThred生成行で「worker()関数が静的でない」とエラーになります。

    で、workerをstatic void worker(void)にすると今度は「Testtt()関数が静的でない」となるので同じくstaticにしますとTesttt()のなかでテキストボックスのthis->text_Data01が参照できなくなってしまうのです。

    #pragma once

    namespace TestMonitor
    {
     using namespace System;
     using namespace System::ComponentModel;
     using namespace System::Collections;
     using namespace System::Windows::Forms;
     using namespace System::Data;
     using namespace System::Drawing;
     using namespace System::Threading;

     public __gc class Form1 : public System::Windows::Forms::Form
     { 
     public:
      Form1(void)
      {
       InitializeComponent();
      }

     ・
     ・
     ・

    public:
     __delegate void TestttDelegate(int);

    void worker(void)
    {
      Testtt(0);
    }

    void Testtt(int a)
    {
      if (InvokeRequired)
       {
        // 別スレッドから呼び出された場合
        Invoke(new TestttDelegate(0,Testtt));
        return;
      }
     this->text_Data01->Text = "test";
    }

    private: System::Void button_Start_Click(System::Object *  sender, System::EventArgs *  e)
    {
     if(0 == button_Start->get_Text()->CompareTo("START"))
     {
      button_Start->set_Text("STOP");

      Thread *oThread = new Thread(new ThreadStart(0,worker));
      oThread->Start();

     }
     else
     {
      button_Start->set_Text("START");
     }
    }


    };
    }
     

     

    2007年2月8日 8:46
  • 書き忘れていましたがタイマーコントロールは制御上の問題で使用できません。

    2007年2月8日 8:54
  •  はね太 さんからの引用
       Thread *oThread = new Thread(new ThreadStart(0,worker));

    が違うのでは?staticメソッドにせずに

    Thread* oThread = new Thread(new ThreadStart(this, &Form1::worker));

    としたらどうでしょうか?
    2007年2月8日 8:56
  • ありがとうございます!

    コンパイルが通りました。

    本当に助かりました、ありがとうございます。

    2007年2月8日 9:06