Delphi OnKeyDown不处理从主窗体调用的对话框(也使用OnKeyDown)

Delphi OnKeyDown不处理从主窗体调用的对话框(也使用OnKeyDown),delphi,delphi-2010,Delphi,Delphi 2010,德尔福2010 我在主窗体上使用OnFormKeyDown事件,在对话框上基本上使用相同的事件 //主要形式 procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_DOWN: btnLast.OnClick(Self); VK_Up: btnFirst.OnClick(Self); VK_Lef

德尔福2010

我在主窗体上使用OnFormKeyDown事件,在对话框上基本上使用相同的事件

//主要形式

procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   case Key of
      VK_DOWN: btnLast.OnClick(Self);
      VK_Up:  btnFirst.OnClick(Self);
      VK_Left:  btnPrev.OnClick(Self);
      VK_Right:  btnNext.OnClick(Self);
    end;
end;

procedure TfrmMain.mniShowOwnedClick(Sender: TObject);
var
 I: Integer;
begin
 frmMain.KeyPreview:= False;
 frmOwned.KeyPreview:= True;
 frmOwned.Owned2.Clear;
 for I := 0 to Tags.Count - 1 do
  if Owned.IndexOf(Tags.Names[I]) <> -1 then
     frmOwned.Owned2.Add(Tags[I]);
 if frmOwned.ShowModal = mrOK then
 begin
  frmMain.KeyPreview:= True;
  frmOwned.KeyPreview:= False;
 end;
end;

表单的OnKeyDown工作正常,但我似乎无法让对话框正常工作

问题是这些键被用作对话框导航键。因此,他们从不去参加
OnKeyDown
事件

老实说,我很难理解他们为什么要为你的主窗体的
OnKeyDown
事件开火。我无法在我的测试环境中实现这一点。那是因为我在表单中添加了一个按钮。这就意味着箭头键被视为导航键。尝试用一个表单创建一个应用程序,并添加几个按钮。然后运行应用程序并使用箭头键在按钮之间移动焦点。这就是我所说的箭头键被视为导航键的意思

我认为这两个表单之间的区别在于主表单没有可以通过箭头键导航的内容,而模态表单有

现在,您可以停止将箭头键视为导航键。像这样:

type
  TMyForm = class(TForm)
  ....
  protected
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
  ....
  end;
....
procedure TMyForm.CMDialogKey(var Message: TCMDialogKey);
begin
  case Message.CharCode of
  VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN:
    Message.Result := 0;
  else
    inherited;
  end;
end;
然而,在我看来,更好的解决方案是停止尝试使用
OnKeyDown
事件实现快捷方式。这似乎是错误的解决方案。正确的解决方案是使用动作。创建一个操作列表。为第一个、最后一个、上一个和下一个操作添加操作。为他们提供适当的
快捷方式
属性。将这些操作分配给按钮。工作完成了

这样做的好处之一是,您可以停止尝试伪造按钮单击事件。无论如何,调用
OnClick
是错误的方法。如果确实需要,请调用按钮的
单击
方法。然而,使用一个动作,它就被处理好了


另一个好处是,您不再需要使用
KeyPreview
四处走动。简单地说,如果您想要实现快捷方式,实际上可以使用
TAction.ShortCut

,但是表单是相同的,因此使用相同的OnKeyDown事件。对话框窗体缺少另一个按钮和一些标签,但除此之外,缺少相同的导航按钮。不过我会试试你的行动清单。我过去成功地使用过它们,所以我知道你的意思,行动上的捷径肯定会激发。毫无疑问,这就是路。上、下、左、右的捷径是什么?呃,上、下、左、右。在对象检查器中键入这些字符串。@Johnny-我也会冒险的。。在主窗体中将按钮的“TabStop”设置为false,但在自己的窗体中忘记了这样做。
type
  TMyForm = class(TForm)
  ....
  protected
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
  ....
  end;
....
procedure TMyForm.CMDialogKey(var Message: TCMDialogKey);
begin
  case Message.CharCode of
  VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN:
    Message.Result := 0;
  else
    inherited;
  end;
end;