OnKeyDown不能处理从主窗体调用的Dialog(它也使用OnKeyDown)

时间:2013-03-03 17:44:54

标签: delphi delphi-2010

Delphi 2010

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

//主要表格

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;

//对话框

procedure TfrmOwned.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;

Form的OnKeyDown工作正常,但我似乎无法使对话框起作用

1 个答案:

答案 0 :(得分:6)

问题是这些键用作对话框导航键。因此,他们永远不会进入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事件实现快捷方式。这似乎是错误的解决方案。正确的解决方案是使用操作。创建一个动作列表。为第一个,最后一个,上一个和下一个操作添加操作。为他们提供适当的ShortCut属性。将这些操作分配给按钮。工作已经完成。

这样做的好处之一是您可以停止尝试伪造按钮点击事件。对于它的价值,调用OnClick是错误的方法。如果您确实需要这样做,请调用按钮的Click方法。但是,使用一个动作就可以了。

另一个好处是你不再需要KeyPreview。简而言之,如果您想实施捷径,请使用TAction.ShortCut