如何避免在 TEdit 聚焦时按下 Escape 时发出叮当声?

发布于 2024-07-16 21:33:55 字数 728 浏览 8 评论 0原文

在我几年前开发的代码中,我经常使用它来随时按 Escape 键关闭当前表单:

procedure TSomeForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
    if key = #27 then close;
end;

此行为是为 TForm 定义的。 表单的 KeyPreview 属性设置为 True 以使表单在任何其他组件之前对按键做出反应。 对于程序的最佳部分来说,这一切都运行得很好,但是,当 TEdit 组件聚焦时按下 Escape 键时,会发出声音(Windows 使用声音来表示无效操作) 。 它仍然工作正常,但我从未完全消除声音。

这有什么问题吗?


重新创建的步骤:

  • 新的 VCL Forms 应用程序,将表单的 KeyPreview 设置为 true
  • 在“事件”选项卡上双击 onKeyPress 事件并输入虚拟代码:

    if key=#27 then ;

  • 将 TListBox、TCheckBox、TEdit 添加到表单并运行应用程序

  • 在应用程序中尝试按 Esc 键,但没有任何反应,如虚拟指定的那样代码
  • 将焦点置于 TEdit 并按 Esc。 没有任何反应,但会播放声音。

In code I have developed some years ago I have been using this a lot to close the current form on pressing the Escape key at any moment:

procedure TSomeForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
    if key = #27 then close;
end;

This behaviour is defined for the TForm. The form's KeyPreview property is be set to True to let the form react to key presses before any other components. It all works perfectly well for the best part of the program, however, when the Escape key is pressed while a TEdit component is focused a sound (a ding sound used by Windows to signify invalid operation) is issued. It still works fine but I have never quite managed to get rid of the sound.

What's the problem with this?


Steps to recreate:

  • new VCL Forms application, set the form's KeyPreview to true
  • on the Events tab double-click the onKeyPress event and enter dummy code:

    if key=#27 then ;

  • add a TListBox, TCheckBox, TEdit to the form and run the application

  • in the application try pressing Esc and NOTHING happens, as specified by the dummy code
  • focus the TEdit and press Esc. Nothing happens but the sound is played.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吹泡泡o 2024-07-23 21:33:55

您收到叮当声是因为您将 ESC 留在了输入中。 看看 Key 是如何成为 var 的? 将其设置为#0,即可消除叮当声。 这使其免于进一步处理。

procedure TSomeForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
    if key = #27 then 
    begin
      key := #0;
      close;
    end;
end;

KeyPreview 就是这样,预览将传递给控件的内容,除非您停止它。

You get the ding because you left the ESC in the input. See how Key is a var? Set it to #0 and you eliminate the ding. That removes it from further processing.

procedure TSomeForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
    if key = #27 then 
    begin
      key := #0;
      close;
    end;
end;

KeyPreview is just that, a preview of what will be passed to the controls unless you stop it.

划一舟意中人 2024-07-23 21:33:55

使用菜单项并将其设置为不可见,并使用快捷方式,是我刚刚偶然发现的一种快速解决方法,但如果您需要使用在第一个字母中使用的字符的快捷方式,则该方法不起作用现有快捷方式:例如,对于 Alt+ENTER,您需要将类似的内容添加到表单创建过程中:

MainMenu1.Items[0].ShortCut:=TextToShortCut('Alt+e');

但是,使用 TActionList 可能更容易,即使未列出类似 Alt+E 的内容,您也可以添加它。

Using the menu items and setting them to invisible, and using the shortcut, is a quick workaround that I've just stumbled across, but won't work if you need a shortcut that uses a character that is used in the first letter of an existing shortcut: For example for Alt+ENTER, you need to add something like this to the form create procedure:

MainMenu1.Items[0].ShortCut:=TextToShortCut('Alt+e');

However it's probably easier to use TActionList instead, and even though something like Alt+E is not listed you can add it.

孤蝉 2024-07-23 21:33:55

从吉姆的回答开始(谢谢吉姆),我必须让它对我有用。 我需要的是制作一个下拉组合框,关闭时保留所选项目,并在按下 TAB/shift+TAB 时移动到下一个/上一个控件。 每次我按下 TAB 键,恼人的声音就会充满房间。 我的工作是使用 onKeyDown 事件来捕获 shiftstate,在表单界面中声明 var aShift: boolean; 并使用以下代码:

procedure TForm2.StComboKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if ssShift in Shift then aShift := true else aShift := false;
end;

procedure TForm2.StComboKeyPress(Sender: TObject; var Key: Char);
begin
 if Key=char(VK_TAB) then
   begin
     Key := #0;
     StCombo.DroppedDown := false;
     if aShift
       then previousControl.SetFocus
       else nextControl.SetFocus;
   end;
end;

Starting from Jim's answer (thanks Jim) I had to make it work for me. What I needed was to make a dropped down combobox close keeping the selected item and move to the next/previous control when TAB/shift+TAB was pressed. Everytime I did press TAB the annoying sound filled the room. My work arroud was using onKeyDown event to catch the shiftstate, declaring var aShift: boolean; in form's interface and use the following code:

procedure TForm2.StComboKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if ssShift in Shift then aShift := true else aShift := false;
end;

procedure TForm2.StComboKeyPress(Sender: TObject; var Key: Char);
begin
 if Key=char(VK_TAB) then
   begin
     Key := #0;
     StCombo.DroppedDown := false;
     if aShift
       then previousControl.SetFocus
       else nextControl.SetFocus;
   end;
end;
酒浓于脸红 2024-07-23 21:33:55

这是一个旧线程...但无论如何,这里有一个更好的线程:捕获 Alt-C

与 ESC 不同,Alt-C 不由 KeyPress 提供服务,因此在 KeyPress 中将 Key 设置为 #0 不起作用,并且会发出可怕的“叮!”声。 每次都会发出。
经过几个小时的尝试,这是我找到的解决方法:
- 创建一个主菜单选项来服务请求
- 将其快捷方式设置为 Alt+C - 是的,确实,这不是可用的快捷方式选择之一(!!)...但无论如何它确实有效!
- 在该菜单选项的 OnClick 中进行处理
- 您甚至可以在“后台”中进行设置:您可以将菜单选项的 Visible 设置为 false - 只要其 Enabled 保持 true,即使它在菜单中不可见,它也会被 Alt-C 激活。

希望能有所帮助! 如果您有更优雅的东西,请提出建议。

It's an old thread... but anyway, here's a far better one: catching Alt-C!

Unlike ESC, Alt-C isn't serviced by KeyPress, so setting Key to #0 in KeyPress doesn't work, and the horrendous "ding!" is issued every time.
After hours of trying, here's the workaround I found:
- create a main menu option to service the request
- set its ShortCut to Alt+C - yes indeed, that is NOT one of the available ShortCut choices(!!)... but it does work anyway!
- do the processing in that menu option's OnClick
- you may even make in "in the background": you may set the menu option's Visible to false - as long as its Enabled stays true, it will be activated by Alt-C even though it will not be visible in the menu.

Hope that may help! And if you have something more elegant, please advise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文