导航:[首页]->[wtl]->[使用SetLayeredWindowAttributes绘制半透明/异性窗口]
/*
使用SetLayeredWindowAttributes/LWA_COLORKEY 实现异型窗口
*/
template<typename T,bool DLG>
class LayeredWindow
{
public:
BEGIN_MSG_MAP(LayeredWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(!DLG)
this->InitSelf();
bHandled = FALSE;
return 0;
}
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(DLG)
this->InitSelf();
bHandled = FALSE;
return 0;
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
T* pT = static_cast<T*>(this);
CPaintDC dc_(pT->m_hWnd);
return 0;
}
LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/){
T* pT = static_cast<T*>(this);
CDCHandle dc_((HDC)wParam);
CRect clt_rect_;
pT->GetClientRect(clt_rect_);
TileBitBlt(dc_,*m_background_,clt_rect_);
return 0;
}
void SetBgBitmapInfo(CBitmap* bitmap,COLORREF mask){
ATLASSERT(bitmap);
m_background_ = bitmap;
m_mask_ = mask;
}
private:
void InitSelf(){
ATLASSERT(m_background_);
T* pT = static_cast<T*>(this);
LONG lWindowLong = GetWindowLong(pT->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED;
::SetWindowLong(pT->m_hWnd, GWL_EXSTYLE, lWindowLong);
::SetLayeredWindowAttributes(pT->m_hWnd,m_mask_,0,LWA_COLORKEY);
CSize size_;
m_background_->GetSize(size_);
int nWidth=GetSystemMetrics(SM_CXSCREEN); //屏幕宽度
int nHeight=GetSystemMetrics(SM_CYSCREEN); //屏幕高度
pT->MoveWindow(
(nWidth - size_.cx)/2,
(nHeight - size_.cy)/2,
size_.cx,
size_.cy);
}
protected:
CBitmap* m_background_;
COLORREF m_mask_;
};
/*
使用SetLayeredWindowAttributes/LWA_COLORKEY 实现异型窗口
*/
template<typename T,bool DLG>
class TranslucentWindow
{
public:
BEGIN_MSG_MAP(TranslucentWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(!DLG)
this->InitSelf();
bHandled = FALSE;
return 0;
}
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(DLG)
this->InitSelf();
bHandled = FALSE;
return 0;
}
void SetTranslucent(unsigned char translucent){
this->m_translucent_ = translucent;
}
private:
void InitSelf(){
T* pT = static_cast<T*>(this);
LONG lWindowLong = ::GetWindowLong(pT->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED;
::SetWindowLong(pT->m_hWnd, GWL_EXSTYLE, lWindowLong);
::SetLayeredWindowAttributes(pT->m_hWnd,0,m_translucent_,LWA_ALPHA);
}
protected:
unsigned char m_translucent_;
};
##Sample
CMainFrame wndMain;
CBitmap bitmap_bg_;
BOOL ret_ = File2CBitmap(&bitmap_bg_,_T("res/bg.bmp"));
ATLASSERT(ret_);
wndMain.SetBgBitmapInfo(&bitmap_bg_,RGB(255,0,255));
if(wndMain.CreateEx() == NULL)
{
ATLTRACE(_T("Main window creation failed!\n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);
class CMainFrame :
public CFrameWindowImpl<CMainFrame>,
public LayeredWindow<CMainFrame,false>
{
typedef LayeredWindow<CMainFrame,false> BaseClass;
public:
static DWORD GetWndStyle(DWORD dwStyle)
{
return WS_POPUP /*| WS_CLIPCHILDREN*/;
}
DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
BEGIN_MSG_MAP(CMainFrame)
REFLECT_NOTIFICATIONS()
CHAIN_MSG_MAP(BaseClass)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnDlg)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 0;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
// 解决wtl不能关闭ws_popup的bug
PostQuitMessage(0);
bHandled = FALSE;
return 1;
}
LRESULT OnDlg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
CAboutDlg dlg;
dlg.SetTranslucent(100);
dlg.DoModal();
return 1;
}
};
class CAboutDlg :
public CDialogImpl<CAboutDlg>,
public TranslucentWindow<CAboutDlg,true>
{
typedef TranslucentWindow<CAboutDlg,true> BaseClass;
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP(CAboutDlg)
CHAIN_MSG_MAP(BaseClass)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
END_MSG_MAP()
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CenterWindow(GetParent());
return TRUE;
}
LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
EndDialog(wID);
return 0;
}
};
|
|