クラス: wxValidator, wxTextValidator, wxGenericValidator, wxIntegerValidator, wxFloatingPointValidator
バリデータという概念の目的はダイアログをより簡単にコーディングできるようにすることです。バリデータは (wxTextCtrl などの) コントロールに接続可能なオブジェクトで、C++ のデータとコントロールとを仲介 (双方向のデータ転送と検証) します。また、コントロールの生成したイベントを捕まえることも可能なため、新しいコントロールクラスを継承することなく、コントロールの振る舞いをフィルタリングすることができます。
wxTextValidator (テキストデータの転送、検証、フィルタリングを行います) や wxGenericValidator (複数のコントロールへデータを転送します) といった既存のバリデータを使用することもできますし、自分で作成することもできます。
ここでは wxTextValidator の使い方の例を示します。
wxTextCtrl *txt1 = new wxTextCtrl( this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
この例ではテキストバリデータは次の機能を提供しています:
入力の検証とフィルタリングは 2 通りの方法で行われます。文字が入力されたときに wxTextValidator はその文字がフィルタフラグ (この場合は wxFILTER_ALPHA
) に合致するか確認します。入力された文字が不適切だった場合、入力は拒否され (画面上に現れません)、警告ビープ音が鳴ります。(ただし、 wxValidator::SetBellOnError(false) が呼ばれていない場合に限ります) ふたつ目の検証はダイアログが閉じられるときに行われます。そのため、デフォルト文字列がすでに不正な文字を含んでいる場合、エラーメッセージが表示され、ダイアログボックスが閉じられることはありません。
どの wxWindow もバリデータを持つことに注意してください; wxWS_EX_VALIDATE_RECURSIVELY
スタイル (wxWindow の拡張スタイルを参照) を使用すると再帰バリデータを実装することも可能です。
新しいバリデータクラスを作成する場合、次の機能を提供する必要があります。
バリデータのコンストラクタでは必要な検証の種類をプログラマが指定できるようにしてください。また、コントロールの値を格納する C++ 変数のポインタもおそらく受け取る必要があります。そのような変数のアドレスが指定されなかった場合、バリデータは内部にデータを格納するべきです。
wxValidator::Validate 関数はコントロール (C++ 変数ではありません) のデータが正しい場合に true を返却する必要があります。また、データが正しくない場合は適切なメッセージを表示する必要があります。
wxValidator::TransferToWindow 関数はバリデータや関連する C++ 変数からコントロールへデータを転送する必要があります。
wxValidator::TransferFromWindow 関数はコントロールからバリデータや関連する C++ 変数へデータを転送する必要があります。
コピーコンストラクタと、バリデータオブジェクトのコピーを返却する wxValidator::Clone 関数を用意する必要があります。バリデータはウィンドウのコンストラクタへ参照渡しされるため、内部的に複製しなければならないという点でこれは重要です。
イベントのフィルタリングを行なうためにバリデータ用のイベントハンドラを任意に定義することができます。これらのハンドラはコントロールでイベント処理が行われる前にイベントを捕まえます。(イベント処理の仕組み を参照) 実装の例は wxWidgets ライブラリの valtext.h
と valtext.cpp
を参照してください。
バリデータが正しく動作するためにはダイアログの初期化時、および終了時の適切なタイミングでバリデータ関数を呼ぶ必要があります。
wxDialog::Show (モードレスダイアログ用) または wxDialog::ShowModal (モーダルダイアログ用) が呼ばれると自動的に wxWindow::InitDialog が呼ばれます。そして、これは初期化イベントをダイアログへ送信します。wxEVT_INIT_DIALOG
イベントのデフォルトのイベントハンドラが wxWindow クラスの中で定義されており、これは単純に wxWindow::TransferDataToWindow 関数を呼ぶだけです。この関数は子コントロールのすべてのバリデータを探し、それぞれの TransferToWindow を呼び出します。そのため、ダイアログが表示されるそのときに C++ 変数からダイアログへデータが転送されます。
OK ボタンなど、ユーザがボタンを押下すると最初に wxWindow::Validate が呼ばれます。この関数は子ウィンドウのいずれかでウィンドウデータの検証に失敗した場合に false を返却します。ボタンハンドラは検証に失敗した場合に直ちに呼び出し元へ戻る必要があります。次に wxWindow::TransferDataFromWindow が呼ばれます。この関数が失敗した場合は呼び出し元へ戻ります。そのときは wxDialog::EndModal (モーダルの場合) や wxDialog::Show (モードレスの場合) を呼んでダイアログを終了しても安全です。
実際のところ、wxDialog は wxID_OK
ボタン用のデフォルトコマンドハンドラを持っています。これは次のようになります:
void wxDialog::OnOK(wxCommandEvent& event) { if ( Validate() && TransferDataFromWindow() ) { if ( IsModal() ) EndModal(wxID_OK); else { SetReturnCode(wxID_OK); this->Show(false); } } }
そのため、バリデータと通常の OK ボタンを使用している場合、ダイアログの終了処理を行なうためのコードを書く必要すらないでしょう。
ダイアログをリソースファイルから読み込む場合、コントロールに対してバリデータを設定する必要があります。これはダイアログリソース内でバリデータを指定できないためです。