我正在尝试在我的项目中实现TDI接口。它到目前为止工作正常(表单是在我的PageControl上的选项卡内创建的 - 正如预期的那样)。但是,我正面临一个令人讨厌的问题:OnKeyPress事件不是因为它们是“父级”而在我的子表单上触发。我在下面尝试了两种方法,但没有成功:
procedure TForm1.Button1Click(Sender: TObject);
var
f: TForm2;
begin
f := TForm2.Create(self);
f.ManualDock(PageControl1);
f.Show;
end;
-OR -
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。
²如果我只是注释以下行,则事件正常(但表单不是在TabSheet中创建的):
//f.Parent := tab;
以前有人遇到过这个问题吗?有帮助吗? 谢谢!
答案 0 :(得分:1)
我查看了这些来源,结果发现接收KeyPress
的控件搜索其父窗体,如果窗体设置了KeyPreview
,则将事件转发到该窗体:< / p>
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;
这给你留下了几个选择:
KeyPress
中的Form1
代替,但您可能必须找出它最初来自哪个子窗体。KeyPreview
设置为false,然后将处理程序添加到
直接Form2
上的控件。KeyPress
转发到顶级表单,但是
而不是链中的下一个形式,我认为这就是我想要的
做。