如何使用winapi使子窗口(也称为拥有窗口)的父窗口保持活动状态?

3

我正在使用winapi编写一个小型的C应用程序。在那里,我有一个带有子窗口(工具箱)的窗口。我能够将其保持在这个窗口内等等,但是我的问题是:如果子窗口获得焦点,如何保持主窗口活动?

此时主窗口会变灰。

这些窗口是通过以下方法创建的:

hMainWindow = DialogBoxParam(.......);
hChildWindow = CreateDialogParam(..., hMainWindow, ...); 
ShowWindow (hChildWindow, SW_SHOW);

以下是两个窗口的行为示意图:

The behaviour of the windows


1
据我所知,活动窗口是具有焦点的窗口,因此如果子窗口具有焦点,则主窗口也不能具有焦点。 - Tony The Lion
也许不是这种方式,但我知道其他应用程序可以实现,比如你可能知道的Paint.NET。 - Christoph Meißner
你可能需要定义一下“活动”的含义?你正在使用 MDI 窗口吗? - jweyrich
1
如果看到Paint.NET这样做。它使用恶意黑客方法,过滤Windows消息来说服窗口它仍然活动中,以便不会重绘标题栏。我记不清确切的细节了,无法在此处重现。源代码已不再提供,也许您可以在其他地方找到旧版本的副本。考虑使用没有标题的工具窗口,在客户端区域绘制模拟标题栏。 - Hans Passant
哦,技术上讲,工具窗口不是子窗口。它是一个拥有的窗口,在某些关键方面有所不同。不幸的是,即使在MSDN中,术语的使用也经常出现误用。 - Adrian McCarthy
显示剩余2条评论
3个回答

3
我发现只需将它创建为 WS_CHILD,并明确地不要创建为 WS_POPUP 即可解决这个问题。这也将绝对窗口坐标转换为相对坐标,因此我不必再关心父窗口的位置而进行移动。
// 已解决

1

将子窗口创建为非模态对话框而不是模态对话框。因此,不要使用DialogBox,而要使用CreateDialog


我已经这样做了。 hPanel = CreateDialogParam(......); ShowWindow (hPanel, SW_SHOW); - Christoph Meißner
那么我想我不理解这个问题。你只能有一个“活动”的窗口。最上面的窗口总是被聚焦的。 - Mike Kwan
@Mike Kwan的答案一直对我有用。你是指你根本无法选择父窗口吗?还是说你只是不希望在创建子窗口时将其聚焦? - user2058002
我已经画了一个小草图。现在你可能会更好地理解问题了。 :) - Christoph Meißner

1

抱歉,这就是 Windows 的工作方式:一次只能有一个活动窗口。

如果您在 Visual Studio 中打开“查找和替换”工具窗口,您会发现它会被激活,而主要的 VS 窗口则变为非活动状态。

试图同时激活它们可能会让用户和辅助工具(如屏幕阅读器)感到困惑。


是的,你说得对,也许我应该把它做成一个面板,但在C中,我会以同样的方式制作一个没有标题的窗口。所以问题仍然存在。还有其他可能性吗? - Christoph Meißner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接