2013-10-08 93 views
1

爲了解決我們系統中的一些問題,我需要在Frames(TFrame)中實現事件OnKeyDownOnKeyPress。目前做了一個緩和的解決方案,但它非常醜陋,並且存在任何問題。如何在TFrame中實現OnKeyDown事件

方法或多或少以下:

1)I創建從TFRAME繼承了基類的事件OnKeyDownOnKeyPress

2)在基於TForm的標準格式中,實現了一個攔截執行密鑰的控件。所以,這個過程在框架上和窗體上的關鍵事件之後執行第一個關鍵事件。

我不得不這樣做,因爲我希望OnKeyDown事件在框架中之前和之後在窗體上執行。實現工作,但我會考慮更好的代碼。

任何人都可以提出更好的解決方案嗎?有沒有更好的方法來解決這個問題?

+0

不知道,但我認爲原來的問題需要這個編輯: 1.我創建了兩個事件處理程序:onKeyDown和中的OnKeyPress我TFRAME。 2.在使用TFrame的TForm中,我編寫了兩個事件處理程序,它們連接到TForm的OnKeyDown和OnKeyPress。這些事件處理程序首先調用TFrame的同名方法。根據這些調用的結果,TForm事件處理程序可以自行處理密鑰。 – RobertFrank

回答

0

我做了一些測試,並得到了這個原理更簡單的解決方案沒有問題。

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; 
1

試試這個。而不是創建一個TFRAME後代,在幀創建KeyDown和按鍵響應程序,如:

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; 
+0

嗨@crefird。目前正是我所做的。但我的方式是通用的,當我的類TMyForm攔截任何框架類型TMyFrame。 我的想法是創建一個可能有點不同的解決方案,但是,如果沒有其他方法,我將不得不離開它。 – Delphiman

相關問題