【问题标题】:How implement OnKeyDown event in TFrame如何在 TFrame 中实现 OnKeyDown 事件
【发布时间】:2013-10-08 22:21:49
【问题描述】:

为了解决我们系统中的一些问题,我需要在 Frames (TFrame) 中实现事件OnKeyDownOnKeyPress。目前做了一个姑息的解决方案,但它非常丑陋并且存在任何问题。

过程大致如下:

1) 我在继承自 TFrame 的基类中创建了事件 OnKeyDownOnKeyPress

2) 在基于 TForm 的标准表单中,实现了一个拦截执行键的控件。所以,这个过程在框架上执行第一个关键事件,然后在表单上执行关键事件。

我不得不这样做,因为我希望 OnKeyDown 事件在帧之前和窗体之后执行。实现工作,但我会考虑更好的代码。

谁能提出更好的解决方案?有没有更优雅的方法来解决这个问题?

【问题讨论】:

  • 不确定,但我认为最初的问题需要这样编辑: 1. 我在 TFrame 中创建了两个事件处理程序:OnKeyDown 和 OnKeyPress。 2. 在使用 TFrame 的 TForm 中,我编写了两个事件处理程序,我连接到 TForm 的 OnKeyDown 和 OnKeyPress。这些事件处理程序首先调用 TFrame 的同名方法。根据这些调用的结果,TForm 事件处理程序可能会自己处理密钥。

标签: delphi events frames keyevent


【解决方案1】:

试试这个。与其创建 TFrame 后代,不如在框架中创建 KeyDown 和 KeyPress 过程,如

procedure TFrame2.KeyDown(var Key: Word; Shift: TShiftState);
begin
  Memo1.Lines.Add('KeyDown: '+IntToStr(Key));
end;

procedure TFrame2.KeyPress(var Key: Char);
begin
  Memo1.Lines.Add('KeyPress: '+IntToStr(ord(Key)));
end;

然后从表单的 OnKeyDown 和 OnKeyPress 中调用它们

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Frame21.KeyDown(Key,Shift);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  Frame21.KeyPress(Key);
end;

【讨论】:

  • 嗨@crefird。目前这正是我所做的。但是当我的类 TMyForm 拦截任何帧类型 TMyFrame 时,我的方式是通用的。我的想法是创建一个可能有点不同的解决方案,但是,如果没有其他方法,我将不得不保留它。
【解决方案2】:

我做了一些更多的测试,得到了一个更简单的解决方案,该解决方案的原理没有问题。

1) 我通过递归函数获得了我的框架的基础类型对象。

2) 如果活动控件包含在标准框架中,则调用 OnKeyDown、OnKeyPress 事件执行。

如果有人需要,下面是我的应用测试代码。

Unit UnFrameBase;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ActnList;

Type
  TFrameBase = Class(TFrame)
    PnlBase: TPanel;
  Private
  Public
    Procedure EventFrameKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); Virtual;
  End;

Implementation


{$R *.dfm}

{ TFrameBase }

Procedure TFrameBase.EventFrameKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
Begin
  //nothing
End;

End.


Unit UnControlsClassTest;

interface

uses Classes, Controls;

Function ActiveControlAs(AControl: TWinControl;
  AClass: TWinControlClass): TWinControl;

    Function CheckControl(Var C: TWinControl; ControlClass: TWinControlClass): Boolean;
    Var
      Parent: TWinControl;
    Begin
      Result := (C Is ControlClass);
      If (Result = False) And (C <> Nil) And (C.Parent <> Nil) Then
      Begin
        Parent := C.Parent;
        Result := CheckControl(Parent, ControlClass);
        If Result Then
          C := Parent;
      End;
    End;


Var
  C: TWinControl;

Begin
  C := AControl;
  If CheckControl(C, AClass) Then
    Result := C
  Else
    Result := Nil;

End;


Unit UnMainFormTest;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, UnFrameCustomer,  UnFrameBase;

Type
  TFormMain = Class(TForm)
    Procedure FormCreate(Sender: TObject);
    Procedure BtnTestarClick(Sender: TObject);
    Procedure FormKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
  Private
    Function GetInstanceActiveFrame(AActiveControl: TWinControl): TFrameBase;
  Public
    { Public declarations }
  End;

Implementation

Uses UnControlsClassTest;

{$R *.dfm}


Function TFormMain.GetInstanceActiveFrame(AActiveControl: TWinControl): TFrameBase;
Begin
  Result := TFrameBase(ActiveControlAs(AActiveControl, TFrameBase));
End;

Procedure TFormMain.FormKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
Var
  LActiveFrame: TFrameBase;

Begin
  LActiveFrame := GetInstanceActiveFrame(ActiveControl);
  If Assigned(LActiveFrame) Then
    LActiveFrame.EventoFrameKeyDown(Sender, Key, Shift);

  If Key In [VK_DOWN, VK_RETURN] Then
  Begin
    Perform(WM_NEXTDLGCTL, 0, 0);
    Key := 0;
  End
  Else If Key = VK_UP Then
  Begin
    Perform(WM_NEXTDLGCTL, 1, 0);
    Key := 0;
  End;
End;

【讨论】:

    猜你喜欢
    • 2010-12-22
    • 1970-01-01
    • 2021-04-11
    • 2011-04-28
    • 2013-12-29
    • 2022-11-28
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多