在运行时创建一个对话框模板
在之前的系列文章中,我们花了很长一段时间来学习了对话框模板和对话框管理器。
现在,让我们将之前所需到的各个知识点融合一下,来做一些有意思的事情,例如:在程序运行期间创建一个对话框模板。
具体来说,我们将会实现一个简陋版本的 MessageBox 函数。为什么我们要花功夫来实现一个 Windows 里已经有了的函数,且这个函数还不一定比原版的好呢?
因为,你可以将它作为一个起点来不断改进优化,来实现其他更加有现实意义的功能。
举个例子,如果你学会了如何在运行期创建一个对话框模板,则你就可以动态的添加除了默认的 “OK” 按钮以外的其他按钮,或者在对话框上添加其他自定义控件,或者插入一个动画控件等。
首先,我将会以一个不那么高效的对话框模板类开始。下面的代码虽然没有生产级别代码的质量,但是作为讲解原理的例子代码,还是足够的。请看:
我没有花很多时间来优化这段代码,因为它并不是本篇文章的重点。DialogTemplate 类带有一个 vector 数据成员和一个 Write 方法用来写入数据,另外还有一个 AlignToDword 方法用来将缓冲区对齐到下一个 DWORD 边界。后面,这些方法都会派上用场。
我们的消息框将需要一个对话框过程函数,该函数在用户按下 IDCANCEL 按钮时结束对话框。如果我们对对话框模板进行了任何自定义改造,我们也会在这个函数中进行处理。如下图所示:
至此,我们创建了一个对话框模板了。整个过程不是很复杂,但是细节挺多的。处于演示的目的,我讲对话框的大小设置成了一个固定值。如果要更完美的话,可以先通过获取 ncm.lfCaptionFont 和 ncm.lfMessageFont 对话框文本的长度和高度,然后选择最为合适的大小。
毕竟,用于确定字体点大小的花哨公式并不那么花哨。对话框管理器通过标准公式将字体高度从点转换为像素,如下:
fontHeight = -MulDiv(pointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
因此,要取回原始像素值,我们需要为pointSize求解这个公式,以便当它再次通过公式发送时,我们得到原始值。
一个微妙之处在于,”确定” 按钮的控件标识符是 IDCANCEL,而不是你可能期望的 IDOK。这是因为此消息框只有一个按钮,因此我们希望让用户按 ESC 键将其关闭。
现在剩下要做的就是把这个函数再修改一下,如下图所示:
现在让我们启动这个程序,点击空格键,然后观察消息框的行为。
好吧,所以这在视觉上不是很令人兴奋,但这不是重点。关键是你现在知道如何在运行时构建对话框模板。
总结
今天我们通过代码的方式,演示了如何在运行时创建一个自定义的对话框模板。
感觉是否还不错?
关键在于,你可以举一反三,将此技术放入到你的常用工具箱中,万一你的”Java大项目”哪天需要用到呢?
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Building a dialog template at run-time》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。
- 下一篇: 管理加速键和焦点矩形的 UI 状态
- 上一篇: 使用消息过滤器找回丢失的线程消息
相关推荐
- 代码片段:Crypto++使用方法汇总
- Posted on 06月26日
- 不是所有的短文件名都包含有波浪符号
- Posted on 02月08日
- OpenStack专题:Please ensure your tgtd config file contains ‘include /var/lib/cinder/volumes/*
- Posted on 01月11日
- 小技巧:远程桌面默认开启ClearType
- Posted on 04月16日
评论已关闭。