如何在TFrame中实现OnKeyDown事件

时间:2013-10-08 22:21:49

标签: delphi events frames keyevent

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

这个过程或多或少如下:

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

2)在基于TForm的标准形式中,实现了拦截执行密钥的控件。因此,此过程在框架上和窗体上的关键事件之后执行第一个关键事件。

我必须这样做,因为我希望OnKeyDown事件在框架之前和之后执行。实施工作,但我想更好的代码。

有人能建议更好的解决方案吗?有没有更优雅的方法来解决这个问题?

2 个答案:

答案 0 :(得分:2)

试试这个。而不是创建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;

答案 1 :(得分:1)

我做了一些更多的测试,得到了一个更简单的解决方案,原理可以顺利运行。

1)我通过递归函数得到了一个框架类型为base的对象。

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;