- 締切済み
ダイアログ アプリで 複数のボタンの制御
コーディング ConBtn->EnableWindow(FALSE); CanBtn->EnableWindow(TRUE); 二つのボタンを排他的制御したいのですが ConBtnが 押されたら そのボタンを無効にして(ここまでOK) 即 別なボタン(CanBtn)を有効にしたいのですが 一連の処理が終わらないと CanBtnが 有効にならない どなたかご教示お願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- chie65536(@chie65535)
- ベストアンサー率44% (8742/19840)
追記。 「ConBtnをクリックすると、外部機器からのレスポンスを無限ループで待つ」と言う処理をするなら、別の方法もあります。 ・ConBtnを押した時の処理 ConBtnをDisableにする CanBtnをEnableにする 中断フラグをクリアする イベントが発生するタイマーをセットしてタイマーをキックする タイマーを起動したら、それ以上は何もしない ・CanBtnを押した時の処理 ConBtnをEnableにする CanBtnをDisableにする 中断フラグをセットする 中断フラグをセットしたら、それ以上は何もしない ・タイマーが起動された時の処理 中断フラグがセットされていたら、ボタン等を元に戻して処理を終了する 中断フラグがセットされていなかったら、外部機器からのレスポンスがあるか調べる 外部機器からのレスポンスが無かったら、一定時間後に自分自身が呼び出されるようにタイマーを再セットして処理を終了する(一定間隔で定期的に呼び出されるタイマーなら、特に再セットする必要はない) 外部機器からのレスポンスがあった場合、タイマーをクリアしてもう自分自身を呼ばないようにしてから、外部機器からデータを取り込むなどの必要な処理をして、ボタン等を元に戻して処理を終了する タイマーの「呼び出し間隔」は「外部機器の応答要求速度」で決めます。 例えば「外部機器に入力があった場合、最低でも30ms(0.3秒)以内に外部機器からデータ入力しないとならない」のであれば、タイマー間隔は「20msくらい」など、適切な値にセットすれば良いでしょう。 「無限ループで監視し続ける」だと、アクセス頻度が多くなりますし、CPUに高負荷をかけてしまいますが、タイマーでの監視なら「一定の間隔ででしか実行しない」ので、CPUに負荷をかけません。
- chie65536(@chie65535)
- ベストアンサー率44% (8742/19840)
>一連の処理が終わらないと CanBtnが 有効にならない 一連の処理が終わる前にCanBtnが有効になると、ConBtnを押した時の処理が完了する前にCanBtnがクリック可能になり「ConBtnの処理中にCanBtnが押される」と言う状況が発生しますが、それで「問題無い」のでしょうか? それで問題無いのであれば、以下のようにする必要があります。 //中断したかのフラグ volatale bool Aboat_flag; (中略) private: System::Void ComBtn_Click(System::Object^ sender, System::EventArgs^ e) { ConBtn->EnableWindow(FALSE); CanBtn->EnableWindow(TRUE); // //中断フラグを消しておく Aboat_flag = FALSE; // //Sleepで他のボタンのクリックイベントを受け付ける Sleep(0); // //中断ボタンが押されたかの判定 if (Aboat_flag) { //中断された場合の後始末をここに書く // //中断したらボタンを押せるように戻す ConBtn->EnableWindow(TRUE); CanBtn->EnableWindow(FALSE); //これ以上何もしない return; } // //時間のかかる処理をここに書く // //Sleepで他のボタンのクリックイベントを受け付ける Sleep(0); // //中断ボタンが押されたかの判定 if (Aboat_flag) { //中断された場合の後始末をここに書く // //処理の最後はボタンを押せるように戻す ConBtn->EnableWindow(TRUE); CanBtn->EnableWindow(FALSE); return; } //時間のかかる処理をここに書く // //処理の最後にボタンを押せるように戻す ConBtn->EnableWindow(TRUE); CanBtn->EnableWindow(FALSE); } (中略) private: System::Void CanBtn_Click(System::Object^ sender, System::EventArgs^ e) { //中断ボタンを押したら、中断フラグをセットする Aboat_flag = TRUE; }
お礼
ありがとうございました。 修正したコードでまた何かございましたら よろしくお願いいたします。
補足
早速 ご回答ありがとうございました 処理ないようはそうのうなことです ConBtnが押されると 外部機器からのレスポンス待ちで無限ループ 任意で中断できるようキャンセルボタンを設けています。 キャンセルボタンが押されたらフラグを立て無限ループをブレイク 最後に ConBtnを有効、CanBtnを無効にして イベント待ち状態 という流れでご指摘の通りです ご教示いただいた内容に従ってトライみてみます ありがとうございました。