使窗口透明可以利用Windows提供的SetLaygerWindowAttributes设置透明和不透明的颜色关键值来实现的。
1 SetLaygerWindowAttributes函数
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,方法如下:
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实例,如下图所示:
![](http://images0.cnblogs.com/blog/522452/201401/201008087194.png)
滑动滚动条用于控制当前的透明度,调整的时候下面的编辑框会显示当前的透明度
#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); }