3

我有一个框架和一些控件(编辑、按钮等)。如何拦截框架控件上任意位置的 ENTER 键并转换为 TAB 键(考虑到 SHIFT 状态)?

4

3 回答 3

7

您只需要修改CM_DIALOGKEY.

type
  TMyForm = class(TForm)
  protected
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
  end;

procedure TMyForm.CMDialogKey(var Message: TCMDialogKey);
begin
  if Message.CharCode=VK_RETURN then
    Message.CharCode := VK_TAB;
  inherited;
end;

好吧,很明显这是做什么以及它是如何工作的。

你问如何在一个框架中做到这一点。无法在框架中处理对话框导航。出于相当明显的原因,这是由表单完成的。因此,您需要以某种方式将此代码拼接到承载您的框架的表单中。

对于备忘录控件,这将无效。他们会将按下ENTER视为换行符的输入。但我想这就是你希望发生的事情。否则备忘录控件将完全无法使用。

于 2013-03-11T14:09:43.863 回答
5

Enter这是一些示例代码,它们将处理框架上的消息,以便在按下时能够导航到下一个控件。请注意,此示例不会将Enter密钥修改为Tab密钥。相反,它选择下一个控件并阻止对按键消息的进一步处理。

另请注意,代码可能需要进一步调整。一个是,如果任何控件实际上需要处理Enter密钥,例如 a TMemo,则需要添加一个异常。其次,导航被包裹在框架中,即在最后一个框架控件之后,第一个框架控件被聚焦 - 不是窗体上的控件,而不是框架上的控件。对于这些,您可能希望为消息返回添加条件,如果您希望在某些条件下进行默认处理,只需调用继承而不做任何其他事情。

type
  TFrame2 = class(TFrame)
    ...
  protected
    procedure CMChildKey(var Message: TCMChildKey); message CM_CHILDKEY;
  end;

..

procedure TFrame2.CMChildKey(var Message: TCMChildKey);
begin
  if Message.CharCode = VK_RETURN then begin
    SelectNext(Screen.ActiveControl, not Bool(GetKeyState(VK_SHIFT) and $80), True);
    Message.Result := 1;
  end else
    inherited;
end;
于 2013-03-12T00:39:33.277 回答
0

我认为有很多“丢弃并忘记”组件可以做到这一点,例如在http://Torry.net

例如,这样的组件是 RxLib 的一部分,后来以TJvEnterAsTab名称继承到 JediVCL 中。

于 2013-03-12T07:33:07.693 回答