MFC/WinAPI 的大问题

2024-02-16

我需要创建一个带有两个选项卡的表单视图的 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的顶部条背景颜色?任何人?


您唯一的选择是拥有该选项卡控件。这并不难。嗯,这令人沮丧,因为 MFC 没有告诉您如何进行必要的 Win32 调用。

在 CPropertySheet 派生类中,覆盖 OnInitDialog() 并添加:

GetTabControl()->ModifyStyle(0,TCS_OWNERDRAWFIXED);

这使 CPropertySheet 派生类负责绘制选项卡控件。添加 WM_DRAWITEM (OnDrawItem) 的处理程序并更改 backgroundColor 和 textColor 以匹配您想要的任何颜色。 OnDrawItem 的代码如下:

void CPropSht::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    if (ODT_TAB != lpDrawItemStruct->CtlType)
    {
        CPropertySheet::OnDrawItem(nIDCtl, lpDrawItemStruct);
        return;
    }

    // prepare to draw the tab control
    COLORREF backgroundColor = RGB(0,255,0);
    COLORREF textColor = RGB(0,0,255);
    CTabCtrl *c_Tab = GetTabControl();

    //  Get the current tab item text.
    TCHAR buffer[256] = {0};
    TC_ITEM tcItem;
    tcItem.pszText = buffer;
    tcItem.cchTextMax = 256;
    tcItem.mask = TCIF_TEXT;

    if (!c_Tab->GetItem(c_Tab->GetCurSel(), &tcItem )) return;

    // draw it
    CDC aDC;
    aDC.Attach(lpDrawItemStruct->hDC);
    int nSavedDC = aDC.SaveDC();

    CBrush newBrush;
    newBrush.CreateSolidBrush(backgroundColor);
    aDC.SelectObject(&newBrush);
    aDC.FillRect(&lpDrawItemStruct->rcItem, &newBrush);
    aDC.SetBkMode(TRANSPARENT); 
    aDC.SetTextColor(textColor);
    aDC.DrawText(tcItem.pszText, &lpDrawItemStruct->rcItem, DT_CENTER|DT_VCENTER|DT_SINGLELINE);

    aDC.RestoreDC(nSavedDC);

    aDC.Detach();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MFC/WinAPI 的大问题 的相关文章

  • Windows XP 风格:为什么我们在静态文本小部件上得到深灰色背景?

    我们正在使用 C 和 Win32 编写 Windows 桌面应用程序 我们的对话框具有 Windows XP 风格 的丑陋外观 静态文本的背景是灰色的 如果对话框背景也是灰色 这不是问题 但在背景为白色的选项卡控件内 文本的灰色背景非常明显
  • Visual Studio Publish 的动态文件夹名称

    是否可以在 VS 2017 中配置文件系统发布选项 以根据日期或增量构建版本部署到新文件夹 即 当我单击发布时 我希望它转到 MyApp v1 然后下次单击 MyApp V2 您可以使用一些宏 要执行日期 请使用此宏 System Date
  • Windows Server / Datacenter:设置 CPU 关联性 > 64 个核心

    SetThreadAffinityMask 允许为 64 个逻辑核心 处理器 设置关联掩码 但是 Windows Datacenter 最多可以有 64 个 CPU 每个 CPU 都有多个内核 请参阅here http social tec
  • 带有 Angular2 和 Typescript 的 Visual Studio 2013

    我在用着angular2 快速入门 https angular io docs ts latest quickstart html我遇到了 Visual Studio 无法识别的问题Angular2 with 打字稿导入模块 其余一切都很好
  • 以编程方式或使用清单 (MinGW) 将“覆盖高 DPI 缩放”设置为“系统(增强)”

    我尝试了所有可能的组合gdiScaling and dpiAware 仍然没有运气 如果我手动右键单击 app exe 并将 覆盖高 DPI 缩放 设置为 系统 增强 效果很好
  • windows下删除进程权限

    出于安全原因 我正在寻找一种删除进程权限的方法 我想以具有特权的用户身份开始 并以受限用户身份结束 例如 我希望我的 Web 服务器在受限用户下运行 但我仍然想监听端口 80 我怎样才能在Windows下做这样的事情 与 Unix 类似的东
  • 多个构建配置可以共享一个配置转换吗?

    我正在使用 SlowCheetah 进行 XML 转换项目中的一堆配置文件 但是 这个相同的解决方案是负载平衡设置的一部分 其中不同服务器 在本例中为两个 之间的某些配置值有所不同 我有以下构建配置 Debug Release 发布 测试
  • 如何检测Windows 8.1开始菜单?

    当我们在 Windows 8 1 上按下开始菜单时 它会以磁贴的形式显示所有新的开始菜单以及应用程序 该菜单显示在整个屏幕上 有没有办法检测这个菜单是否在 C 中打开 8 1 SDK 中是否有 winAPI 可以执行此操作 提前致谢 调用
  • 如何获取 Visual Studio 2017 的离线安装程序?

    我最近尝试安装视觉工作室 2017 但没有离线安装程序 如何获取它的离线安装程序 我也尝试安装Xamarin 尽管我有最新的安卓软件开发工具包 它要求我下载安卓软件开发工具包再次 如何纠正 提前致谢 要生成离线安装程序 您首先需要下载相应的
  • VC++ 代码 DOM 可以从 VS 插件访问吗?

    Visual Studio IntelliSense for VC 包括 完整 EDG C 解析器 http www edg com location c frontend 英特尔和其他公司也使用 由于插件可以访问 C Code DOM 如
  • Visual Studio 模板 - 添加其他预先存在的项目

    我正在开发一个 Visual Studio 模板 其中生成的项目依赖于许多引用 这些引用恰好是源代码控制下的其他项目 问题是如何在我的 ProjectGroup 模板中进行设置 例如 如果我在 C Stuff MyUtilityProjec
  • 有没有办法在两个 Visual Studio 实例之间拖放来复制文件?

    有没有办法在两个 Visual Studio 2008 实例之间复制文件 插件 设置还是其他什么 目前 将文件从一个实例拖动到另一个实例不会执行任何操作 鼠标显示该操作无效 右键单击文件并从实例 1 中选择 复制 然后粘贴到实例 2 中会导
  • 如何向 Visual Studio Intellisense 添加按钮

    我想在 Visual Studio 的 IntelliSense 返回的选项列表的顶部添加一个按钮 单击该按钮时 将执行我的自定义代码 这将导致出现弹出窗口 我将其称为 按钮 因为当用户单击该项目时 我希望出现一个弹出窗口 而不是完成用户输
  • winapi 函数的函数指针 (stdcall/cdecl)

    请有人给我一些为 MS winapi 函数创建函数指针的提示吗 我试图为 DefWindowProc DefWindowProcA DefWindowProcW 创建一个指针 但出现此错误 LRESULT dwp HWND UINT WPA
  • 在 Visual Studio 中为项目创建目标 OBJ 文件夹

    是否可以像创建 BIN 文件夹一样创建目标 OBJ 文件路径 您可以在项目属性中设置输出路径 示例路径是 Bin 调试 Windows Phone 7 Bin 调试 NETMF Bin 调试 这里的一个用例是 如果我有多个针对不同平台的项目
  • 检测 Windows 重新启动是否是由于 Windows 更新造成的

    我的电脑上的一些应用程序一直在检测 Windows 更新是否重新启动 这是可以观察到的 因为它们会在 Windows 更新自动重启后重新启动 这非常有帮助 因为这些应用程序会重新加载更改 甚至unsaved更改或恢复选项卡 如果是浏览器 执
  • Win32:将窗口置于顶部

    我有一个 Windows 程序 其中有两个 2 窗口 hwnd main interface hwnd2 toplevel window no parent created by hwnd 当我双击 hwnd 时 我需要弹出 hwnd2 并
  • :: 右侧的非法标记

    我有以下模板声明 template
  • 有什么方法可以延迟 Visual Studio 中智能感知的淡入时间吗?

    我刚刚切换到 VS2008 智能感知比 2005 年更加 有用 我发现它真的打破了我的注意力 每次我到达标记或关键词或其他任何内容的末尾时 它都会弹出 我必须按 ESC 或忽略它 这是really恼人的 我无法找到延迟其激活的设置 我确实想
  • Windows.Automation 中的旧版 IAccessible

    如何使用C 获取AutomationElement的LegacyIAccessible State和其他LegacyIAccessibles 就像工具中的 Inspect exe 一样 The LegacyIAccessible是新的 并且

随机推荐

  • 在 mongodb 中,获取第一个和最后一个文档的最有效方法是什么

    我有这样的文件 class A DateTime T 我想找到最早和最新的文档 这样做是否更好 var First db Collection AsQueryable OrderBy gt t FirstOrDefault var Last
  • 使用 Nginx + Gzip + Unicorn 时缺少 Content-Length 标头

    我不知道为什么当我在 nginx 中使用 gzip 时 http 响应会丢失 Content Length header 我真的陷入困境 请有人帮助我 非常感谢 这是我的配置文件 nginx conf 用户无人无人 工作进程 8 event
  • 使用 Dynamorm 在 Python 中构建 AWS SAM 嵌套应用程序

    我在用AWS SAM https aws amazon com serverless sam 构建无服务器应用程序 我按照说明构建嵌套应用程序 https aws amazon com blogs compute announcing ne
  • CakePHP Cache::clear 不起作用

    我的 bootstrap php 文件中有一个缓存配置 Cache config long array engine gt File duration gt 1 week probability gt 100 mask gt 0666 pa
  • 调用android中隐藏的API来关闭屏幕

    我正在考虑使用隐藏的 api 来关闭我的应用程序中的屏幕 setScreenState from https android googlesource com platform frameworks base eclair release
  • 是否有适用于 iPhone、Android 和 Windows Phone 7 的增强现实框架?

    我想开发一个在 iPhone Android Windows Phone 7 智能手机上运行的应用程序 能够识别标记并在其上放置增强现实内容 我可以使用任何通用框架来完成该任务吗 这可能是您得到的最接近的结果 http nyatla jp
  • ASP.NET WebApi 中异步调用的本地化

    嗨 我计划基于 Accept Language 标头 通过基于该标头设置 CurrentUICulture 来处理错误字符串等的服务器端本地化 但显然它不会通过异步调用 下面是示例代码来说明问题 是否有处理异步调用本地化的默认方法 publ
  • 如何查找指向 Oracle 中一条记录的外键依赖关系?

    我有一个非常大的 Oracle 数据库 有很多表和数百万行 我需要删除其中之一 但希望确保删除它不会破坏任何其他指向它作为外键记录的依赖行 有没有办法获取指向该行的所有其他记录的列表 或者至少是表模式 我知道我可以尝试自己删除它并捕获异常
  • 每行上的模态按钮显示从数据库获取详细信息的模态

    我已经使用表从两个表中获取所有记录 效果很好 我在显示的每一行末尾添加了一个按钮Modal 在此模式中 我想根据每个行 ID 显示数据 我的代码有一个 while 循环 它显示表中的记录 在该 while 循环中 我又编写了一个 sql 语
  • 如何在使用 XMLHttpRequest() 时在 python 中接收 POST 数据

    我有两个关于使用 XMLHttpRequest 时接收数据的问题 客户端是用javascript编写的 服务器端是用python写的 如何在 python 端接收 处理数据 如何响应 HTTP 请求 客户端 var http new XML
  • powershell - 使用文件名列表删除文件

    我从堆栈溢出中得到了以下代码 它工作正常 TargetFolder Pathofyourfolder Files Get ChildItem TargetFolder Exclude gc List txt Recurse foreach
  • 使用 AJAX 观察 SQL 数据库的更改 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我的数据库中有一个列将随机更新 每当该列更新时 我都需要刷新页面上的内容 如何使用 AJAX jQuery 仅对数据库更改执行操作 你
  • 错误您已经拥有该商品

    我有一个新的 Android 应用程序 其中添加了应用程序内计费功能 我感到沮丧得抓狂 我已上传签名的 APK 并发布到 alpha 我创建了一组应用内产品并将其全部激活 我创建了一个新的 Gmail 帐户 并将其定义为应用程序 apk 页
  • Java 中的架构约束 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想确保我的项目不包含包之间不必要的依赖关系 例如 我想确保该项目具有分层结构 IE 模型低于一切 业务
  • 从 HDC 句柄创建 QPaintDevice

    我有一个来自外部库的 Windows HDC 句柄 我想使用 QPainter 功能来绘图 Qt 中有什么方法可以从 HDC 句柄创建 QPaintDevice 吗 这样做的一种方法 使用 Windows API 从 HDC 获取 HWND
  • 使用 jQuery 操作 TinyMCE 内容

    使用 TinyMCE 我可以轻松操作内容并将其发送回编辑器 如下所示 get content from tinyMCE var content tinyMCE get content getContent manipulate conten
  • 使用 NSMutableString 追加到文件末尾

    我有一个日志文件 我试图将数据附加到其末尾 我有一个NSMutableString textToWrite变量 我正在执行以下操作 textToWrite writeToFile filepath atomically YES encodi
  • 从 ASP.NET MVC2 升级到 MVC3 的原因 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用此关键字并揭示模块模式的严格违规

    无法让以下内容通过 jslint jshint jshint strict true var myModule function use strict var privVar true pubVar false function privF
  • MFC/WinAPI 的大问题

    我需要创建一个带有两个选项卡的表单视图的 SDI 表单 其中封装了多个对话框作为选项卡内容 但表格必须有彩色背景 诸如此类的事情让我讨厌编程 首先 我通过资源编辑器尝试了 CTabControl 尝试了不同的事情 但未记录的行为和没有答案的