2017-02-25 59 views
0

我試圖在我的項目中實現TDI接口。到目前爲止它工作得很好(表單在我的PageControl的選項卡內創建 - 如預期的那樣)。然而,我正面臨着一個惱人的問題:OnKeyPress事件不是因爲它們是「父對象」而在我的子表單上觸發的。我已經試過兩種方式下面,但沒有成功:當Form有父項時,OnKeyPress事件不會被觸發

procedure TForm1.Button1Click(Sender: TObject); 
var 
    f: TForm2; 
begin 
    f := TForm2.Create(self); 
    f.ManualDock(PageControl1); 
    f.Show; 
end; 

- 或 -

procedure TForm1.Button1Click(Sender: TObject); 
var 
    f: TForm2; 
    tab: TTabSheet; 
begin 
    tab := TTabSheet.Create(PageControl1); 
    tab.PageControl := PageControl1; 
    tab.Parent := PageControl1; 

    f := TForm2.Create(tab); 
    f.BorderStyle := bsNone; 
    f.Align := alClient; 
    f.Parent := tab; 
    tab.Caption := f.Caption; 

    f.Show; 
end; 

¹不用說,KeyPreview屬性被設置爲TRUE。

²如果我只是註釋以下行,事件工作正常(但不是一個標籤頁中創建的形式):

//f.Parent := tab; 

有沒有人遇到這個問題?任何幫助? 謝謝!

+2

KeyPreview爲True解釋它。按照設計,活動將轉到頂層表單。 –

+0

正常情況下,KeyPreview只會使窗體在控件中接收* * *添加*中的事件*,所以它仍然可以工作。 – dummzeuch

+0

它應該工作,但它不會。 –

回答

1

我看看人士透露,事實證明,控制接收KeyPress搜索它的父窗體,如果窗體上有KeyPreview集,中繼事件這種形式:

function TWinControl.DoKeyPress(var Message: TWMKey): Boolean; 
var 
    Form: TCustomForm; 
    Ch: Char; 
begin 
    Result := True; 
    Form := GetParentForm(Self); 
    if (Form <> nil) and (Form <> Self) and Form.KeyPreview and 
    TWinControl(Form).DoKeyPress(Message) then Exit; 
    // [...] 
    Result := False; 
end; 

的父母形式是鏈中的頂級形式。這意味着你的Form1接收事件(如果有KeyPreview套),除了原有的控制:

function GetRealParentForm(Control: TControl; TopForm: Boolean = True): TCustomForm; 
begin 
    while (TopForm or not (Control is TCustomForm)) and (Control.Parent <> nil) do 
    Control := Control.Parent; 
    if Control is TCustomForm then 
    Result := TCustomForm(Control) else 
    Result := nil; 
end; 

這讓你有兩個選擇:

  • 處理的KeyPressForm1代替,儘管你可能必須找出它最初來自哪個孩子的形式。
  • 將表單的KeyPreview設置爲false,而是直接將處理程序添加到 控件Form2
  • 修改VCL 源不KeyPress轉發他們到頂層的形式,但 而不是在鏈中的下一個形式,我認爲這就是我會做 。
  • 當然,我現在可能還沒有其他選擇。
+0

你說得對。我試圖重寫這個方法,但我不確定它是否會按需要工作。 –

相關問題