- ベストアンサー
C-BuilderでEditのデーターが変化した時に二重割り込みを防ぐ方法を教えてください
- C-BuilderでEditのデーターが変化した時に二重割り込みが発生する問題があります。現在、bInhibitフラグを使用して二重割り込みを防いでいますが、タイミングによってはまだ問題が発生しています。他の方法を教えていただきたいです。
- Editの内容が変化した時にエラーメッセージを表示させ、内容を以前の状態に戻している処理がありますが、その状態でも再度OnChangeイベントが発生してしまいます。bInhibitフラグを使用して再度OnChangeイベントの発生を防いでいますが、まだ問題が解消されていません。
- Editの内容が変化した時に二重割り込みが発生してしまう問題があります。bInhibitフラグを使用して現在は二重割り込みを防いでいますが、まだ完全に問題が解決されていません。他の解決方法があれば教えていただきたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
あまり変わらないかも知れませんが、OnChangeイベントの頭でイベントにNULLを設定してみたらどうでしょう? void __fastcall TForm1::Edit1Change(TObject *Sender) { dynamic_cast<TEdit*>(Sender)->OnChange = NULL; -------- dynamic_cast<TEdit*>(Sender)->OnChange = Edit1Change; }
その他の回答 (1)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
下記、いずれも未検証ですが…… 【案1】 void __fastcall TForm1::Edit1Change(TObject *Sender) { Edit1->Enabled = false; // とりあえず、これ以降割り込み発生しないようにして Application->ProcessMessages(); //イベントループを一回りさせる(これで、内部状態も反映される) // 実際の処理 Edit1->Enabled = true; // 元に戻す。 } 【案2】 実際の処理を、OnChange ハンドラの外でやる。 bool isChagned = false; void __fastcall TForm1::Edit1Change(TObject *Sender) { Edit1->Enabled = false; // とりあえず、これ以降割り込み発生しないようにして isChanged = true; // 変化したというフラグを立てて Timer1->Enabled = true; // 定期的な監視をスタートして、処理終了 } だけにして、定期的に、isChanged をチェックするという方法です。 定期的なチェックは、Timer を使って、タイムラグが気にならない程度の頻度でハンドラを起動し、 void __fastcall TForm1::Timer1Timer(TObject *Sender) { // 実際の処理 // 処理が終わったら、 Timer1->Enabled = false; // 定期的な監視を終了 isChanged = false; // 変化しフラグをクリアして、 Edit1->Enabled = true; // 割り込みが発生できるようにして、処理終了 } こんな感じで。 OnChage() を抜けて、割り込みが発生しない状態になってから、編集が始まるというのがみそです。 マルチスレッドで構成できれば、もう少しきれいにできると思います。
お礼
ご回答ありがとう御座います。 Application->ProcessMessages();の方は既に検討済みです。 やはり外部で制御する必要があるのでしょうか。 メインテナンスの事を考えると出来るだけ内部でやりたいと思っております。 今は2重にフラグを作って対応して居ますが、このEdit自体実際はダイナミックキャストを使って居ますので、そこら辺のタイムラグ等で最初のフラグが認識されない事があるのかも知れません。 2重にしてどうにか正常動作?して居ますので、特に割り込み禁止プロパティー等が無ければ今のプログラムで行こうと思っております。 ありがとう御座いました。
お礼
ご回答ありがとうございます。 OnChangeが制御出来るのですね。 このやり方は知りませんでした。 明日、会社で試して見たいと思います。 ありがとう御座いました。
補足
本日、会社で試して見ました。 この方法では二重割り込みは発生しませんでした。 その他のマスクにも使えますね。 ありがとう御座いました。