Modaldialog对enter/esc键没有反应。

8
我有一个带有OKCancel按钮的模态对话框。我将OKDefault属性设置为True,将Cancel按钮的Cancel属性设置为True。ModalResult分别设置为mrOKmrCancel

然而,无论是按下键盘上的Enter还是Esc键,都不能关闭对话框。我错过了什么吗?

编辑
我在我的网站上发布了一个使用怀疑的对话框的小测试应用程序。IDE是RAD Studio XE3。

enter image description here


1
你是否将ModalResult属性设置为mrOk/mrCancel? - LU RD
@lurd - 是的,我做了(否则按钮也不会起作用)。我会将信息添加到我的问题中。感谢您的回复。 - stevenvh
你是否使用ShowModal方法调用模态对话框?只是为了确认一下。否则,我建议您创建一个小的可编译示例来演示您的问题。 - LU RD
@lurd - 是的,我调用了ShowModal。我在我的网站上发布了一个测试应用程序 - stevenvh
这似乎与TSpinEdit有关; 如果您将TEdit添加到表单中,则在TEdit获得焦点时,Enter和Esc将正常工作,但在TSpinEdit获得焦点时不起作用。 - davea
@davea,当TStringGrid编辑器处于活动状态时,它的行为与TSpinEdit相同。当编辑器处于非活动状态时,按下esc键会关闭对话框,而按下enter键则会调用编辑器(前提是设置了goEditing选项)。 - LU RD
2个回答

5

从您发布的示例中,您可以看到TSpinEdit控件已获得焦点并捕获了按键。

为了在所有情况下关闭模态窗体,请将窗体的KeyPreview设置为true,并将以下内容插入OnKeyPress事件中:

procedure TSelectDlg.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = Char(vk_escape)) then  // #27
    CancelBtn.Click
  else
  if (Key = Char(vk_return)) then  // #13
    OkBtn.Click;    
end;

虽然我同意这解决了问题(感谢您),但它也带来了一个新的问题:如果我们必须自己编写代码来模拟按键,那么CancelDefault属性有什么用处呢?此外,如果我没有setfocus行,也需要这段代码。 - stevenvh
1
如果使用Tab键使OK按钮获得焦点,则可以使用回车键退出而无需其他代码。这是Windows的默认行为。当没有其他获取按键的控件被关注时,将处理取消和默认属性。 - LU RD
明白了。看起来我对“Cancel”和“Default”属性期望过高了 :-)。 (自上次使用Delphi以来已经有一段时间了) - stevenvh
@Silver 我不认为这与那些方法有任何关系。但是我对平台标准的理解是错误的。单行编辑不想处理回车键。 - David Heffernan
@silver,就像Allen所说的那样。 - David Heffernan
显示剩余3条评论

5
记录一下,这应该是可以工作的。然而,似乎TSpinEdit存在一个Bug。由于TSpinEdit是一个示例(VCL.Samples.Spin.pas,注意“Samples”),您可以自己修复此问题。
在WMCut后面添加以下方法声明即可:
   procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;

完成课程(Shift+Ctrl+C)并将以下代码添加到WMGetDlgCode:

procedure TSpinEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  Message.Result := Message.Result and not DLGC_WANTALLKEYS;
end;

这将告诉VCL编辑控件不希望处理回车和Esc键(VK_ENTER,VK_ESCAPE)。由于它不处理这些键,它们将被转发到按钮,然后根据其设置(默认和取消)调用。

欢迎在Quality Central上报告此问题。


也许现在是考虑用真正的上下控制来替换那个“示例”的时候了。 - TLama
喜欢TUpDown组件吗?它已经存在了一段时间,就像Delphi 2或3以来一样。 - Allen Bauer
@LURD 请问您能否编辑一下QC吗?这个问题从Delphi 7开始就一直存在,甚至可能还有更早版本。Delphi 7的编译器版本是15,但您输入的是20,相当于Delphi 2009。 - SilverWarior
@SilverWarior,20 是 Delphi-XE6。我不确定,但我认为应该添加展示 Bug 的最新版本。无论如何,我已经添加了一个注释,指出至少从 D7 起就存在这个问题。 - LU RD
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接