• ベストアンサー

VC++のwin32アプリ作成におけるボタンの扱い

Visual C++でWin32アプリケーションを作成しています。 作成環境: Windows Vista 64bit (iMac bootcamp) Microsoft Visual C++ 2010 Express フォーム上にbutton1とbutton2がセッティングされている状態で、 button1_Clickの処理を行っている間に、button2が押されたとします。 その作用として、button1_Click内部の変数を変更したいと考えています。 この処理は可能でしょうか。 または、代替処理として、何らかの形で干渉する事は出来ますでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

>ただ、よりシンプルに記述する方法はないのでしょうか。 #2 のプログラムは、質問に >button1_Click内部の変数を変更したいと考えています。 と書かれていたので、無理やりこのような形にしただけのことです。 #2 のプログラムを private 変数を使用する方法にすると次のようになります。 private: bool loopFlag; System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { loopFlag = false; } // 開始 System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { if( !loopFlag ) { loopFlag = true; while( loopFlag ) { Application::DoEvents(); this->label1->Text = DateTime::Now.ToString(); } this->label1->Text = ""; } } // 停止 System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { loopFlag = false; } System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) { loopFlag = false; } マルチスレッドについては .NETマルチスレッド・プログラミング入門 第2回 .NETにおけるマルチスレッドの実装方法を総括 http://www.atmarkit.co.jp/fdotnet/mthread/mthread02/mthread02_01.html Windowsフォームで別スレッドからコントロールを操作するには? http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html などを参考にされると良いと思います。

すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.2

C++/CLI ということですね? button1_Click の中で Application.DoEvents() を実行してやれば、多少動作はぎこちなくなると思いますが、button1_Click の処理中に button2 をクリックすることが可能となります。 static 変数にすれば、無理やり感はありますが、button2_Click から button1_Click を呼び出して static 変数を変更することは可能です。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { static bool loopFlag = false; if( ((Button^)sender)->Name == "button1" ) { if( !loopFlag ) { loopFlag = true; while( loopFlag ) { Application::DoEvents(); this->label1->Text = DateTime::Now.ToString(); } this->label1->Text = ""; } } else { loopFlag = false; } } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { button1_Click(sender, e ); } private: System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) { this->button2->PerformClick(); } ただ、static 変数にせず、private などで宣言するのが一般的なやり方ではないかと思います。 ( Application.DoEvents() も使用せず、別スレッドを作成する方がよいような気がします。)

asanosiki
質問者

補足

ご回答ありがとうございます。解りやすいコードでやり方を理解できました。 Application::DoEventsがミソになるんですね。 ただ、よりシンプルに記述する方法はないのでしょうか。 例えば、button1が再生ボタンで、そこに中断ボタン(button2)があったり、 ボリューム調整ボタン(trackBar1)があったりして、 button1_Click中に、複数のイベントが発生する場合があると思います。 別スレッドの作成についてももう少し詳しい説明をいただければ幸いです。

すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.1

>button1_Clickの処理を行っている間に、button2が押されたとします。 >その作用として、button1_Click内部の変数を変更したいと考えています。 button1_Click()の処理が終わるまで、button2の操作に対する処理(button2_Click())は実行できません。 仮にbutton2_Click()が処理できても「button1_Click内部の変数」はスコープ外でしょうから無理かと。 # 静的変数にしていない限り、寿命は処理が終わるまで…ですしね。 button1_Click()内で、自前でメッセージ処理すれば可能かも知れませんが…いろいろ面倒かと思われます。 「メッセージポンプ」とか「PeekMessage」で検索すると見つかるかと。 MFC固有の処理が実行されるか…はどうなんでしょうかね。 まぁ、現実的にbutton1_Click()で時間のかかる処理でもしていない限り、button2を押すのは無理でしょう。 また、時間のかかる処理をしているならワーカースレッド起こしてそちらで処理するべきです。 同期処理が手間になりますが。(button1が連打されるとか) ワーカースレッドなしで時間のかかる処理をしていると…OSから「(応答なし)」のラベルを貰えるかも知れません。 # button1を押した後、ウィンドウの移動してみるとかAlt+TAB等でアクティブを切り替えるとか。

すると、全ての回答が全文表示されます。

関連するQ&A