ユーザーから複数の異なるタイプの値 (時間、圧力、名前など) を取得したい。入力ボックスをカスタマイズしたい。ただし、値は 1 つしか取りません。
この状況を解決する方法、または使用するコンポーネントはありますか?
ユーザーから複数の異なるタイプの値 (時間、圧力、名前など) を取得したい。入力ボックスをカスタマイズしたい。ただし、値は 1 つしか取りません。
この状況を解決する方法、または使用するコンポーネントはありますか?
フランソワは正しい。与えられたツールの限界に達しました。InputBox
複雑な入力用に設計されていないだけでなく、複数の値を処理するように拡張するようにも設計されていません。
コメントでリンクしたページには例がありますが、かなり貧弱に提示されているため、誤解していることを責めません. 取得するのにも数回の読み取りが必要でした。その核となるのはMyAsk
、下部の機能です。(上部のクラス宣言は無視してTAppendThread
ください。役に立ちません。)MyAsk
プロンプトと値を含むレコードのリストを受け取り、レコードごとにInputBox
、ユーザーから値を要求するために呼び出します。記録がない方が分かりやすいかもしれません。次のように書き換えることができます。
procedure MultiInputBox(const Prompts: array of string; var Values: array of string]);
var
i: Integer;
begin
Assert(Length(Prompts) = Length(Values));
for i := 0 to High(Prompts) do begin
Values[i] := InputBox(Application.Title, Prompts[i], Values[i]);
end;
end;
次のように呼び出します。
TempTime := TimeToStr(DefaultTime);
TempPressure := IntToStr(DefaultPressure);
TempName := DefaultName;
MultiInputBox(['Time', 'Pressure', 'Name'], [TempTime, TempPressure, TempName]);
TimeToUse := StrToTime(TempTime);
PressureToUse := StrToInt(TempPressure);
NameToUse := TempName;
ただし、これはユーザーにとってひどいインターフェースです。戻る方法も、取り消す方法もありません。尋問がどれくらい続くかを示すものもありません。また、特定のデータ型の形式を強制する方法もありません。必要な情報を正確に取得するカスタム フォームを設計すれば、はるかに良い結果が得られます。世界で最も簡単にフォームをデザインできるツールを使用しています。それに抵抗しないでください。
時間、圧力、名前を取得する必要がある場合は、3 つの入力コントロールを含むフォームを作成します。TDateTimePicker
時刻には aを使用TSpinEdit
し、数値入力には a を使用TEdit
し、名前には a を使用します。各入力の横TLabel
にコントロールを配置して、ユーザーが各入力の目的を理解できるようにします。フォームに OK ボタンとキャンセル ボタンを配置します。境界線のスタイルやキャプションなど、その他のさまざまなフォーム プロパティを設定します。その形式で記述するコードはほとんどありません。ただし、入力値が意味を成していることを確認するために、入力値を検証するコードを自由に追加できます。
使用するには、単純に作成し、初期値を設定し、モーダルに表示し、閉じるときに新しい値を読み取ります。
var
form: TDatePressureNameDialog;
begin
form := TDatePressureNameDialog.Create(nil);
try
form.TimePicker.Value := DefaultTime;
form.PressureEdit.Value := DefaultPressure;
form.NameEdit.Text := DefaultName;
if form.ShowModal = mrOK then begin
TimeToUse := Frac(form.TimePicker.Value);
PressureToUse := form.PressureEdit.Value;
NameToUse := form.NameEdit.Text;
end;
finally
form.Free;
end;
end;
メソッドの結果を確認する方法にも注意してくださいShowModal
。これにより、ユーザーが [OK] または [キャンセル] を押してフォームを閉じたかどうかがわかります。InputBox
常に文字列を返す では、これを行うことはできません。(InputQuery
これらの 2 つの関数の主な違いであるその情報を伝えることができますが、それだけでは、状況でどちらの関数を使用する価値もありません。)
この新しいフォーム クラスがプロジェクトの負担になることを心配する必要はありません。プロジェクトのサイズに最も大きな影響を与える 2 つの要素は、SysUtilsユニットとFormsユニットです。すでにそれらを含めているので、最悪の事態はすでに過去のものです。少なくとも 1 つのフォームが既にあるプロジェクトにフォームを追加しても、プロジェクトのサイズにはまったく影響しません。特に、上記で説明した 8 つのコントロールしかないフォームには影響しません。
「入力ボックス」、つまり TEdit とは正確には何を意味しますか? 入力用のさまざまな種類のコンポーネントがあり、さまざまなことを行うことができます。名前に関しては、TEdit は非常に優れていますが、時間に関しては、カレンダー コントロールが必要になる場合があり、圧力に関しては、数値に最適なコントロールを使用する必要がある場合があります。
はい、フォームをデザインしましょう!
Dialogs.InputBox は、ユーザーから 1 つの文字列をすばやく簡単に取得するように設計されています。
さらに必要な場合は、エントリー フォームを設計する必要があります。
基本的なダイアログが必要な場合は、Dialogs.InputQuery のコードを参照し、それを出発点として使用して、独自の手順をコーディングできます。
本当の取引が必要な場合は、掘り下げて実際のフォームをコーディングする必要があります。
すべてのフォームを自動作成するように設定する必要はありません。フォームを作成したら、プロジェクト オプションに移動し、フォーム オプションを選択して、自動作成したくないすべてのフォームを右側に移動します。
これらの非自動作成フォームに最も一般的に使用するパターンは、次のようなものです。
Function GetValuesFromDialog : boolean;
var
dlg : tValuesDialog;
begin
result := false;
dlg := tValuesDialog.Create(nil);
try
// set initial values in dialog
dlg.SetValues( rData );
// show the dialog
result := dlg.ShowModal = mrOk;
// pull values from dialog
if result then
dlg.GetValues( rData );
finally
dlg.free;
end;
end;
GetValues/SetValues メソッドは、ルーチンで使用される値を保持するレコードまたはクラスからダイアログに入力します。フォームの外部からフォーム上のコントロールを操作しようとはしませんが、フォーム自体でそれを行うためのルーチンを記述します。
ロブのケネディは正しい..入力ボックスは良い選択肢ではありません...正確に何を保存しようとしていますか? Exe スペース、リソース、またはソース コード? それとも、「グリーン」コードで環境を保存したいだけですか?
InputQuery 関数を見ると、TForm を作成し、いくつかの TButtons/TLabels/TEdit を作成し、フォームを配置してモーダルに表示することがわかります。
プロジェクトに追加する新しいフォームで行うこととまったく同じです..検証、コントロールのカスタマイズ、配置、さらにはヒントの追加もできます...
新しいフォームで行こう...