使用 return 键从 TEdit 移动到 TDBGrid 时出现问题
Problem when using return key to move to TDBGrid from TEdit
在搜索表单中,我有两个组成部分,TEdit
和 TDBGrid
。用户在 TEdit
中输入文本,在 TEdit.OnChange
事件中,我使用查询在 table 中搜索匹配项。这些显示在 TDGrid
中。仅当用户在 TEdit.Text
中输入超过三个字符以减少开销时才会触发该事件。
当搜索 return 了所有可能的记录并且用户想要 select TDBGrid
中显示的记录之一时,就会出现问题。当我告诉用户使用 Tab
键(或鼠标)从 TEdit
切换到 TDBGrid
时,他们使用 return 键在另一个中执行此操作应用程序,并坚持认为他们应该能够在我 altering/adding 的应用程序中做同样的事情。我能理解这一点,但问题是如果我使用
if (key = VK_RETURN) then key := VK_TAB;
在 TEdit.OnKeyUp
事件中,TEdit
中最后按下的键的原始值被“记住”为 VK_RETURN
并传递给 TDBGrid
' s OnKeyUp
事件。由于我在该事件中触发了其他操作,所以一旦 TDBGrid
获得焦点,我就会发生不希望的事情,因为他们还想通过按 return select 网格中的正确行再次键入。
因此我想做的是“取消”从TEdit
传递给TDBGrid
的键值。我尝试在 DGBrid
的 OnKeyUp
事件中使用 if (Sender = TEdit) then Key := VK_CANCEL;
,但出现编译器“类型不兼容”错误,我找不到任何信息告诉我应该如何在此使用它情况。
这可能吗?还是我做错了?
提前致谢!
我相信以下方法可以满足您的需求,并且我怀疑它是最短的此类方法:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
Key := #0;
end;
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_RETURN then
begin
PostMessage(Handle, WM_NEXTDLGCTL, 0, 0);
Key := 0;
end;
end;
这将使 Enter,在 Edit1
中,将焦点移动到下一个控件。这是通过向表单发送 WM_NEXTDLGCTL
消息来完成的。需要 OnKeyPress
处理程序来抑制“无效输入”消息提示音。
要获得奖励积分,请执行
PostMessage(Handle, WM_NEXTDLGCTL, Ord(ssShift in Shift), 0);
而不是 Shift+Enter 对应 Shift+ Tab.
不过,我不太确定我是否喜欢这整个想法。我想我更喜欢让 Enter 按下按键。目标控件不应该关心这个按键消息。
补充一下 Andreas 的回答,我使用了相同的方法。您可以使用 3 个事件,onkeydown、onkeypress、onkeyup。在某些时候,您可能必须将密钥分配给 null 以避免“哔”声。另一件需要注意的事情是意外的副作用,比如移动 2 个字段而不是我过去发生的一个字段。
在搜索表单中,我有两个组成部分,TEdit
和 TDBGrid
。用户在 TEdit
中输入文本,在 TEdit.OnChange
事件中,我使用查询在 table 中搜索匹配项。这些显示在 TDGrid
中。仅当用户在 TEdit.Text
中输入超过三个字符以减少开销时才会触发该事件。
当搜索 return 了所有可能的记录并且用户想要 select TDBGrid
中显示的记录之一时,就会出现问题。当我告诉用户使用 Tab
键(或鼠标)从 TEdit
切换到 TDBGrid
时,他们使用 return 键在另一个中执行此操作应用程序,并坚持认为他们应该能够在我 altering/adding 的应用程序中做同样的事情。我能理解这一点,但问题是如果我使用
if (key = VK_RETURN) then key := VK_TAB;
在 TEdit.OnKeyUp
事件中,TEdit
中最后按下的键的原始值被“记住”为 VK_RETURN
并传递给 TDBGrid
' s OnKeyUp
事件。由于我在该事件中触发了其他操作,所以一旦 TDBGrid
获得焦点,我就会发生不希望的事情,因为他们还想通过按 return select 网格中的正确行再次键入。
因此我想做的是“取消”从TEdit
传递给TDBGrid
的键值。我尝试在 DGBrid
的 OnKeyUp
事件中使用 if (Sender = TEdit) then Key := VK_CANCEL;
,但出现编译器“类型不兼容”错误,我找不到任何信息告诉我应该如何在此使用它情况。
这可能吗?还是我做错了?
提前致谢!
我相信以下方法可以满足您的需求,并且我怀疑它是最短的此类方法:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
Key := #0;
end;
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_RETURN then
begin
PostMessage(Handle, WM_NEXTDLGCTL, 0, 0);
Key := 0;
end;
end;
这将使 Enter,在 Edit1
中,将焦点移动到下一个控件。这是通过向表单发送 WM_NEXTDLGCTL
消息来完成的。需要 OnKeyPress
处理程序来抑制“无效输入”消息提示音。
要获得奖励积分,请执行
PostMessage(Handle, WM_NEXTDLGCTL, Ord(ssShift in Shift), 0);
而不是 Shift+Enter 对应 Shift+ Tab.
不过,我不太确定我是否喜欢这整个想法。我想我更喜欢让 Enter 按下按键。目标控件不应该关心这个按键消息。
补充一下 Andreas 的回答,我使用了相同的方法。您可以使用 3 个事件,onkeydown、onkeypress、onkeyup。在某些时候,您可能必须将密钥分配给 null 以避免“哔”声。另一件需要注意的事情是意外的副作用,比如移动 2 个字段而不是我过去发生的一个字段。