使窗口透明可以利用Windows提供的SetLaygerWindowAttributes设置透明和不透明的颜色关键值来实现的。
1 SetLaygerWindowAttributes函数
1
2
3
4
5
6
|
BOOL SetLayeredWindowAttributes( HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
); |
参数说明:
hWnd是透明窗体的句柄,
crKey为掩码的颜色,可以用RGB(r,g,b)来指定。
bAlpha是不透明度,取值范围是(0,255),其中0代表全透明,255代表不透明。
dwFlags是透明方式,可以取两个值:
当取值为LWA_ALPHA(0x2)时,crKey参数无效,bAlpha参数有效;
当取值为LWA_COLORKEY(0x1)时,窗体中的所有颜色为crKey的地方将变为透明,bAlpha参数无效。
也可以取两个值的组合:LWA_ALPHA Or
LWA_COLORKEY。这样crKey的地方将变为全透明,而其它地方根据bAlpha参数确定透明度。
2 使用说明
2.1
用使窗体具有透明效果,必须先使要操作的窗体具有WS_EX_LAYERED扩展属性,方法:
1 SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE, 2 GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);
2.2 调用函数::SetLayeredWindowAttributes(), 如::SetLayeredWindowAttributes(m_hWnd,0,128,2);
也可以调用动态链接库中的::SetLayeredWindowAttributes,方法如下:
1
2
3
4
5
6
7
8
9
|
HINSTANCE hInst = LoadLibrary( "User32.DLL" ); //显式加载DLL
if (hInst)
{
typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
MYFUNC fun = NULL;
fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes" ); //取得SetLayeredWindowAttributes函数指针
if (fun)fun( this ->GetSafeHwnd(),0,128,2);
FreeLibrary(hInst);
}
|
注意:
在VC6中调用SetLayeredWindowAttributes时,要先定义_WIN32_WINNT这个宏的值,用于确定操作系统。
如:
#define _WIN32_WINNT 0x0500
#include "windows.h"
//当 _WIN32_WINNT >=
0x0500时,才能连接得到SetLayeredWindowAttributes函数。
//需要定义在windows.h的前面
3 VC实现实例
下面是一个用于调节当前对话框透明度的VC实例,如下图所示:
滑动滚动条用于控制当前的透明度,调整的时候下面的编辑框会显示当前的透明度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#pragma once #include "afxwin.h" #include "afxcmn.h" // CTransDlg 对话框 class
CTransDlg : public
CDialog
{ DECLARE_DYNAMIC(CTransDlg)
public :
CTransDlg(CWnd* pParent = NULL); // 标准构造函数
virtual
~CTransDlg();
virtual
BOOL OnInitDialog();
// 对话框数据 enum
{ IDD = IDD_TRANSDLG };
protected :
virtual
void
DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public :
afx_msg void
OnNMCustomdrawSliderTrans(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void
OnNMReleasedcaptureSliderTrans(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void
OnBnClickedCancel();
afx_msg void
OnBnClickedOk();
CStatic m_image;
CSliderCtrl m_slider;
CEdit m_alpahEdit;
afx_msg void
OnEnChangeEditTrans();
}; |
// TransDlg.cpp : 实现文件 // #include "stdafx.h" #include "MainWin.h" #include "TransDlg.h" // CTransDlg 对话框 IMPLEMENT_DYNAMIC(CTransDlg, CDialog) CTransDlg::CTransDlg(CWnd* pParent /*=NULL*/) : CDialog(CTransDlg::IDD, pParent) { } CTransDlg::~CTransDlg() { } void CTransDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_IMAGE_TRANS, m_image); DDX_Control(pDX, IDC_SLIDER_TRANS, m_slider); DDX_Control(pDX, IDC_EDIT_TRANS, m_alpahEdit); } BEGIN_MESSAGE_MAP(CTransDlg, CDialog) ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_TRANS, &CTransDlg::OnNMCustomdrawSliderTrans) ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_TRANS, &CTransDlg::OnNMReleasedcaptureSliderTrans) ON_BN_CLICKED(IDC_CANCEL, &CTransDlg::OnBnClickedCancel) ON_BN_CLICKED(IDC_OK, &CTransDlg::OnBnClickedOk) ON_EN_CHANGE(IDC_EDIT_TRANS, &CTransDlg::OnEnChangeEditTrans) END_MESSAGE_MAP() // CTransDlg 消息处理程序 void CTransDlg::OnNMCustomdrawSliderTrans(NMHDR *pNMHDR, LRESULT *pResult) { LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0; } void CTransDlg::OnNMReleasedcaptureSliderTrans(NMHDR *pNMHDR, LRESULT *pResult) { // TODO: 在此添加控件通知处理程序代码 BYTE pos = m_slider.GetPos(); ::SetLayeredWindowAttributes(m_hWnd, 0, pos, 2); CString showAlpha; showAlpha.Format(_T("%d"),m_slider.GetPos()); m_alpahEdit.SetWindowText(showAlpha); UpdateData(FALSE); *pResult = 0; } void CTransDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 } void CTransDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 } BOOL CTransDlg::OnInitDialog() { CDialog::OnInitDialog(); m_slider.SetRange(10,255); m_slider.SetPos(128); //设置窗体属性,要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性 SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE, GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000); ::SetLayeredWindowAttributes(m_hWnd,0,128,2); //m_alpha = m_slider.GetPos(); UpdateData(FALSE); return TRUE; } void CTransDlg::OnEnChangeEditTrans() { // TODO: 如果该控件是 RICHEDIT 控件,则它将不会 // 发送该通知,除非重写 CDialog::OnInitDialog() // 函数并调用 CRichEditCtrl().SetEventMask(), // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 // TODO: 在此添加控件通知处理程序代码 int nAlpah = GetDlgItemInt(IDC_EDIT_TRANS); //::SetLayeredWindowAttributes(m_hWnd,0, 128,LWA_ALPHA); }