【问题标题】:OnKeyDown not working on Dialog invoked from main form (which also uses OnKeyDown)OnKeyDown 不适用于从主窗体调用的对话框(也使用 OnKeyDown)
【发布时间】:2013-03-03 17:44:53
【问题描述】:

德尔福 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;

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

【问题讨论】:

    标签: delphi delphi-2010


    【解决方案1】:

    问题是这些键被用作对话框导航键。因此,他们从未参加过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

    【讨论】:

    • 实际上,但表单是相同的,因此相同的 OnKeyDown 事件。对话框表单缺少另一个按钮和一些标签,但除此之外,相同的导航按钮。不过,我会试试你的行动清单。我过去成功使用过它们,所以我知道您的意思
    • 动作的快捷方式肯定会触发。毫无疑问,这是要走的路。
    • 上、下、左、右的快捷键是什么?
    • 呃,上,下,左,右。在对象检查器中输入这些字符串。
    • @Johnny - 我也会抓住机会。您在主表单中将按钮的“TabStop”设置为 false,但忘记在自己的表单中执行相同操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多