質問

To solve some problems in our system, I need to implement the events OnKeyDown and OnKeyPress in Frames (TFrame). Currently did a palliative solution, but it is very ugly and present any problems.

The process is more or less the following:

1) I created the event OnKeyDown and OnKeyPress in a base class inherited from TFrame.

2) In a standard form based on TForm, implemented a control that intercepts execution keys. So, this process execute first key events on frame and after key events on the form.

I had to do way, because I wanted the OnKeyDown events execute before in frame and after on the Form. The implementation work, but I'll think in better code.

Can anyone suggest a better solution? Is there a more elegant way to solve this problem?

役に立ちましたか?

解決 2

I did some more tests and got a simpler solution that principle worked without problems.

1) I get an object of type base of my frame through a recursive function.

2) If the active control is inclue in standard frame, call the OnKeyDown, OnKeyPress event execution.

If someone needs something, below is the code of my application testing.

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;

他のヒント

Try this. Instead of creating a TFrame descendent, create KeyDown and KeyPress procedures in the frame like

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;

Then call them from the OnKeyDown and OnKeyPress of the form like

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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top