在重写的KeyUp事件中,将焦点移动到下一个控件

13
我有一个继承自 TEdit 的自定义类:
  TMyTextEdit = class (TEdit)
   private
     fFocusNextOnEnter: Boolean;
   public
    procedure KeyUp(var Key: Word; Shift :TShiftState); override;
   published
     property FocusNextOnExnter: Boolean read fFocusNextOnEnter
                                 write fFocusNextOnEnter default false;
  end;

在KeyUp过程中,我执行以下操作:

procedure TMyTextEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited;

  if FocusNextOnExnter then
    if Key = VK_RETURN then 
      SelectNext(Self as TWinControl, True, false);
end;

但是它没有将焦点移动到下一个控件。我试过

if Key = VK_RETURN then
      Key := VK_TAB;

但它也没有起作用。我错过了什么吗?

4个回答

14

SelectNext会选择下一个兄弟子控件,也就是你需要在编辑器的父控件上调用它:

type
  THackWinControl = class(TWinControl);

if Key = VK_RETURN then
  if Assigned(Parent) then
    THackWinControl(Parent).SelectNext(Self, True, False);

谢谢,但它不像一个Tab键那样工作 - 它总是将焦点移动到表单上的第一个控件。 - JustMe
2
它应该根据其他兄弟控件的TabOrderTabStop属性移动到下一个控件。 - Ondrej Kelle
2
@JustMe,我刚刚测试了TOndrej的代码(因为我本来也要发布同样的内容,但他更快)。它完全正常工作,我的表单上有3个“TYourTextEdit”,焦点从一个转移到另一个,就像你期望的那样。 - Cosmin Prund
尝试将True作为最后一个参数(CheckTabStop)传递。 - Ondrej Kelle
4
如果父容器是表单上的多个容器之一,那么这段代码会只循环遍历该容器中的控件,还是会扩展到下一个容器的第一个控件? - David Heffernan
显示剩余2条评论

6
这里是使用PostMessage方法(使用消息)的方式来记录 :)
procedure TMyEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if FocusNextOnExnter then
    if Key = VK_RETURN then begin
      PostMessage(GetParentForm(Self).Handle, wm_NextDlgCtl, Ord((ssShift in Shift)), 0);
      Key := 0;
    end;
end;

5
procedure TMyEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin

  inherited;

  if FocusNextOnExnter and Focused and (Key = VK_RETURN) then 

  begin

    Perform(CM_DIALOGKEY, VK_TAB, 0);

    Key := 0;

  end;

end;

2
强烈建议在答案中添加一些描述,因为代码可能对每个人都不是自我描述的。 - Aleksei Zyrianov
非常棒,感谢Tacu Aureliu。 - NOTSermsak

0

可以避免使用THackWinControl,并使其更加美观:

SelectNext(ActiveControl as TWinControl, True, ssShift in Shift);

问题是它仍然下拉选择框的选项。
我正在处理这个问题。

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