看了 InputBox、InputQuery 函數實現的源碼, 有些收獲與心得...
通過 InputBox 可獲取用戶輸入的字符串:
procedure TForm1.Button1Click(Sender: TObject);
var
str: string;
begin
str := InputBox('輸入窗口標題' , '輸入提示', '默認輸入內容');
ShowMessage(str); //顯示輸入的內容
end;
InputBox 是調用了 InputQuery, InputQuery 是通過一個 var 參數獲取新字串:
procedure TForm1.Button2Click(Sender: TObject);
var
str: string;
begin
InputQuery('輸入窗口標題', '輸入提示', str);
ShowMessage(str); //顯示輸入的內容
end;
InputQuery 可返回一個 Boolean 值, 可判斷用戶是確認還是取消, 挺有用的:
procedure TForm1.Button3Click(Sender: TObject);
var
str: string;
begin
str := '默認輸入內容';
if InputQuery('輸入窗口標題', '輸入提示', str) then
ShowMessage(str); //如果點擊了 ok 按鈕將顯示輸入的內容
end;
我經常用到需要用戶輸入或選擇的窗口, 一般都是 Show 一個提前設計好的窗口; 這會浪費資源, InputQuery 的窗口應該是動態建立的.
但如果動態建立還是有諸多麻煩, 譬如給按鈕添加事件...
但查看 InputQuery 的源碼, 只有區區幾十行, 果然是動態建立的窗口, 但並沒有發現 "事件" 相關的代碼!
再看下去, 發現這和 "模式窗口" 有關, 假如不是用 ShowModal 啟動窗口的話, 恐怕 "事件" 代碼是非寫不可.
那 "模式窗口" 中的 "按鈕" 和 "模式窗口" 又是如何關聯的呢?
還是做起來看吧:
//主體代碼就這些:
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
frm.ShowModal;
frm.Free;
end;
同時動態添加進兩個按鈕:
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
with TButton.Create(frm) do begin
Caption := '確認';
Parent := frm;
Left := 100; top := 40;
end;
with TButton.Create(frm) do begin
Caption := '取消';
Parent := frm;
Left := 100; top := 80;
end;
frm.ShowModal;
frm.Free;
end;
但上面代碼寫出的按鈕並沒有任何作用, 其實只要設置一下按鈕的 ModalResult 屬性就可以了:
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
with TButton.Create(frm) do begin
Caption := '確認';
ModalResult := mrOk; {1}
Parent := frm;
Left := 100; top := 40;
end;
with TButton.Create(frm) do begin
Caption := '取消';
ModalResult := mrCancel; {2}
Parent := frm;
Left := 100; top := 80;
end;
frm.ShowModal;
frm.Free;
end;
按鈕的 ModalResult 屬性就是一個整數, 窗體也有相同的屬性; 點擊按鈕時它會傳遞給所屬窗體的同名(ModalResult)屬性; 這個屬性的默認值是 0, 非 0 時模式窗口即刻關閉.
另外: ShowModal 是個函數, 調用時會返回窗口的 ModalResult 值.
上面幾句話挺重要, 我也都從相關源碼中核實了.
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
with TButton.Create(frm) do begin
Caption := '確認';
ModalResult := mrOk; {1}
Parent := frm;
Left := 100; top := 40;
end;
with TButton.Create(frm) do begin
Caption := '取消';
ModalResult := mrCancel; {2}
Parent := frm;
Left := 100; top := 80;
end;
if frm.ShowModal = mrOk then
ShowMessage('確認了')
else
ShowMessage('沒有確認');
frm.Free;
end;
完善一下, 並添加兩個文本框准備接受信息:
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
frm.Position := poScreenCenter;
frm.ClIEntWidth := 270;
frm.ClIEntHeight := 100;
frm.Caption := '輸入對話框';
with TEdit.Create(frm) do begin
Parent := frm;
Name := 'Edit1';
SetBounds(10, 10, 100, 20);
end;
with TEdit.Create(frm) do begin
Parent := frm;
Name := 'Edit2';
SetBounds(150, 10, 100, 20);
end;
with TButton.Create(frm) do begin
Caption := '確認';
ModalResult := mrOk;
Default := True;
Parent := frm;
SetBounds(100, 40, 75, 25);
end;
with TButton.Create(frm) do begin
Caption := '取消';
ModalResult := mrCancel;
Cancel := True;
Parent := frm;
SetBounds(100, 70, 75, 25);
end;
if frm.ShowModal = mrOk then
begin
ShowMessage('確認了');
end;
frm.Free;
end;
如何傳回用戶輸入的信息呢? 我覺得用類似 InputQuery 函數中的 var 參數接受信息就挺好的, 這種方式用於接受復雜的信息也很方便; 不過要先把上面的代碼寫到一個函數裡:
{函數}
function GetInfo(var str1,str2: string): Boolean;
var
frm: TForm;
MyEdit1, MyEdit2: TEdit;
begin
Result := False;
frm := TForm.Create(Application);
frm.Position := poScreenCenter;
frm.ClIEntWidth := 270;
frm.ClIEntHeight := 100;
frm.Caption := '輸入對話框';
MyEdit1 := TEdit.Create(frm);
with MyEdit1 do begin
Parent := frm;
Text := str1;
SetBounds(10, 10, 100, 20);
end;
MyEdit2 := TEdit.Create(frm);
with MyEdit2 do begin
Parent := frm;
Text := str2;
SetBounds(150, 10, 100, 20);
end;
with TButton.Create(frm) do begin
Caption := '確認';
ModalResult := mrOk;
Default := True;
Parent := frm;
SetBounds(100, 40, 75, 25);
end;
with TButton.Create(frm) do begin
Caption := '取消';
ModalResult := mrCancel;
Cancel := True;
Parent := frm;
SetBounds(100, 70, 75, 25);
end;
if frm.ShowModal = mrOk then
begin
str1 := MyEdit1.Text;
str2 := MyEdit2.Text;
Result := True;
end;
frm.Free;
end;
{調用測試}
procedure TForm1.Button1Click(Sender: TObject);
var
s1,s2: string;
begin
s1 := 'aaa';
s2 := 'bbb';
if GetInfo(s1, s2) then ShowMessageFmt('%s - %s', [s1, s2]);
end;
完成了, 但這遠遠沒有 InputQuery 的源碼精彩; 不過從今往後再用到一個采集信息的對話框時, 我會盡量用這樣一個函數來完成; 這就是我閱讀 InputQuery 源碼的收獲.