我需要创建一个带有两个选项卡的表单视图的 SDI 表单,其中封装了多个对话框作为选项卡内容。但表格必须有彩色背景。
诸如此类的事情让我讨厌编程。
首先,我通过资源编辑器尝试了 CTabControl,尝试了不同的事情,但未记录的行为和没有答案的怪癖使我陷入了障碍。
经过几个小时的搜索,我发现有一个名为属性表的控件,这实际上是我需要的。
后来进行更多搜索,我发现属性表甚至可以实际嵌入到 CFormView 中,如下所示:http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c591 http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c591
并且从 CPropertyPage 派生的对话框类可以通过 CPropertySheet 的 AddPage 方法直接添加为页面。
伟大的!不完全是这样...一些控件不起作用,并且没有创建,遇到了奇怪的断言。结果对话框中缺少 DS_CONTROL 样式。完全是偶然发现的Link https://devblogs.microsoft.com/oldnewthing/2007/01/08,MSDN 上没有任何相关信息!!!!属性页必须具有:DS_3DLOOK | DS_CONTROL | DS_控制WS_CHILD | WS_CHILD WS_TABSTOP,并且可以有:DS_SHELLFONT | DS_LOCALEDIT | WS_CLIPCHILDREN 样式!不是任何其他,默认情况下使用资源编辑器创建。为软件开发人员提供的甜蜜、超级隐藏信息!
该页面评论中引用的内容是:“天哪。这就是这种行为的来源......
事实证明,PlaySound API 在 64 位机器上播放声音时依赖于这种行为。”作者是 Larry Osterman(据我所知,他在 Microsoft 工作了 20 年),这让我笑出了声。
无论如何,修复了这个问题,对话框控件(CPropertyPages)现在已按预期创建,并且该部分看起来很有希望,但下一个带有颜色的部分又是死胡同!
通常,您会覆盖 WM_CTLCOLOR,检查控件 ID 或 hwnd 并提供必要的画笔来设置所需的颜色。 CPropertySheet 则不然,整个顶行保持灰色!对于 CTabCtrl 它以某种方式工作,对于 CPropertySheet 它不工作。
为什么?似乎 CPropertySheet 有点嵌入在 CTabControl 之类的内部,因为如果我覆盖 WM_ERASEBKGND,只有内部部分会更改颜色。
现在看来CPropertySheet中有一个GetTabControl()方法,它返回CPropertySheet的实际CTabCtrl*。但由于它是内部构造的,我找不到如何覆盖它的 WM_CTLCOLOR 消息处理。
似乎有一种方法可以对 windowproc 进行子类化,但是经过多次尝试,我找不到任何关于如何做到这一点的好来源。 MSDN 上的 SubclassWindow 文档说:“调用此函数时,窗口不得附加到 MFC 对象。”?!那是什么?
我尝试通过 MFC 向导创建一个基于 CTabCtrl 的自定义 CCustomTabCtrl 类,并从 CCustomPropertySheet 处理程序之一创建了一个名为 SubclassWindow 的实例,以覆盖内部 CTabCtrl,但没有任何效果,神秘的崩溃在 MFC 深处。
尝试为内部 CTabCtrl 设置 WindowLong 与 GCL_HBRBACKGROUND ,没有任何变化。
最糟糕的是,我找不到有关该主题的任何有用的文档或教程。
我能找到的最多的是如何所有者绘制选项卡控件,但这在很多方面都是严重错误的,我想要一个标准的控件行为减去背景颜色,我不想支持不同的配色方案、Windows 版本、IAccesible 接口等等这个东西,我见过的所有的ownerdraw 样本都不能正确实现所有标准控制行为的10%。我并不幻想我会创造出更好的东西,我不会利用手头的资源。
我偶然发现了这个帖子,我非常同意作者的观点:所有者绘制控件是未记录的 PITA,不可能正确执行,并且 MSDN 上有 NULL 信息可以提供帮助。
那么还有什么我错过了或者还没有尝试过的吗?如何更改CPropertySheet的顶部条背景颜色?任何人?