窗体上放一个 BitBtn1, 设置其属性 Kind 的值为 bkClose; 然后运行看看...
结果是: 不仅自动更改了标题、图标, 并且还真的有了关闭窗口的功能.
实话说, 这之前我不知道这个小功能.
TBitBtn 的 Kind 属性对应的是一个枚举:
TBitBtnKind = (bkCustom, bkOK, bkCancel, bkHelp, bkYes, bkNo, bkClose, bkAbort, bkRetry, bkIgnore, bkAll);
再试其他值, 除了图标的变化外, 貌似没有其他功能了, 为什么 bkClose 可以关闭窗口?
代码追踪到 TBitBtn 重写的 Click 方法, 就明白了:
procedure TBitBtn.Click;
var
Form: TCustomForm;
Control: TWinControl;
begin
case FKind of
bkClose:
begin
Form := GetParentForm(Self);
if Form <> nil then Form.Close
else inherited Click;
end;
bkHelp:
begin
Control := Self;
while (Control <> nil) and (Control.HelpContext = 0) do
Control := Control.Parent;
if Control <> nil then Application.HelpContext(Control.HelpContext)
else inherited Click;
end;
else
inherited Click;
end;
end;
看来不只是 bkClose, 还有 bkHelp 也赋予了功能, 当然这得先给窗体关联了帮助文件才行.
那其他呢? 譬如 bkOK、bkCancel 等等, 难道只是更换个图标那么简单?
当代码追踪到:
procedure TBitBtn.SetKind(Value: TBitBtnKind); begin ... ModalResult := BitBtnModalResults[Value]; ... end;
原来 TBitBtn 不同的 Kind 属性决定着其 ModalResult 的值, 并且根据 BitBtnModalResults 的定义, 知道了 Kind 与 ModalResult 的对应关系:
bkCustom { ModalResult = 0 }
bkOK { ModalResult = 1 }
bkCancel { ModalResult = 2 }
bkHelp { ModalResult = 0 }
bkYes { ModalResult = 6 }
bkNo { ModalResult = 7 }
bkClose { ModalResult = 0 }
bkAbort { ModalResult = 3 }
bkRetry { ModalResult = 4 }
bkIgnore { ModalResult = 5 }
bkAll { ModalResult = 8 }
什么是 ModalResult, 这是模式窗口(用 ShowModal 方法打开的窗口)的返回值.
这个 ModalResult 不是 TBitBtn 的吗? 和窗口有什么关系? 继续追踪代码:
procedure TCustomButton.Click; var Form: TCustomForm; begin Form := GetParentForm(Self); if Form <> nil then Form.ModalResult := ModalResult; inherited Click; end;
原来在按钮点击时, 按钮的 ModalResult 值就付给了窗体的同名属性.
对模式窗口来讲, 如果给 ModalResult 赋的值大于 0, 模式窗口将即刻关闭, 测试下:
//代码功能:
//点击按钮弹出一个模式窗口;
//在模式窗口中画有 11 个 TBitBtn 按钮, 分别设置了不同的 Kind 属性;
//鼠标指向按钮, Hint 提示出按钮的 ModalResult 值.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons; { TBitBtn 在 Buttons 单元 }
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
const
w = 75; h = 25; a = 8; b = 8;
var
ModalForm: TForm;
i,x,y: Integer;
begin
Application.HintColor := clRed;
ModalForm := TForm.Create(Application);
ModalForm.ClientWidth := (w + a) * 6 + a;
ModalForm.ClientHeight := (h + b) * 2 + b;
ModalForm.Caption := 'ModalFormTest';
x := a; y := b;
for i := 0 to 10 do
begin
with TBitBtn.Create(ModalForm) do
begin
Parent := ModalForm;
Kind := TBitBtnKind(i);
Hint := Format(' %d ', [ModalResult]);
ShowHint := True;
SetBounds(x, y, w, h);
Inc(x, w + a);
if i = 5 then
begin
x := a;
Inc(y, h + b);
end;
end;
end;
ModalForm.ShowModal;
end;
end.
点击按钮后, 弹出窗口的效果图如下:

其中有 3 个按钮的值是 0, 也就是说点击它们窗口不应该关闭, 但点击 Kind 属性是 bkClose 的按钮窗口也还是关闭了, 尽管它的 ModalResult 值也是 0.
这不矛盾, 又回到刚开始的问题了, 这是 TBitBtn 重写的 Click 方法赋予的功能.
其他按钮行吗? 譬如: TButton.
看了一下, TButton 根本没有 Kind 属性, 但它有 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;
其他控件行吗? 譬如 TEdit.
查了一下, 它没有 ModalResult 属性, 但它所在的窗口有啊.
譬如下面的例子, 在模式窗口的 Edit 中输入 "Exit" 即可关闭该模式窗口:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure EditChange(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
frm: TForm;
begin
frm := TForm.Create(Application);
with TEdit.Create(frm) do begin
Parent := frm;
Left := 100; top := 40;
CharCase := ecLowerCase;
OnChange := EditChange; //
end;
frm.ShowModal;
frm.Free;
end;
{ 这是供动态建立的 TEdit 的 OnChange 事件调用的方法 }
procedure TForm1.EditChange(Sender: TObject);
begin
if TEdit(Sender).Text = 'exit' then
GetParentForm(TEdit(Sender)).ModalResult := 1;
end;
end.
浙公网安备 33010602011771号