delphi - 在 TComboBox 或 TButton 上按 VK_LEFT 时不会触发 OnKeyDown 事件

标签 delphi

当在 TCheckBox 或 TButton 控件上按下 VK_LEFT 键时,是否有办法触发 OnKeyDown 事件。目前,它只是选择另一个控件,但不会触发该事件。

更新

这是我的代码,用于像 TAB Back 一样使用 VK_LEFT 键。

首先,我需要在某些控件上禁用 VK_LEFT 的标准行为,例如(TCheckBox、TButton...):

procedure TfmBase.CMDialogKey(var Message: TCMDialogKey);
begin
  if Message.CharCode <> VK_LEFT then
    inherited;
end;

然后,TCheckBox、TButton 上的 VK_LEFT 也会触发 OnKeyDown 事件,...在该事件上,我放置了代码来选择前一个控件。 KeyPreview 当然必须是 true。

procedure TfmBase.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  handled: Boolean;
begin
  if Key = VK_LEFT then
  begin
    handled := false;
    TabBack(handled); //This is my function, which checks the type of the control and selects the previous control.
    if handled then
      Key := 0;
  end;
end;

最佳答案

您不会触发该事件,因为该按键被解释为表单导航。顶层消息循环识别出这是一个导航键并转移消息以执行该导航。

如果您想处理此事件,那么唯一的机会是在 Application.OnMessage 中,该事件在消息转移之前触发。

更新

在评论中,您表明您想要拦截此事件以执行导航。由于正在执行默认导航而未触发该事件,因此也许理想的解决方案是覆盖默认导航。

我相信驱动此操作的关键例程是 TWinControl.CNKeyDown。通读这段代码,我认为您只需要在表单中处理 CM_DIALOGKEY 并说服导航按照您希望的方式运行。

您的代码应如下所示:

procedure TMyForm.CMDialogKey(var Message: TCMDialogKey);
begin
  if GetKeyState(VK_MENU) >= 0 then begin
    case Message.CharCode of
    VK_LEFT:
      if ActiveControl=MyControl1 then begin
        MyControl2.SetFocus;
        Message.Result := 1;
        Exit;
      end;
    end;
  end;
  inherited;
end;

关于delphi - 在 TComboBox 或 TButton 上按 VK_LEFT 时不会触发 OnKeyDown 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5064349/

相关文章:

delphi - 使用 GDI+ 居中旋转图像

Delphi Statictext字体颜色变化无样式

Delphi:使用TClientDataset作为内存数据集

delphi - 在 Delphi xe2 中初始化给定类的变量

delphi - 如何从派生类访问隐藏成员?

Delphi 5 编译器错误返回接口(interface)指针而不是返回值

如果您无权执行需要管理员权限的操作(例如安装服务),Delphi 代码会显示友好消息

delphi - 调整实例类内存分配的大小

delphi - 如何找到丢失的TActionList

delphi - 如何让 VCL 和 FMX 组件具有相同的名称?