要解决我们系统中的一些问题,我需要在Frames(TFrame)中实现事件OnKeyDown
和OnKeyPress
。目前做了一个姑息性的解决方案,但它非常难看并且存在任何问题。
这个过程或多或少如下:
1)我在从TFrame继承的基类中创建了事件OnKeyDown
和OnKeyPress
。
2)在基于TForm的标准形式中,实现了拦截执行密钥的控件。因此,此过程在框架上和窗体上的关键事件之后执行第一个关键事件。
我必须这样做,因为我希望OnKeyDown事件在框架之前和之后执行。实施工作,但我想更好的代码。
有人能建议更好的解决方案吗?有没有更优雅的方法来解决这个问题?
答案 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;