2017-02-25 14 views
0

Ich versuche, eine TDI-Schnittstelle in meinem Projekt zu implementieren. Es funktioniert soweit gut (die Formulare werden in Tabs auf meinem PageControl erstellt - wie erwartet). Ich stehe jedoch vor einem nervigen Problem: Das OnKeyPress-Ereignis wird nicht auf meine untergeordneten Formulare ausgelöst, nur weil sie "parented" sind. Ich habe unten in beiden Richtungen versucht, aber ohne Erfolg:OnKeyPress Ereignis wird nicht ausgelöst, wenn Formular ein Elternteil hat

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

-ODER-

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; 

¹ unnötig zu sagen, dass die KeyPreview-Eigenschaft auf True gesetzt ist.

², wenn ich nur die folgende Zeile kommentieren, das Ereignis funktioniert gut (aber die Form ist nicht in einem tabsheet erstellt):

//f.Parent := tab; 

Hat jemand vor dieser Frage konfrontiert? Irgendeine Hilfe? Danke!

+2

KeyPreview wahr zu sein, erklärt sie. Das Ereignis wird wie geplant auf das oberste Formular übertragen. –

+0

Normalerweise KeyPreview nur das Formular erhält die Ereignisse * in * * Zusatz * an das Steuerelement, so sollte es noch funktionieren. – dummzeuch

+0

Es sollte funktionieren, aber es tut es nicht. –

Antwort

1

hatte ich einen Blick auf die Quellen, es stellt sich heraus, dass die Steuerung die KeyPress sucht nach seiner Mutterform empfängt, und wenn das Formular KeyPreview festgelegt ist, um das Ereignis zu dieser Form weiterleitet:

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; 

Die Elternformular ist das oberste Formular in der Kette. Dies bedeutet, dass Ihr Form1 das Ereignis erhält zusätzlich zu der ursprünglichen Regelung (wenn es KeyPreview gesetzt hat):

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; 

Dies lässt Sie mit ein paar Optionen:

  • Behandeln Sie die KeyPress in Form1 statt , obwohl Sie dann wahrscheinlich herausfinden müssen, aus welcher Kinderform es ursprünglich stammt.
  • Setzen Sie das Formular auf false, und fügen Sie stattdessen den Handler zu die Steuerelemente auf Form2 direkt.
  • Ändern Sie die VCL Quelle sie nicht KeyPress auf die oberste Ebene Form weiterzuleiten, sondern stattdessen auf die nächste Form in der Kette, ich denke, das ist, was ich würde tun.
  • Natürlich könnte es andere Optionen geben, an die ich momentan nicht denke.
+0

Sie haben Recht. Ich versuche, diese Methode zu überschreiben, aber ich bin mir nicht sicher, ob es wie gewünscht funktioniert. –

Verwandte Themen