看了 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 源码的收获.