65.9K
CodeProject 正在变化。 阅读更多。
Home

一组有用的分隔符

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (29投票s)

2003年10月2日

CPOL

4分钟阅读

viewsIcon

123472

downloadIcon

3196

一些替换分组框的对话框分隔符。

Sample Image - Separators.gif

引言

这组类是用于对话框中的项分隔符集。它们看起来就像Office 2000/XP选项中使用的分隔符,并具有额外功能。该集包含四个控件

  • CSeparator:简单的控件,仅绘制一个斜角线
  • CStaticSeparator:静态文本,右侧带有一个斜角线
  • CCheckBoxSeparator:复选框,右侧带有一个斜角线,可以自动启用/禁用一组控件
  • CSectionSeparator:静态文本,右侧带有一个斜角线,可以自动隐藏/显示一组控件。

在上图所示的控件顺序为:CStaticSeparatorCCheckBoxSeparatorCSectionSeparator CSeparator。在第二个截图中,已单击CCheckBoxSeparator (启用了“关于...”按钮),并且CSectionSeparator 已折叠。

用法

使用这些控件非常简单:只需在对话框编辑器中绘制它们,并使用您想要的类为其分配一个值。不要忘记正确调整控件大小:线条将延伸到控件的右边缘。

在对话框编辑器中,为CSeparatorCStaticSeparator CSectionSeparator使用静态控件。为CCheckBoxSeparator使用复选框。

CSeparator CStaticSeparator 无需进一步操作。CCheckBoxSeparator CSectionSeparator 需要进行设置,以便它们知道应在哪些控件上执行其操作。

最简单的方法是使用SetNextSectionId(int id),该方法在两个类中都可用。将参数设置为定义下一节开始的控件的ID。分隔符本身与传递的ID之间的所有控件都将由分隔符控制。如果您的分隔符是对话框的最后一节,则传递-1,分隔符下的所有控件都将受到影响。

这必须在您的对话框的InitDialog中完成。对于CCheckBoxSeparator ,请不要忘记调用UpdateControlledDlgItems(),以便根据复选框的状态正确禁用/启用项目。对于CSectionSeparator ,您可以调用Collapse()使其初始显示为折叠状态。

实现相当简单,所以我不打算多说,只提两点。它们是。

绘图

简而言之,关于如何绘制斜角线。感谢David Y. Zhao及其XP Visual Style支持文件 [^],我们能够在Windows XP下绘制支持XP主题的斜角线。我们只需打开主题数据,然后告诉主题数据在我们的DC中绘制自己。如果应用程序未设置主题,则我们使用标准的CDC调用来绘制线条和斜角。

正如MSDN所述,一个好的控件应该正确处理WM_PRINTWM_PRINTCLIENT。所以我就是这么做的,OnPaint 只是调用Print处理程序。此外,我们需要正确实现这一点,以便在动画期间实现无闪烁的绘图(见下文)。

(展开/折叠)动画

CSectionSeparator (展开/折叠)时进行的动画可能是最棘手的部分。我想要平滑无闪烁的动画,这比我想象的要困难。

第一件事是使用BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos来避免逐个移动控件。使用这些函数(可在Win32 API中使用),我们将要移动的控件分组,Windows会在EndDeferWindowPos中一次性处理该操作。当我们在动画期间调整窗口大小时,我们会告诉EndDeferWindowPos不要重绘控件,并告诉它们在调整大小时重绘整个窗口。

为了消除闪烁,我使用了双缓冲技巧:告诉所有控件在内存DC中自行绘制(使用WM_PRINT消息),然后将内存DC BitBlt 到对话框的DC中。我想在调整父窗口大小时禁用重绘标志,因为我重绘了整个窗口,但当我这样做时,下面的窗口却不再更新。所以,我不得不保留它。对话框会绘制两次,但这似乎不是问题。

最后,因为我们想要恒定时间的动画,所以我们只需正确计时。如果我们时间超前,我们就稍微等待一下(使用类似于PumpMessage 的循环来避免应用程序冻结并允许底层窗口重绘自身)。如果我们滞后,我们就前进帧计数器以跳过我们错过的帧。

为了计时,我使用性能计数器进行精确测量。有关性能计数器的更多信息可以在此处 [^]找到。

设置

您可以通过更改SectionSeparator.cpp顶部的常量来调整动画。您可以更改每秒帧数和动画时长。使用0使其尽快运行。使用-1则不使用动画,实现即时折叠/展开效果。

结论

我想我已经讲了我想要的一切。希望您喜欢这些分隔符,并在您的下一个应用程序中使用它们! 抱歉,我不再安装Visual Studio 6.0了,所以无法为演示项目提供dsw/dsp文件。但仍包含可执行文件,您可以查看。

历史

  • 更新于2003年12月16日 - 添加了对XP主题属性页的支持
© . All rights reserved.