翻译来源:https://www.codeproject.com/Articles/28336/StyleDialog-A-transparent-dialog-class-with-an-opt
介绍
CodeProject有几个透明对话框; 但是,它们都不提供通用对话框,允许您在透明区域上绘制。原因是因为Windows首先不能有效地支持透明CWnd
对象。
上图显示了StyleDialog与Style Toolkit [ ^ ] 1.1版本一起使用。但是,StyleDialog可以使用或不使用工具包,有或没有透明度。
创建透明对话框中的问题
StyleDialog需要的关键功能是使用透明区域。这意味着,您可以绘制,绘制,并添加控件。
以下是使用的一些典型方法,以及相关的缺点:
- 返回
HOLLOW_BRUSH
的OnCtlColor
-这工作好了控制,因为应用程序控制的背景。它也适用于一个对话框,只要你不移动它,这使得它相对没有用。它也会导致子控件停止接收他们的OnCtlColor
消息。 - 使用区域 - 这个解决方案运行得很好; 但是,您不能使用透明区域。另外,由于你不能反边界的边缘,边缘看起来有点粗糙。
- 分层的Windows - 这是创建一个真正的透明窗口的唯一方法。这可以很好地产生淡入淡出的效果,但由于透明度适用于整体
CWnd
,所以不能让某些东西透明,而其他的则不透明。 - 分层
CWnd
s - 这些解决方案的外观和行为最好,但它们不是通用的,也不能在透明区域上绘画。
StyleDialog设计注意事项
难以克服的其他问题是拖动窗口时的抖动,并且在应用程序不是活动窗口时保持正确的背景。
为了克服这些问题,StyleDialog强加了以下设计规则:
- 显示不是活动应用程序时的备用背景。这克服了当应用程序可见但不活动时,背景更改的问题。
- 拖动应用程序时显示备用背景。实际上,StyleDialog可以在拖动时显示正确的背景,但是与分层窗口相关联的抖动是不合需要的。
StyleDialog通过使用不透明的分层窗口实现透明度,并利用它保持在屏幕外位图中的优势。
使用StyleDialog
步骤1 - 在StyleDialog.h中配置使用
// comment out this line if Style Toolkit is not used #define USE_STYLE_TOOLKIT // comment out this line if transparency is not supported #define USE_LAYERED_WINDOWS
步骤2 - 从StyleDialog派生一个对话框
像往常一样使用向导创建一个基于对话框的应用程序。替换的所有实例CDialog
用StyleDialog
。注意:CAboutDlg
在做更换时跳过,除非你想要它也是StyleDialog
。
对于子对话框,只需将其声明为StyleDialog
。有关示例,请参阅演示程序。
步骤3 - 配置StyleDialog
在打电话OnInitDialog
或之前进行以下操作DoModal
。
// configure StyleDialog before calling the init function SetTransparent(TRUE); SetControls(ALL_CONTROLS); SetTitle(_T("Style Dialog Demo"));
SetTransparent
实现透明度。它默认为禁用,因为如果不使用它,它将浪费带宽。SetControls
告诉StyleDialog
在有自定义框架时要使用的控件。这在下面更详细地描述。默认是无控制。SetTitle
是使用自定义框架时将在任务栏中显示的标题。默认值为空字符串。
步骤4 - 向对话框添加样式[可选]
用对话框加载样式AddBackGroundStyle(style)
。
StyleDialog的最小实现
下面的图像和代码来自演示程序的Dialog 3按钮。
StyleDialog dlg(IDD_DIALOG3); dlg.SetTransparent(TRUE); dlg.SetTitle(_T("Standard Frame")); dlg.DoModal();
此示例使用标准框架,并且不使用Style Toolkit。实际上没有必要设置标题,但是如果没有,则只会说出“对话框”。
控制替代背景
如果启用StyleDialog
了透明度,当它不是活动应用程序时或当窗口被移动时,将显示备用背景。替代背景将在透明区域上可能绘制的任何内容。
默认情况下,备用背景将是桌面背景颜色的实心填充。这可以通过以下方法之一覆盖:
SetOpaqueColor(clr)
- 将实心填充更改为另一种颜色。AddOpaqueStyle(style)
- 将填充更改为样式。
对话框2按钮演示了背景风格的使用。
此示例使用不带控件的自定义框架和使用半透明PNG图像的背景样式。
这显示无效状态。它使用相同图像的完全不透明版本的不透明样式。
创建自定义框架
StyleDialog
在创建自定义框架时,需要知道客户端矩形的大小。这是对标题栏区域进行命中测试和支持重写功能所需要的GetClientRect()
。
StyleDialog
维护可以检索的外框GetFrameRect
和可以检索的客户端框架GetClientRect
。请注意,Windows不会将其视为客户端矩形。有些情况下,您应该使用绘画或删除,GetFrameRect
或CDialog::GetClientRect
获得客户端矩形的Windows定义。
方法1 - 使用SetClientRect
调用GetFrameRect()
外框框架,调整边框和标题栏大小,然后调用SetClientRect()
。
方法2 - 使用资源编辑器
使用资源编辑器并创建具有静态控件的客户端矩形。这具有在设计对话框时能够调整标题和边框大小的优点。使用静态图片控件,因为它没有任何偏移。
将控件的ID设置为其中一个SytleDialog
关键字ID IDC_SC_CLIENT
。当StyleDialog
在resource.h文件中检测到此ID时,它将自动创建客户端矩形。
还有如下图所示的控件的关键字ID。
如果StyleDialog
看到任何控件ID,它将StyleButton
为它们创建s并使用关联的图像加载它们。它还将为每个按钮创建预期的功能。
其他注意事项
StyleDialog不支持最大化; 实际上它会禁用它。原则上可以支持这一点,但是我以后没有打算添加这个功能。
我没有真正计划支持透明对话框的透明对话框; 然而,它似乎工作正常,演示程序实际上这样做。
为了在打开子对话框时没有刻录效果,可以禁用父级的透明度,然后重新启用。但是,打开和关闭分层窗口可能会有时间问题,因此请谨慎使用此功能。
问题
- 使用自定义框架时最小化和还原 - 如果单击任务栏图标,StyleDialog将进入正确的活动或非活动状态,但不会最小化和还原。我认为这涉及系统菜单没有这个功能的事实,我希望在将来的版本中解决这个问题。
- VC6用户 - 如果您注释掉分层窗口功能,StyleDialog将会工作。分层窗口可以在Win2K SP3和更高版本上工作,但是您需要获取较新版本的winuser.h,user32.lib和user32.dll。