窗口调用时先将窗口定义为继承自此窗口类,
class CAboutDlg : public CDialogSK
{
public:
CAboutDlg();
};
然后在窗口的OnInitDialog事件中调用SetBitmap(IDB_DLG_BK)和SetStyle(LO_RESIZE);
CDialogSK代码:
// ===========================================================================
// File CDialogSk.h
//
// Path $(PROJECTROOT)
// Desc Definition for the class CButtonSK
//
// Rev
//
// This computer program is copyright to Texas Instruments Inc.
// The program may not be used without the written permission
// of Texas Instruments Inc. or against the terms and conditions
// stipulated in the agreement under which this proram has been
// supplied.
//
// (c) Texas Instruments 2002
// ===========================================================================
// Revision History
//
// DEC 16, 2002 REF=ORG Abhinaba Basu
// Original implementation
// ===========================================================================
#ifndef _ABHI_CDIALOG_H_
#define _ABHI_CDIALOG_H_
// ===========================================================================
// Layout styles for the background bmp
// ===========================================================================
enum LayOutStyle
{
LO_DEFAULT,
LO_TILE, // Tile the background picture
LO_CENTER, // Center the background picture
LO_STRETCH, // Stretch the background picture to the dialog window size
LO_RESIZE // Resize the dialog so that it just fits the background
};
// ===========================================================================
// class CDialogSK
// desc This class can be used to skin Dialogs
// To use this class create Dialog and then make the dialog class
// derive from CDialogSK instead of CDialog
// ===========================================================================
class CDialogSK : public CDialog
{
public:
// =======================================================================
// desc constructor / desctructors
//
// arg1 handle to the bitmap for the bitmap
// =======================================================================
CDialogSK(CWnd* pParent = NULL);
CDialogSK(UINT uResourceID, CWnd* pParent = NULL);
CDialogSK(LPCTSTR pszResourceID, CWnd* pParent = NULL);
virtual ~CDialogSK();
// =======================================================================
// desc Set the bitmap for the button
//
// arg1 handle to the bitmap for the bitmap
// =======================================================================
DWORD SetBitmap(HBITMAP hBitmap);
// =======================================================================
// desc Set the bitmap for the button
//
// arg1 Resource Id for the bitmap
// =======================================================================
DWORD SetBitmap(int nBitmap);
// =======================================================================
// desc Set the bitmap for the button
//
// arg1 Name of the bitmap file
// =======================================================================
DWORD SetBitmap(LPCTSTR lpszFileName);
// =======================================================================
// desc Set the bitmap layout style
//
// arg1 See the definition of LayOutStyle above
// =======================================================================
void SetStyle(LayOutStyle style);
// =======================================================================
// desc Allows moving of the dialog by clicking anywhere in the dialog
//
// arg1 TRUE enables, FLASE disables
// =======================================================================
void EnableEasyMove (BOOL pEnable = TRUE);
// =======================================================================
// desc Makes the dialog transparent
//
// arg1 Alpha range is 0-255. If 255 then dialog becomes opaque
// ret TRUE if successful
// =======================================================================
BOOL SetTransparent (BYTE bAlpha);
// =======================================================================
// desc Makes one color on the dialog transparent. This can be used
// to create irregular shaped dialogs
//
// arg1 color to be made transparent
// arg2 TRUE will use the color, FALSE remove transparency
// ret TRUE if successful
// =======================================================================
BOOL SetTransparentColor (COLORREF col, BOOL bTrans = TRUE);
void SetupRegion(CDC *pDC);
void DrawTransBitmap(HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
);
// Dialog Data
//{{AFX_DATA(CDialogSK)
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDialogSK)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CDialogSK)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
BOOL m_bEasyMove;
void FreeResources();
void Init();
HBITMAP m_hBitmap;
DWORD m_dwWidth; // Width of bitmap
DWORD m_dwHeight; // Height of bitmap
LayOutStyle m_loStyle; // LayOutStyle style
};
#endif // _ABHI_CDIALOG_H_
#include "stdafx.h"
#include "DialogSK.h"
/////////////////////////////////////////////////////////////////////////////
// CDialogSK dialog
// these variables should have been defined in some standard header but is not
#define WS_EX_LAYERED 0x00080000
#define LWA_COLORKEY 1 // Use color as the transparency color.
#define LWA_ALPHA 2 // Use bAlpha to determine the opacity of the layer
// ===========================================================================
// Function pointer for lyering API in User32.dll
// ===========================================================================
typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)
(HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags);
lpfnSetLayeredWindowAttributes g_pSetLayeredWindowAttributes;
CDialogSK::CDialogSK(CWnd* pParent /*=NULL*/)
{
//{{AFX_DATA_INIT(CBkDialogST)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
Init();
}
CDialogSK::CDialogSK(UINT uResourceID, CWnd* pParent)
: CDialog(uResourceID, pParent)
{
Init();
}
CDialogSK::CDialogSK(LPCTSTR pszResourceID, CWnd* pParent)
: CDialog(pszResourceID, pParent)
{
Init();
}
CDialogSK::~CDialogSK()
{
FreeResources();
}
BOOL CDialogSK::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE;
}
void CDialogSK::SetupRegion(CDC *pDC)
{
CDC memDC;
CBitmap* cBitmap=CBitmap::FromHandle(m_hBitmap);
CBitmap* pOldMemBmp = NULL;
COLORREF col,colMask;
CRect cRect;
int x, y;
CRgn wndRgn, rgnTemp;
int iPixel=5;
GetWindowRect(&cRect);
CPoint ptOrg=cRect.TopLeft();
BITMAP bmInfo;
cBitmap->GetObject(sizeof(bmInfo),&bmInfo);
CRect rcNewWnd=CRect(ptOrg,CSize(bmInfo.bmWidth,bmInfo.bmHeight));
memDC.CreateCompatibleDC(pDC);
pOldMemBmp = memDC.SelectObject(cBitmap);
colMask=RGB(255,0,255);//memDC.GetPixel(0,0);
wndRgn.CreateRectRgn(0, 0, rcNewWnd.Width(), rcNewWnd.Height());
// for(x=0; x<=rcNewWnd.Width(); x++)
// {
// for(y=0; y<=rcNewWnd.Height(); y++)
// {
// col = memDC.GetPixel(x, y);
// if(col == colMask)
// {
// rgnTemp.CreateRectRgn(x, y, x+1, y+1);
// wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
// rgnTemp.DeleteObject();
// }
// }
// }
for(x=0; x<=iPixel; x++)
{
for(y=0; y<=iPixel; y++)
{
col = memDC.GetPixel(x, y);
if(col == colMask)
{
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
for(x=rcNewWnd.Width()-iPixel; x<=rcNewWnd.Width(); x++)
{
for(y=0; y<=iPixel; y++)
{
col = memDC.GetPixel(x, y);
if(col == colMask)
{
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
for(x=0; x<=iPixel; x++)
{
for(y=rcNewWnd.Height()-iPixel; y<=rcNewWnd.Height(); y++)
{
col = memDC.GetPixel(x, y);
if(col == colMask)
{
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
for(x=rcNewWnd.Width()-iPixel; x<=rcNewWnd.Width(); x++)
{
for(y=rcNewWnd.Height()-iPixel; y<=rcNewWnd.Height(); y++)
{
col = memDC.GetPixel(x, y);
if(col == colMask)
{
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
if (pOldMemBmp) memDC.SelectObject(pOldMemBmp);
SetWindowRgn((HRGN)wndRgn, TRUE);
MoveWindow(rcNewWnd);
// wndRgn.DeleteObject();
// cBitmap->DeleteObject();
// pOldMemBmp->DeleteObject();
// memDC.DeleteDC();
}
BOOL CDialogSK::SetTransparent (BYTE bAlpha)
{
// if (g_pSetLayeredWindowAttributes == NULL)
// return FALSE;
//
// if (bAlpha < 255)
// {
// // set layered style for the dialog
// SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
//
// // call it with 255 as alpha - opacity
// g_pSetLayeredWindowAttributes(m_hWnd, 0, bAlpha, LWA_ALPHA);
// }
// else
// {
// SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
//
// // Ask the window and its children to repaint
// ::RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
// }
return TRUE;
}
BOOL CDialogSK::SetTransparentColor (COLORREF col, BOOL bTrans)
{
// if (g_pSetLayeredWindowAttributes == NULL)
// return FALSE;
//
// if (bTrans)
// {
// // set layered style for the dialog
// SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// // call it with 0 alpha for the given color
// g_pSetLayeredWindowAttributes(m_hWnd, col, 0, LWA_COLORKEY);
// }
// else
// {
// SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
//
// // Ask the window and its children to repaint
// ::RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
// }
//
return TRUE;
}
void CDialogSK::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDialogSK)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDialogSK, CDialog)
//{{AFX_MSG_MAP(CDialogSK)
ON_WM_LBUTTONDOWN()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialogSK message handlers
void CDialogSK::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_bEasyMove)
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
CDialog::OnLButtonDown(nFlags, point);
}
void CDialogSK::Init()
{
m_hBitmap = NULL;
m_bEasyMove = TRUE;
m_loStyle = LO_DEFAULT;
// get the function from the user32.dll
// HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
// g_pSetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)
// GetProcAddress(hUser32, "SetLayeredWindowAttributes");
}
void CDialogSK::FreeResources()
{
if (m_hBitmap)
::DeleteObject (m_hBitmap);
m_hBitmap = NULL;
}
DWORD CDialogSK::SetBitmap(int nBitmap)
{
HBITMAP hBitmap = NULL;
HINSTANCE hInstResource = NULL;
// Find correct resource handle
hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmap), RT_BITMAP);
// Load bitmap In
hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmap),
IMAGE_BITMAP, 0, 0, 0);
return SetBitmap(hBitmap);
}
DWORD CDialogSK::SetBitmap(HBITMAP hBitmap)
{
int nRetValue;
BITMAP csBitmapSize;
// Free any loaded resource
FreeResources();
if (hBitmap)
{
m_hBitmap = hBitmap;
// Get bitmap size
nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize);
if (nRetValue == 0)
{
FreeResources();
return 0;
}
m_dwWidth = (DWORD)csBitmapSize.bmWidth;
m_dwHeight = (DWORD)csBitmapSize.bmHeight;
}
if (IsWindow(this->GetSafeHwnd()))
Invalidate();
CWindowDC dc(this);
SetupRegion(&dc);
// CDC *dc=GetDC();
// SetupRegion(dc);
return 1;
}
DWORD CDialogSK::SetBitmap(LPCTSTR lpszFileName)
{
HBITMAP hBitmap = NULL;
hBitmap = (HBITMAP)::LoadImage(0, lpszFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
return SetBitmap(hBitmap);
}
BOOL CDialogSK::OnEraseBkgnd(CDC* pDC)
{
BOOL bRetValue = CDialog::OnEraseBkgnd(pDC);
if (!m_hBitmap)
return bRetValue;
CRect rect;
GetClientRect(rect);
// CDC dc;
// dc.CreateCompatibleDC(pDC);
// HBITMAP pbmpOldBmp = NULL;
// pbmpOldBmp = (HBITMAP)::SelectObject(dc.m_hDC, m_hBitmap);
// //pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
// SetupRegion(pDC);
// return bRetValue;
CDC dc;
dc.CreateCompatibleDC(pDC);
// CDC tmpDC;
HBITMAP pbmpOldBmp = NULL;
pbmpOldBmp = (HBITMAP)::SelectObject(dc.m_hDC, m_hBitmap);
//tmpDC.SelectObject(m_hBitmap);
//pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
if ( m_loStyle == LO_DEFAULT || m_loStyle == LO_RESIZE )
{
DrawTransBitmap(pDC->m_hDC,0,0,rect.Width(), rect.Height(), dc.m_hDC, 0, 0,rect.Width(), rect.Height(),RGB(255,0,255));
//pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
}
else if (m_loStyle == LO_TILE)
{
int ixOrg, iyOrg;
for (iyOrg = 0; iyOrg < rect.Height(); iyOrg += m_dwHeight)
{
for (ixOrg = 0; ixOrg < rect.Width(); ixOrg += m_dwWidth)
{
DrawTransBitmap(pDC->m_hDC,ixOrg, iyOrg,rect.Width(), rect.Height(), dc.m_hDC, 0, 0,rect.Width(), rect.Height(),RGB(255,0,255));
//pDC->BitBlt (ixOrg, iyOrg, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
}
}
}
else if (m_loStyle == LO_CENTER)
{
int ixOrg = (rect.Width() - m_dwWidth) / 2;
int iyOrg = (rect.Height() - m_dwHeight) / 2;
DrawTransBitmap(pDC->m_hDC,ixOrg, iyOrg,rect.Width(), rect.Height(), dc.m_hDC, 0, 0,rect.Width(), rect.Height(),RGB(255,0,255));
//pDC->BitBlt(ixOrg, iyOrg, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
}
else if ( m_loStyle == LO_STRETCH)
{
DrawTransBitmap(pDC->m_hDC,0, 0,rect.Width(), rect.Height(), dc.m_hDC, 0, 0,m_dwWidth, m_dwHeight,RGB(255,0,255));
// pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, m_dwWidth, m_dwHeight, SRCCOPY);
}
::SelectObject(dc.m_hDC, m_hBitmap);
return bRetValue;
}
void CDialogSK::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (m_hBitmap != NULL)
{
Invalidate();
}
}
void CDialogSK::EnableEasyMove(BOOL pEnable)
{
m_bEasyMove = pEnable;
}
void CDialogSK::SetStyle(LayOutStyle style)
{
m_loStyle = style;
if(m_loStyle == LO_RESIZE && m_hBitmap)
{
SetWindowPos(0, 0, 0, m_dwWidth, m_dwHeight, SWP_NOMOVE | SWP_NOREPOSITION );
}
}
void CDialogSK::DrawTransBitmap(HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
)
{
HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图
HDC hImageDC = CreateCompatibleDC(hdcDest);
HDC hMaskDC = CreateCompatibleDC(hdcDest);
hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);
// SetBkMode(hImageDC,TRANSPARENT);
// SetBkMode(hMaskDC,TRANSPARENT);
// 将源DC中的位图拷贝到临时DC中
if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
else
StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
// 设置透明色
SetBkColor(hImageDC, crTransparent);
// 生成透明区域为白色,其它区域为黑色的掩码位图
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
// 生成透明区域为黑色,其它区域保持不变的位图
SetBkColor(hImageDC, RGB(0,0,0));
SetTextColor(hImageDC, RGB(255,255,255));
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// 透明部分保持屏幕不变,其它部分变成黑色
SetBkColor(hdcDest,RGB(0xff,0xff,0xff));
SetTextColor(hdcDest,RGB(0,0,0));
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// "或"运算,生成最终效果
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
SelectObject(hImageDC, hOldImageBMP);
DeleteDC(hImageDC);
SelectObject(hMaskDC, hOldMaskBMP);
DeleteDC(hMaskDC);
DeleteObject(hImageBMP);
DeleteObject(hMaskBMP);
}