Delphi 调用嵌入表单的Show()应显示父表单

Delphi 调用嵌入表单的Show()应显示父表单,delphi,c++builder,vcl,tform,Delphi,C++builder,Vcl,Tform,我在我的应用程序中使用嵌入式表单,我尝试了以下方法: 在设计时,表单是一个普通表单,它对嵌入/对接一无所知。 通过调用表单的Show方法,我可以使用按钮单击使表单可见。 在运行时,表单可能会停靠到另一个表单中,并成为嵌入式表单。 当我再次按下显示表单的按钮时,由于 我现在必须调用Show以获取包含嵌入表单的表单 我正在寻找一种方法,在调用嵌入表单的Show方法时强制显示父表单。在调用Show之前,我可以通过检查父窗体的存在性来处理此问题,但我不想包含此特定处理 我更愿意在父窗体中执行此处理,当窗

我在我的应用程序中使用嵌入式表单,我尝试了以下方法:

在设计时,表单是一个普通表单,它对嵌入/对接一无所知。 通过调用表单的Show方法,我可以使用按钮单击使表单可见。 在运行时,表单可能会停靠到另一个表单中,并成为嵌入式表单。 当我再次按下显示表单的按钮时,由于 我现在必须调用Show以获取包含嵌入表单的表单

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

我更愿意在父窗体中执行此处理,当窗体停靠时会收到通知

Show方法只将Visible属性设置为true RAD Studio Help,因此我认为不会触发消息

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

编辑

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

应用程序使用多个插件来适应连接的硬件。exe提供了拖放和停靠环境,并包含可停靠窗体的基类。这些插件对对接实现一无所知。通过创建一个可固定的表单并嵌入插件中的表单,插件表单变得可固定。这就是为什么我希望在调用嵌入表单的Show方法时显示父表单的原因。

使用SetFocus而不是在嵌入表单上显示

这也将强制显示父窗体。

使用SetFocus而不是在嵌入窗体上显示


这也将强制显示父窗体。

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

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;
表格3正在显示


我只使用Spy++确认的另一个选项是拦截TEmbeddedForm中的WM_CHILDACTIVATE或WM_WINDOWPOSCHANGING。当子窗体调用TEmbeddedForm.Show时,会将其发送给它,并相应地执行操作,即GetParentFormSelf.Show。

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

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;
表格3正在显示


我只使用Spy++确认的另一个选项是拦截TEmbeddedForm中的WM_CHILDACTIVATE或WM_WINDOWPOSCHANGING。当子窗体调用TEmbeddedForm.Show时,会将其发送给它,并相应地执行操作,即GetParentFormSelf.Show。

调用Show并不能满足您的需要。您需要做的是遍历父链以找到顶级表单,并调用Show。您希望显示顶级表单,但希望避免遍历父链。您是否准备好了您所要求的可能无法完成?一旦嵌入了子窗体WindowProc,父窗体可以通过对其进行分类并检查WM_SHOW etc消息来连接子窗体WindowProc。我最好使用GetParentForm nil并简单地显示它。@DavidHeffernan是的,我为此做好了准备:我希望vcl有一个我还不知道的机制。@kobik:WM_show是否会在未触发OnShow的情况下被解雇?调用show并不能满足您的需要。您需要做的是遍历父链以找到顶级表单,并调用Show。您希望显示顶级表单,但希望避免遍历父链。您是否准备好了您所要求的可能无法完成?一旦嵌入了子窗体WindowProc,父窗体可以通过对其进行分类并检查WM_SHOW etc消息来连接子窗体WindowProc。我最好使用GetParentForm nil并简单地显示它。@DavidHeffernan是的,我为此做好了准备:我希望vcl有一个我还不知道的机制。@kobik:即使OnShow没有触发,WM_show也会被触发吗?不幸的是,我无法确认这一点。另外,我必须先调用Show,否则我会得到一个errorNot visible控件无法获得焦点OSLT。它要求两个窗体在之前都显示一次。这可以通过在设计器中设置Visible=True来解决。您是对的。但是当我关闭父窗体并再次调用它时,我也遇到了同样的问题。谢谢。很遗憾,我不能证实这一点。另外,我必须先调用Show,否则我会得到一个errorNot visible控件无法获得焦点OSLT。它要求两个窗体在之前都显示一次。这可以通过在设计器中设置Visible=True来解决。您是对的。但是当我关闭父窗体并再次调用它时,我也遇到了同样的问题。谢谢,谢谢,但这不是我想要的。我的应用程序在运行时被几个插件BPL和DLL扩展。通过嵌入包含
如果我想的话,我可以给它们一个特殊的功能。当我把基类放在几个BPL中并加载它们时,它并没有按照我们所知道的那样工作。我不确定我是否遵循了最后一部分。如果您使用表单插件,建议使用公共祖先,例如TPluginForm。请用相关信息更新您的问题,因为现在我不确定您想要什么。这就是终极的意思。据我所知,我不敢告诉你,你所要求的是不可能的,不幸的是,你将不得不放弃。由于您只接受一个调用就可以在嵌入表单上显示,因此您别无选择。对于TCustomForm,GetParentForm将不会返回nil。您不会覆盖它。你在涂搽剂。查看我发布的Delphi源代码,没有覆盖。我称之为表演;用新方法。谢谢,但这不是我想要的。我的应用程序在运行时被几个插件BPL和DLL扩展。通过嵌入包含在这些包中的表单,如果我愿意,我可以给它们一个特殊的功能。当我把基类放在几个BPL中并加载它们时,它并没有按照我们所知道的那样工作。我不确定我是否遵循了最后一部分。如果您使用表单插件,建议使用公共祖先,例如TPluginForm。请用相关信息更新您的问题,因为现在我不确定您想要什么。这就是终极的意思。据我所知,我不敢告诉你,你所要求的是不可能的,不幸的是,你将不得不放弃。由于您只接受一个调用就可以在嵌入表单上显示,因此您别无选择。对于TCustomForm,GetParentForm将不会返回nil。您不会覆盖它。你在涂搽剂。查看我发布的Delphi源代码,没有覆盖。我称之为表演;在新方法中。