Delphi 在TForm.OnKeyDown中使用KeyPreview处理密钥不适用于TListBox
A.创建VCL表单应用程序 B.在表格上放置一个TListBox,并在设计时填写一些项目,例如: C.将表单的Delphi 在TForm.OnKeyDown中使用KeyPreview处理密钥不适用于TListBox,delphi,onkeydown,delphi-10.1-berlin,keypreview,Delphi,Onkeydown,Delphi 10.1 Berlin,Keypreview,A.创建VCL表单应用程序 B.在表格上放置一个TListBox,并在设计时填写一些项目,例如: C.将表单的KeyPreview属性设置为True: D.在表单的OnKeyDown事件处理程序中编写以下代码: procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_BACK then begin if ListBox1.Focuse
KeyPreview
属性设置为True
:
D.在表单的OnKeyDown
事件处理程序中编写以下代码:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_BACK then
begin
if ListBox1.Focused then
begin
Key := 0;
CodeSite.Send('ListBox1 is focused!');
end;
end;
end;
E.运行程序,点击项目5选择:
现在ListBox1有了焦点
F.现在按退格键。假定,设置键:=0表单的OnKeyDown
事件处理程序中的code>应阻止ListBox1控件处理退格键。但这不起作用,如您所见:BACKSPACE键导致选择从Item5更改为Item1:
那么,如何防止在聚焦的ListBox控件中处理退格键并更改ListBox的选择
德尔福10.1柏林更新2
Windows 7 x64 SP1改用OnKeyPress
事件:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #8 then
begin
if ListBox1.Focused then
begin
Key := #0;
CodeSite.Send('ListBox1 is focused!');
end;
end;
end;
您不能总是在OnKeyDown
中阻止所有内容,请改用OnKeyPress
事件:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #8 then
begin
if ListBox1.Focused then
begin
Key := #0;
CodeSite.Send('ListBox1 is focused!');
end;
end;
end;
在OnKeyDown
阅读关于WM的内容时,您不能总是阻止所有内容_GETDLGCODE@DavidHeffernan:您建议从该消息返回什么值?没有任何标志表示忽略退格键击。您是否在考虑禁用DLGC\u wantKeys
和/或DLGC\u WANTCHARS
标志,或启用DLGC\u WANTMESSAGE
标志?您必须更具体一些。TranslateMessage在消息循环中的DispatchMessage之前被调用,因此您没有阻止将WM_字符(从WM_键向下翻译)发布到列表框。因此,雷米的答案是……阅读关于WM的文章_GETDLGCODE@DavidHeffernan:您建议从该消息返回什么值?没有任何标志表示忽略退格键击。您是否在考虑禁用DLGC\u wantKeys
和/或DLGC\u WANTCHARS
标志,或启用DLGC\u WANTMESSAGE
标志?您必须更具体一些。TranslateMessage在消息循环中的DispatchMessage之前被调用,因此您没有阻止将WM_字符(从WM_键向下翻译)发布到列表框。因此,雷米的回答……谢谢你,它起作用了。但这是令人惊讶的,因为OnKeyDown
发生在OnKeyPress
之前,尽管Key
在OnKeyDown
中显式设置为零,事件OnKeyPress
仍然被调用!我一直相信像BACKSPACE
这样的键不会触发OnKeyPress
。通常,如果OnKeyPress
拒绝一个键,则不会调用OnKeyPress
。请注意,我的回答是使用OnKeyPress
而不是OnKeyDown
,而不是使用它。在任何情况下,OnKeyDown/Up
中的Key
是一个虚拟键代码,但是OnKeyPress
中的Key
是一个翻译字符,因此它们的值并不总是相同的(在这种情况下,它们是相同的)。奇怪的是,用键:=0阻塞HOME
键和END
键OnKeyDown
中的code>起作用,并且这些键未触发任何OnKeyPress
事件。为什么?为什么这些键的处理方式不同?Home
和End
不是字符,根本不触发OnKeyPress
(试试看)<代码>退格
是一个字符(Unicode代码点U+0008
)OnKeyDown/Up
被触发,以响应从键盘携带虚拟键代码的WM\u KEYDOWN/Up
消息,即使对于非字符键也是如此,但是OnKeyPress
在响应仅携带字符的WM\u CHAR
时被触发:“[WM\u CHAR
]当TranslateMessage()
函数翻译WM_KEYDOWN
消息时,以键盘焦点发布到窗口。WM_CHAR
消息包含按下键的字符代码“感谢您的详细解释,非常感谢!谢谢,它很有效。但这是令人惊讶的,因为OnKeyDown
发生在OnKeyPress
之前,尽管Key
在OnKeyDown
中显式设置为零,事件OnKeyPress
仍然被调用!我一直相信像BACKSPACE
这样的键不会触发OnKeyPress
。通常,如果OnKeyPress
拒绝一个键,则不会调用OnKeyPress
。请注意,我的回答是使用OnKeyPress
而不是OnKeyDown
,而不是使用它。在任何情况下,OnKeyDown/Up
中的Key
是一个虚拟键代码,但是OnKeyPress
中的Key
是一个翻译字符,因此它们的值并不总是相同的(在这种情况下,它们是相同的)。奇怪的是,用键:=0阻塞HOME
键和END
键OnKeyDown
中的code>起作用,并且这些键未触发任何OnKeyPress
事件。为什么?为什么这些键的处理方式不同?Home
和End
不是字符,根本不触发OnKeyPress
(试试看)<代码>退格
是一个字符(Unicode代码点U+0008
)OnKeyDown/Up
被触发,以响应从键盘携带虚拟键代码的WM\u KEYDOWN/Up
消息,即使对于非字符键也是如此,但是OnKeyPress
在响应仅携带字符的WM\u CHAR
时被触发:“[WM\u CHAR
]当TranslateMessage()
函数翻译WM_KEYDOWN
消息时,以键盘焦点发布到窗口。WM_CHAR
消息包含按下键的字符代码“感谢您的详细解释,非常感谢!