在Windows编程中,创建一个允许在其透明区域进行绘图的对话框是一项具有挑战性的任务。Windows操作系统本身并不直接支持透明的CWnd对象。尽管如此,可以通过一些技巧和方法来实现这一功能。本文将探讨创建透明对话框时遇到的一些问题,以及如何使用StyleDialog来实现透明效果。
实现StyleDialog的关键特性之一是能够使用透明区域。这意味着可以在其上进行绘制、绘画,并添加控件。以下是一些常用的方法及其相关的缺点:
在创建透明对话框时,需要克服的其他难题包括拖动窗口时的抖动问题,以及在应用程序不是活动窗口时保持正确的背景。为了克服这些问题,StyleDialog采用了以下设计规则:
StyleDialog通过使用不透明的层叠窗口,并利用它在屏幕外位图上被维护的事实,实现了透明效果。以下是使用StyleDialog的步骤:
// 如果不使用Style Toolkit,则注释掉此行
#define USE_STYLE_TOOLKIT
// 如果不支持透明度,则注释掉此行
#define USE_LAYERED_WINDOWS
像往常一样使用向导创建基于对话框的应用程序。将所有CDialog实例替换为StyleDialog。注意:在替换时跳过CAboutDlg,除非也希望它成为StyleDialog。对于子对话框,只需将它们声明为StyleDialog。请参阅演示程序以获取示例。
在调用OnInitDialog或DoModal之前,请执行以下操作:
// 在调用初始化函数之前配置StyleDialog
SetTransparent(TRUE);
SetControls(ALL_CONTROLS);
SetTitle(_T("Style Dialog Demo"));
SetTransparent启用透明度。默认情况下它被禁用,因为在未使用的情况下它会浪费带宽。SetControls告诉StyleDialog在有自定义框架时使用哪些控件。这在下面有更详细的描述。默认情况下没有控件。SetTitle是当使用自定义框架时在任务栏中显示的标题。默认为空字符串。
使用AddBackGroundStyle(style)将样式加载到对话框中。
以下图片和代码来自演示程序的Dialog 3按钮。
StyleDialog dlg(IDD_DIALOG3);
dlg.SetTransparent(TRUE);
dlg.SetTitle(_T("Standard Frame"));
dlg.DoModal();
此示例使用标准框架,并且不使用Style Toolkit。实际上,设置标题并不是必须的,但如果不做,它只会显示“Dialog”。
如果启用了透明度,StyleDialog将在不是活动应用程序或窗口正在移动时显示替代背景。替代背景将位于可能已在透明区域上绘制的任何内容下方。
默认情况下,替代背景将是桌面背景色的实心填充。这可以通过以下方式之一覆盖:
对话框2按钮演示了背景样式的使用。
此示例使用没有控件的自定义框架,以及带有半透明PNG图像的背景样式。
这显示了非活动状态。它使用相同图像的完全不透明版本作为不透明样式。
StyleDialog需要知道在创建自定义框架时客户矩形的大小应该是多少。这是进行标题栏区域的命中测试和支持重写函数GetClientRect()所需的。StyleDialog维护一个可以通过GetFrameRect获取的外部框架,以及可以通过GetClientRect获取的客户框架。请注意,Windows不将此视为客户矩形。在进行绘画或擦除时,应该使用GetFrameRect或CDialog::GetClientRect来获取Windows定义的客户矩形。
调用GetFrameRect()获取外部框架矩形,然后调整边框和标题栏大小,然后调用SetClientRect()。
使用资源编辑器并创建一个带有静态控件的客户矩形。这样做的好处是可以在设计对话框时调整标题和边框大小。使用静态图片控件,因为它没有偏移量。
将控件的ID设置为SytleDialog的一个关键字ID - IDC_SC_CLIENT。当StyleDialog在resource.h文件中检测到此ID时,它将自动创建客户矩形。
还有用于控件的关键字ID,如下面的图片所示。
如果StyleDialog看到任何控件ID,它将为它们创建StyleButton,并加载关联的图像。它还将为每个按钮创建预期的功能。
StyleDialog不支持最大化;实际上,它禁用了它。原则上,这个功能可以被支持,但没有计划在未来添加这个功能。
并没有真正计划支持带有透明子对话框的透明对话框;然而,它似乎工作得很好,演示程序实际上就是这样做的。
为了避免在打开子对话框时出现烧穿效果,可以禁用父对话框的透明度,然后再重新启用。然而,开启和关闭层叠窗口可能存在时间问题,因此请谨慎使用此功能。
使用自定义框架时的最小化和恢复 - 如果点击任务栏图标,StyleDialog将进入正确的活动或非活动状态,但它不会最小化和恢复。认为这与系统菜单没有此功能有关,希望在未来的版本中修复这个问题。
VC6用户 - 如果注释掉层叠窗口功能,StyleDialog将按原样工作。层叠窗口将在Win2K SP3及更高版本上工作,但需要获取更新版本的winuser.h、user32.lib和user32.dll。