1

我在我的应用程序中使用嵌入式表单,我正在尝试这样的事情:

在设计时,表单是一个正常的表单,对嵌入/对接一无所知。使用 ButtonClick,我可以通过调用表单的 Show() 方法使表单可见。在运行时,表单可能会停靠到另一个表单并成为嵌入式表单。当我按下按钮再次显示表单(现在是嵌入的)时,什么也没有发生,因为我现在必须为包含嵌入表单的表单调用 Show()。

我正在寻找一种在调用嵌入表单的 Show() 方法时强制显示父表单的方法。我可以通过在调用 Show() 之前检查父表单的存在来处理这个问题,但我不想包含这个特定的处理。

我更愿意在父表单中进行此处理,当表单停靠时会收到通知。

Show() 方法仅将 Visible 属性设置为 true(RAD Studio 帮助),所以我认为不会触发消息...?

你知道实现这样的事情的方法吗?

编辑

我想提供一些关于我的应用程序的信息,因为我猜这更像是一个设计问题而不是编程问题。

该应用程序使用多个插件来适应连接的硬件。该 exe 提供了一个拖放环境,并包含一个可停靠表单的基类。插件对对接实现没有任何了解。通过创建可停靠表单并从插件嵌入表单,插件表单变得可停靠。这就是为什么我希望在某处调用嵌入表单的方法 Show() 时显示父表单的原因。

4

2 回答 2

4

您可以为您的嵌入式表单甚至应用程序中的所有表单创建一个共同的祖先,然后从中派生您的表单:

type
  TEmbeddedForm = class(TForm)
  public
    procedure Show;
  end;

procedure TEmbeddedForm.Show;
var
  ParentForm: TCustomForm;
begin
  inherited Show;
  ParentForm := GetParentForm(Self);
  if ParentForm <> Self then
  begin
    // Form is Embedded
    Update;        
    ParentForm.Show;
    // You might alternatively consider to send custom 
    // message to the Parent form, and let it decide what to do e.g.
    // SendMessage(ParentForm.Handle, CM_MY_EMBEDED_FORM_SHOW, 0, 0);
  end;
end;

然后当你打电话时:

procedure TForm1.Button1Click(Sender: TObject);
begin
  // MyEmbeddedForm is derived from TEmbeddedForm 
  MyEmbeddedForm.Align := alClient;
  MyEmbeddedForm.BorderStyle := bsNone;

  MyEmbeddedForm.Parent := Form3.Panel1;
  MyEmbeddedForm.Show;
end;

Form3正在显示。


另一种选择(我只用 Spy++ 确认)是拦截WM_CHILDACTIVATEWM_WINDOWPOSCHANGINGTEmbeddedForm. 它在子窗体调用时发送给它TEmbeddedForm.Show,并相应地采取行动,即GetParentForm(Self).Show

于 2014-11-18T08:21:49.433 回答
0

在嵌入表单上使用SetFocus而不是。Show

这也将强制显示父表单。

于 2014-11-18T07:16:30.613 回答