记事本里的顶层窗口设置WS_EX_CONTROLPARENT风格的窗口

我们先用一句话来说明,如果一个对象被设置为DS_CONTROL样式,就意味着这个对话框将被视为另一个对话框的子窗口,而不是一个普通的顶级对话框。也称为嵌套对话框。

实际上,嵌套对话框并不可怕,而且比较常见。您经常会看到属性对话框,其中每个页面都是一个单独的对话框对话框程序消息循环对话框程序消息循环,这些对话框是外部对话框的子窗口。此外,在一些常见的对话框中,也会看到这种嵌套对话框。如果您查看记事本中的“另存为”窗口,窗口底部的额外选项是嵌套窗口。

在对话框模板中设置DS_CONTROL样式(或在普通窗口设置WS_EX_CONTROLPARENT扩展样式)时,会生成一些新的执行规则进行干预。

首先,对话框的 WS_CAPTION 和 WS_SYSMENU 样式都被忽略。因为设置了 DS_CONTROL 样式后,对话框变成了子窗口,而不是顶级窗口,所以它不应该有标题栏或系统菜单栏(因为标准栏和系统菜单都来自外层窗口)。

然后,一些与对话框导航功能相关的函数,比如GetNextDlgTabItem,在遍历对话框上的控件时,该函数会遍历嵌套的WS_EX_CONTROLPARENT样式窗口。如果未设置此样式,控件搜索会将嵌入对话框视为一个巨型控件,而不是其他控件的容器。

当你用 DS_CONTROL 样式创建对话框时,你需要使用像 CreateDialogParam 这样的创建函数,而不是像 DialogBoxParam 这样的对话框相关函数,因为消息循环是由外部对话框控制的,而不是由子窗口控制的。

为了避免将对话管理器送入无限循环,必须了解递归行为。当调用GetNextDlgTabItem函数查询上一个控件时,会从起始控件开始,遍历对话框上方的所有控件,直到返回到起始点。如果忘记将对话框标记为 DS_CONTROL,并且焦点开始在子对话框上,则控件枚举不会递归到子对话框中,因此永远找不到起点。对话管理器将继续循环,寻找那个启动控件,但永远找不到它,即进入一个无限循环。

(即使没有 DS_CONTROL 也存在此问题。如果您从禁用或不可见控件开始遍历,则遍历控件将永远找不到起点,因为在通过对话框禁用和不可见控件时会跳过这些起点。)

总结

当对话框程序的焦点在容器对话框上时,切换焦点,界面暂停,可能是因为这个DS_CONTROL风格的问题。这是一个小技巧。

最后

Raymond Chen 的“The Old New Thing”是我最喜欢的博客之一。里面包含了很多关于Windows的小知识,对广大Windows平台开发者来说真的很有帮助。本文来自:《DS_CONTROL 样式有什么用?》

我最近写了一些东西

如您所知,Topomel Box 是一款绿色软件,主要面向经常使用电脑的朋友。它提供了多种小功能,提高办公效率,同时操作尽可能简单方便。我认为:你应得的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论