在现代的图形用户界面(GUI)设计中,半透明对话框为用户提供了更加丰富的视觉体验。本文将展示如何创建具有标准控件、ActiveX控件(如WebBrowser控件、Flash控件)以及与Windows 2000及更高版本兼容的半透明控件的对话框。
Jerry.Wang在他的文章《Cool, Semi-transparent and Shaped Dialogs with Standard Controls for Windows 2000 and Above》中提出了一种实现半透明对话框的方法。他创建了两个对话框:一个用于处理用户输入事件和Windows消息(真实对话框),另一个用于展示(假对话框)。假对话框通过CreateWindowEx
函数创建,使用WS_EX_LAYERED
、WS_EX_TRANSPARENT
和WS_EX_NOACTIVATE
样式,并始终保持与真实对话框相同的大小和位置。真实对话框几乎透明,因为它的透明度值通过SetLayeredWindowAttributes
函数修改为5。
尽管Jerry.Wang的方法在视觉上令人印象深刻,但它存在一些限制:
WM_PRINT
消息一起工作,导致这些控件无法正确显示。WM_PRINT
消息一起工作。为了解决上述问题,提出了一种新的方法。以下是实现机制的示意图:
半透明对话框使用WS_EX_LAYERED
和WS_OVERLAPPED
样式创建。在创建时,通过CreateWindowEx
函数创建一个标准对话框,使用WS_EX_LAYERED
、WS_POPUP
、无边框、无大小框和无对话框框架的样式。半透明对话框负责处理半透明背景和半透明控件;标准对话框负责处理标准控件和ActiveX控件。标准对话框始终保持与半透明对话框相同的大小和位置。
以下是使用原生C++/MFC实现半透明对话框的步骤:
CDialog
更改为CStandardDialog
。
CDialog
更改为CTranslucentDialog
。
CTranslucentWnd
类,如将CButton
子类化为CTranslucentButton
。以下演示源代码来自演示程序:
// 在 CDemoTranslucentDlg.h 中
CTranslucentButton m_btnTest;
CTranslucentProgressBar m_ctrlProgress;
// 在 CDemoTranslucentDlg.cpp 中
void CDemoTranslucentDlg::DoDataExchange(CDataExchange* pDX)
{
CTranslucentDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BUTTON1, m_btnTest);
DDX_Control(pDX, IDC_PROGRESS, m_ctrlProgress);
}
CreateStandardDialog
和OnInitChildrenWnds
方法。CreateStandardDialog
方法负责创建相应的标准对话框,OnInitChildrenWnds
方法负责设置半透明控件的属性并将它们注册到半透明对话框。以下演示源代码来自演示程序:
// 在 CDemoTranslucentDlg.cpp 中
CStandardDialog* CDemoTranslucentDlg::CreateStandardDialog()
{
return ::new CDemoStandardDlg(this);
}
void CDemoTranslucentDlg::OnInitChildrenWnds()
{
LPCTSTR szImageList[TWS_BUTTON_NUM] = { _T("res\\close_normal.PNG"),
_T("res\\close_disable.png"), _T("res\\close_over.PNG"),
_T("res\\close_down.PNG"), 0 };
m_btnTest.LoadImageList(szImageList);
RegisterTranslucentWnd(&m_btnTest);
m_ctrlProgress.MoveWindow(400, 400, 146, 61, TRUE);
m_ctrlProgress.SetPos(50);
m_ctrlProgress.SetFgImage(_T("res\\progress.png"));
RegisterTranslucentWnd(&m_ctrlProgress);
}