【问题标题】:How can I create a Delphi child window that has a main menu?如何创建具有主菜单的 Delphi 子窗口?
【发布时间】:2013-05-02 11:42:03
【问题描述】:

我正在使用包含 TMainMenu 的 Delphi 表单。在特定情况下,我想在另一个表单中显示此表单的父级和客户端对齐。这工作正常,但没有出现父窗体的主菜单。我在this SO question 中看到一条评论,指出“子窗口不能有菜单”。我可以做些什么来覆盖此行为并显示 TMainMenu 吗?

顺便说一句:我刚刚注意到这一点,因为我以前使用过这个原理,我一直在使用 Developer Express 菜单组件,并且很高兴以子窗体显示。

后期编辑: 使用下面 TLama 中的代码,这是可行的(但子菜单不是主题,我很简单): 这有效:

procedure TForm65.FormShow(Sender: TObject);
begin
  Winapi.Windows.SetParent(ChildForm.Handle, Handle); // <<<<<<<<
  ChildForm.BorderStyle := bsNone;
  ChildForm.Align := alClient;
  ChildForm.Show;
end;

此代码不起作用。为什么?

procedure TForm65.FormShow(Sender: TObject);
begin
  ChildForm.Parent := Self; // <<<<<<<<<
  ChildForm.BorderStyle := bsNone;
  ChildForm.Align := alClient;
  ChildForm.Show;
end;

【问题讨论】:

  • 在表单中显示表单有点奇怪(如果没有 MDI 接口)。如果您将表单替换为 Frame 会怎样?
  • 我无法重现这个。我尝试使用代码like this,但放在ChildForm 上的主菜单仍然可以正常工作(Delphi 2009)。
  • @whosrdaddy:但这很酷!有时我让我的标准控件(例如按钮)有窗口框架只是为了好玩。
  • @TLama:您的代码确实有效,但菜单非常简单(缺少主题?)。我想知道为什么我的父母分配失败了,但你的(几乎)有效。
  • @Brian 调用 SetParent 不会使窗口成为子窗口。这在 SetParent 的文档中进行了解释。我的回答是准确的。毕竟,MSDN 上的文档再清楚不过了。

标签: delphi menu childwindow


【解决方案1】:

MSDN 非常清楚:

子窗口有一个客户区,但没有其他功能,除非明确要求。应用程序可以为子窗口请求标题栏、窗口菜单、最小化和最大化按钮、边框和滚动条,但子窗口不能有菜单。

这是指由 Windows 自己绘制的菜单。如果你的组件自定义绘制了一个菜单栏,那么它当然可以有一个菜单,即使它是一个子窗口。


您对SetParent 的调用不会使您的窗口成为子窗口。这在documentation中有解释:

出于兼容性原因,SetParent 不会修改正在更改其父级的窗口的 WS_CHILD 或 WS_POPUP 窗口样式。因此,如果 hWndNewParent 为 NULL,还应在调用 SetParent 后清除 WS_CHILD 位并设置 WS_POPUP 样式。反之,如果 hWndNewParent 不为 NULL 且窗口之前是桌面的子窗口,则应在调用 SetParent 之前清除 WS_POPUP 样式并设置 WS_CHILD 样式。

【讨论】:

  • 我相信OP默默想要MDI子窗口,而不是一般的子窗口。它在菜单部分没有太大区别,但仍然......
  • @david 好的,我现在明白 SetParent 是我们想要的,我们看到它有效。您现在能否进一步解释为什么 SetParent 的行为与 ChildForm.Parent := Self 不同?
  • 我已经做到了。它在我的答案中的 MSDN 摘录中。当您调用 SetParent 时,您没有设置 WS_CHILD 样式。所以你的窗口不是子窗口。它仍然是一个弹出窗口,WS_POPUP。
猜你喜欢
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
相关资源
最近更新 更多