窗口贴图代码

来源:互联网 发布:网络不稳定老掉线 编辑:程序博客网 时间:2024/05/16 06:36

窗口调用时先将窗口定义为继承自此窗口类,

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);
   
}

 

 

 

原创粉丝点击