• 締切済み

ダイアログ アプリで 複数のボタンの制御

コーディング ConBtn->EnableWindow(FALSE); CanBtn->EnableWindow(TRUE); 二つのボタンを排他的制御したいのですが ConBtnが 押されたら そのボタンを無効にして(ここまでOK) 即 別なボタン(CanBtn)を有効にしたいのですが 一連の処理が終わらないと CanBtnが 有効にならない どなたかご教示お願いいたします。

みんなの回答

  • chie65535
  • ベストアンサー率43% (8466/19280)
回答No.2

追記。 「ConBtnをクリックすると、外部機器からのレスポンスを無限ループで待つ」と言う処理をするなら、別の方法もあります。 ・ConBtnを押した時の処理 ConBtnをDisableにする CanBtnをEnableにする 中断フラグをクリアする イベントが発生するタイマーをセットしてタイマーをキックする タイマーを起動したら、それ以上は何もしない ・CanBtnを押した時の処理 ConBtnをEnableにする CanBtnをDisableにする 中断フラグをセットする 中断フラグをセットしたら、それ以上は何もしない ・タイマーが起動された時の処理 中断フラグがセットされていたら、ボタン等を元に戻して処理を終了する 中断フラグがセットされていなかったら、外部機器からのレスポンスがあるか調べる 外部機器からのレスポンスが無かったら、一定時間後に自分自身が呼び出されるようにタイマーを再セットして処理を終了する(一定間隔で定期的に呼び出されるタイマーなら、特に再セットする必要はない) 外部機器からのレスポンスがあった場合、タイマーをクリアしてもう自分自身を呼ばないようにしてから、外部機器からデータを取り込むなどの必要な処理をして、ボタン等を元に戻して処理を終了する タイマーの「呼び出し間隔」は「外部機器の応答要求速度」で決めます。 例えば「外部機器に入力があった場合、最低でも30ms(0.3秒)以内に外部機器からデータ入力しないとならない」のであれば、タイマー間隔は「20msくらい」など、適切な値にセットすれば良いでしょう。 「無限ループで監視し続ける」だと、アクセス頻度が多くなりますし、CPUに高負荷をかけてしまいますが、タイマーでの監視なら「一定の間隔ででしか実行しない」ので、CPUに負荷をかけません。

  • chie65535
  • ベストアンサー率43% (8466/19280)
回答No.1

>一連の処理が終わらないと 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; }

lsas2012
質問者

お礼

ありがとうございました。 修正したコードでまた何かございましたら よろしくお願いいたします。

lsas2012
質問者

補足

早速 ご回答ありがとうございました 処理ないようはそうのうなことです ConBtnが押されると 外部機器からのレスポンス待ちで無限ループ 任意で中断できるようキャンセルボタンを設けています。 キャンセルボタンが押されたらフラグを立て無限ループをブレイク 最後に ConBtnを有効、CanBtnを無効にして イベント待ち状態 という流れでご指摘の通りです ご教示いただいた内容に従ってトライみてみます ありがとうございました。

関連するQ&A

  • Qダイアログ アプリで 複数のボタンの制御(続き)

    先ほど回答していただき、修正しましたが 動作に変化はありませんでした。 私の質問方法が悪かったのかしれませんが 解決したい箇所は次の通りです //ConBtnのイベント void CKm370ReaderDlg::OnBnClickedBtnCon() { // TODO: ここにコントロール通知ハンドラー コードを追加します。 CANCEL = false; m_ListCtrl.ClearBox(); ConBtn->EnableWindow(FALSE); CanBtn->EnableWindow(TRUE); <--ここで即 CanBtnを有効にしたい   Exit = false;    while(!Exit) { switch(sequence) {  case 0: while(Polling()) { if(CANCEL) { Exit = True; break; }   }     break;      case 1: : } } 現状では、CanBtnが有効にならないので while(!Exit) { }の処理がすべて終わった時点でCanBtnが有効になっています。 再度、ご検討のほどよろしくお願いいたします。

  • 「キャンセル」ボタン付きの処理中ダイアログ

    Windowsアプリで、ある時間のかかる処理を キャンセルボタン付処理中ダイアログを表示し、途中で処理をキャンセル可能にしたいと考えています。 ここの過去ログから上記はマルチスレッドにする必要があると拝見しました。http://oshiete1.goo.ne.jp/kotaeru.php3?q=96951 <メイン画面の開始ボタン処理> ------------------ void C_SampleDlg::OnStart(){  CWinThread *cwt;  C_CancelDlg dlgCancel(this);  cwt = AfxBeginThread(Sample_Proc, &InputParams);  cwt->m_bAutoDelete = FALSE;  cwt->ResumeThread();  EnableWindow(FALSE);  dlgCancel.Create();  dlgCancel.ShowWindow(SW_SHOW);  while(TRUE){   if(dlgCancel.CheckCancel() == TRUE){    // キャンセルが押された時    EnableWindow(TRUE);    dRcd = WaitForSingleObject(cwt->m_hThread, INFINITE);    if(dRcd == WAIT_OBJECT_0)     return;   }   dRcd = WaitForSingleObject(cwt->m_hThread, 0);   if(dRcd == WAIT_OBJECT_0){    dlgCancel.DestroyWindow();    EnableWindow(TRUE);    break;   }  }  return; } <プロシージャ> ---------------------------------- UINT Sample_Proc(LPVOID pParam){  C_SampleDlg->やりたい処理関数呼び出し  ::AfxEndThread(0);  return 0; } 以降別ソース ================================== <C_SampleDlg::やりたい処理関数> ↑ここでdlgCancel.CheckCancel() == TRUEかどうか 判定したい場合、グローバル関数を使うか、または呼出し元で作成したインスタンスをパラメタとして渡して使うべきなのでしょうか。文字数の関係で分かりにくいところもありますが、よろしくお願いします。 ※dlgCancel.CheckCancel()はC_CancelDlgクラスのプロテクト変数を内部で操作しています。

  • 閉じるボタン「×」を制御したい

    PHPを使って作業している者です。 windowの閉じるボタンが押された場合、イベントを起こす方法はありませんか? どうしたいのかを具体的にいいますと、 ユーザーのログイン、ログアウトの情報をPHPを介してMysqlのデータベースで管理しています。 閉じるボタン「×」を押した場合、データベース内にあるユーザー情報を削除したいのです。 ログアウトボタンを押されずに退席し、データベース上にユーザー情報が残ったままになってしまうことを避けたいのです。 javascriptを併用してもかまわないので何とかならないでしょうか? 排他制御の一環として今回の質問内容を模索しているので、もっと別で効率のいい方法が有るとは思いますが、排他ロックをいまいち理解できないためデータベース上にユーザー情報の有無で制御してしまおう考えてのことです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • ツールボタンの制御について

    メールソフトやテキストエディタなどで編集系ボタン(切り取り 貼り付け、コピー、元に戻すなど)のツールボタンがある時 クリップボードとかにデータがなければ貼り付けが使用 できない(Enabled = false)とかになっていたりしますが これはどこのイベントで制御しているのでしょうか? DelphiだとTActionList(だったかな?)のようにメニューの イベントと連動して出来たのですが、C#ではどうすれば 良いのでしょうか? 現状は無理やりタイマーコントロールでクリップボードとか テキストボックスの選択文字数を監視してツールボタンの 有効/無効を切り替えています。

  • トグルボタンの排他制御でご教授ください。

    いつもお世話になっております。 エクセル2003のマクロVBAで、トグルボタンの排他制御を行っております。 ひとつのフレーム上の二つのトグルボタンの制御は、MSのサンプルソースを参考に以下のようなソースを作成して、制御できております。 教えて頂きたい内容は、同じようにひとつのフレーム上に、二つのトグルボタンを追加して、排他制御を行いたいたく検討しています、できれば、以下の ExclusiveToggleButtons() を使いたいと思っていますが、for ループのフレーム名が固定です。 フレーム名を可変にすれば、共用できるのではないかと思っていますが、なかなかうまくいきません、よい方法がありましたら、ご教授願います。 --- 標準モジュール ------------ start --- Sub ExclusiveToggleButtons() Dim my_toggle As Control ' Loop through all the ToggleButtons on Frame1. For Each my_toggle In myStartForm.my_MonthChoice_Frame.Controls ' If Name of ToggleButton matches name of ToggleButton ' that was clicked... If my_toggle.Name = my_Clicked_But Then '...select the button. my_toggle.Value = True Else '...otherwise clear the selection of the button. my_toggle.Value = False End If Next --- 標準モジュール ------------ end ---

  • 【VC++2005(CLR)】ダイアログ右上の最小化、最大化、閉じるボタンの制御の仕方を教えてください。

    VC++初心者です。 たびたび、お世話になっております。 現在、VC++2005 Express Edition、CLRのプロジェクトで コーディングしています。 基本的な質問だと思いますが、ダイアログ右上に配置される 最小化、最大化、閉じるボタンの制御の仕方を 教えていただけませんでしょうか。 具体的にはやりたいことは、以下のようなものです。 ・閉じるボタンを押されたら、MessageBoxを表示させる。 ・他のダイアログのボタンから別のダイアログの最大化ボタンが  押されたことと同じ動作をする。

  • VC++ 2005 MFC ボタンの無効化

    VC++ 2005 MFC ボタンの無効化 現在スレッドを使ったプログラムを作成しています。 あるボタンを押すと、 親スレッド 1、RS232C受信スレッドを作成 2、RS232Cにデータを送信 3、WaitSingleObjectでイベント待ち 4、受信状態に応じた処理 子スレッド 1、サムチェック等確認して、受信が完了すれば   受信データを格納してCEventのSetEventを発行 というような処理の部分があるのですが、待っている間にウィンドウ内にある ボタンが押せてしまいます。厳密には、イベント待ちを抜けた時点で待っている 間に押せてしまったボタンの処理が走ってしまうのですが。 EnableWindow(FALSE)をやっても駄目でした。 何かいい方法がありませんか??すいませんがよろしくお願いします。

  • 削除ボタンの確認ダイアログを表示させると処理が進まない

    いろいろ検索しましたが、回答が得られなかったため質問します。 削除ボタンを押した時、確認ダイアログを表示させ、 OKをクリックすると処理が進むようにしようと思っているのですが、 下記のコードだと、OKでもキャンセルでもonclickの処理に進まず困っています。 ■javascript function del_confirm(){ Ans = confirm("削除します"); if(Ans==true){ alert("削除しました"); return true; }else{ alert("キャンセルしました"); return false; } } ■body <input type="submit" value="チェックしたものを削除" onmouseup="return del_confirm()" onclick="action_delete.php"> 間違ったところなどあればご指摘お願い致します。 わからないことがあれば追記しますので、 よろしくお願い致します。

  • 削除ボタンの確認ダイアログを表示させると処理が進まない

    いろいろ検索しましたが、回答が得られなかったため質問します。 削除ボタンを押した時、確認ダイアログを表示させ、 OKをクリックすると処理が進むようにしようと思っているのですが、 下記のコードだと、OKでもキャンセルでもonclickの処理に進まず困っています。 ■javascript function del_confirm(){ Ans = confirm(\"削除します\"); if(Ans==true){ alert(\"削除しました\"); return true; }else{ alert(\"キャンセルしました\"); return false; } } ■body <input type=\"submit\" value=\"チェックしたものを削除\" onmouseup=\"return del_confirm()\" onclick=\"action_delete.php\"> 間違ったところなどあればご指摘お願い致します。 わからないことがあれば追記しますので、 よろしくお願い致します。

  • ムービークリップのボタンの無効化について

    お世話になっております。 actionscript3でFLASHサイトを製作しております。 マウスオーバー、マウスアウト、マウスクリックのイベント機能を付与したムービークリップ型のボタンがあり、ボタンモードを有効にしています。 button.buttonMode = true; マウスオーバーの際はムービークリップの指定のフレームからアニメーション処理を行っています。 button.addEventListener(MouseEvent.MOUSE_OVER, btnOver); function btnOver(event:MouseEvent):void { button.gotoAndPlay(2); } このボタンを、あるイベントが実行された時にボタンとしての機能をなくし、尚且つマウスオーバー、マウスアウトのアニメーション処理も無効化したいと思い、以下の処理を行いました。 ボタンモードは無効になりましたが、マウスオーバー、マウスアウト、クリック処理は無効にならず、動作してしまいます。 button.buttonMode = false; button.mouseEnabled = false; button.enabled = false; 上記の方法とは別にイベント処理を削除しようと思い、removeEventListener処理を行いましたが、「TypeError: Error #2007: パラメータ listener は null 以外でなければなりません。」というエラーが表示されてしまいました。 指定の仕方が間違っているのだと思いますが、何方かご教授いただけないでしょうか? また、上記の方法以外で無効化する手段があればご教授いただければと思います。 宜しくお願いいたします。

専門家に質問してみよう