mfc 不规则对话框

BitmapDialog.h :

#if !defined(AFX_BITMAPDIALOG_H__A76F9E74_DF43_11D4_AE27_4854E828E6FD__INCLUDED_)
#define AFX_BITMAPDIALOG_H__A76F9E74_DF43_11D4_AE27_4854E828E6FD__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// BitmapDialog.h : header file
//

/
// CBitmapDialog dialog

class CBitmapDialog : public CDialog
{
// Construction
public:
    // Common constructor
    void Constructor (LPCTSTR lpszResourceName, UINT nIDResource,
        LPCTSTR lpszFilename, CBitmap *pBitmap);

    CBitmapDialog (LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL,
        LPCTSTR lpszResourceName = NULL, UINT nIDResource = 0,
        LPCTSTR lpszFilename = NULL, CBitmap *pBitmap = NULL);

    CBitmapDialog (UINT nIDTemplate, CWnd* pParentWnd = NULL,
        LPCTSTR lpszResourceName = NULL, UINT nIDResource = 0,
        LPCTSTR lpszFilename = NULL, CBitmap *pBitmap = NULL);

    CBitmapDialog (LPCTSTR lpszResourceName = NULL, UINT nIDResource = 0,
        LPCTSTR lpszFilename = NULL, CBitmap *pBitmap = NULL);

    // Destructor (just release the bitmap)
    ~CBitmapDialog () { ReleaseBitmap (); }

    // Bitmap
    BOOL LoadBitmap (LPCTSTR lpszResourceName,
        LPCTSTR lpszFilename);                    // Load from resource or file
    BOOL LoadBitmap (UINT nIDResource);            // Load from resource
    BOOL CopyBitmapFrom (CBitmap *pBitmap);        // Copy of user defined
    void SetBitmap (CBitmap *pBitmap);            // User defined
    void ReleaseBitmap ();
    CBitmap *GetBitmap () { return m_bmBitmap; }

    // Transparency
    void SetTransparent (BOOL bTransparent);
    BOOL GetTransparent () { return m_bTransparent; }
    void SetTransColor (COLORREF col);
    COLORREF GetTransColor () { return m_colTrans; }

    // Static control transparency
    void SetStaticTransparent (BOOL bTransparent) { m_bStaticTransparent = bTransparent; }
    BOOL GetStaticTransparent () { return m_bStaticTransparent; }

    // Clicking anywhere moves
    void SetClickAnywhereMove (BOOL bMove) { m_bClickAnywhereMove = bMove; }
    BOOL GetClickAnywhereMove () { return m_bClickAnywhereMove; }

// Dialog Data
    //{{AFX_DATA(CBitmapDialog)
        // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA


// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CBitmapDialog)
    protected:
    //}}AFX_VIRTUAL

// Implementation
protected:
    void    MakeWindowRgn ();

    // Transparency
    BOOL        m_bTransparent;
    BOOL        m_bStaticTransparent;
    HBRUSH        m_brushHollow;
    COLORREF    m_colTrans;

    // Clicking anywhere moves
    BOOL        m_bClickAnywhereMove;

    // Bitmap and its DC
    BOOL    m_bBitmapCreated, m_bBitmapExists;
    CBitmap    *m_bmBitmap;

    // Generated message map functions
    //{{AFX_MSG(CBitmapDialog)
    afx_msg BOOL OnEraseBkgnd (CDC *pDC);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_BITMAPDIALOG_H__A76F9E74_DF43_11D4_AE27_4854E828E6FD__INCLUDED_)

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

// BitmapDialog.cpp : implementation file
//
// Created by David Forrester, January 1, 2001
// Feel free to use this code in any way you want.

#include "stdafx.h"
#include "BitmapDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/
// CBitmapDialog dialog

//----------------------------------------------------------------
// CBitmapDialog :: CBitmapDialog - constructor for CBitmapDialog
//
// Parameters:
//  lpszTemplateName - the name of the dialog template resource
//  nIDTemplate - the ID of the dialog template resource
//  pParentWnd - the parent window
//
// You can leave any or all of the below NULL or 0 to not use it
//  lpszResourceName - the name of the bitmap resource to load
//  nIDResource - the ID of the bitmap resource to load
//  lpszFilename - the filename of the bitmap file to load
//  pBitmap - the bitmap to use (user is responsible for handling the bitmap)

// The common constructor for CBitmapDialog
void CBitmapDialog :: Constructor (LPCTSTR lpszResourceName, UINT nIDResource,
                                   LPCTSTR lpszFilename, CBitmap *pBitmap)
{
    m_bTransparent = FALSE;            // No transparency
    m_bStaticTransparent = TRUE;    // Static controls are transparent
    m_bBitmapCreated = FALSE;        // Don't automatically release the bitmap
    m_bBitmapExists = FALSE;        // IS there a bitmap?
    m_bClickAnywhereMove = FALSE;    // Clicking anywhere moves
    
    // Create a hollow brush used in making static controls transparent
    m_brushHollow = (HBRUSH) GetStockObject (HOLLOW_BRUSH);

    // Load a bitmap from a resource name
    if (lpszResourceName != NULL)
    {
        LoadBitmap (lpszResourceName, NULL);
    }
    // Load a bitmap from a resource ID
    else if (nIDResource != 0)
    {
        LoadBitmap (nIDResource);
    }
    // Use the passed bitmap
    else if (pBitmap != 0)
    {
        // NOTE: The user is responsible for handling the bitmap
        SetBitmap (pBitmap);
    }
    // else: No bitmap has been created yet
}

CBitmapDialog::CBitmapDialog (LPCTSTR lpszTemplateName, CWnd* pParentWnd,
                              LPCTSTR lpszResourceName, UINT nIDResource,
                              LPCTSTR lpszFilename, CBitmap *pBitmap)
    : CDialog (lpszTemplateName, pParentWnd)
{
    Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
}

CBitmapDialog::CBitmapDialog (UINT nIDTemplate, CWnd* pParentWnd,
                              LPCTSTR lpszResourceName, UINT nIDResource,
                              LPCTSTR lpszFilename, CBitmap *pBitmap)
    : CDialog (nIDTemplate, pParentWnd)
{
    Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
}

CBitmapDialog::CBitmapDialog (LPCTSTR lpszResourceName, UINT nIDResource,
                              LPCTSTR lpszFilename, CBitmap *pBitmap)
    : CDialog ()
{
    Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
}

//----------------------------------------------------------------
// CBitmapDialog :: LoadBitmap - load a bitmap from a resource or file
//
// Parameters:
//  lpszResourceName - the name of the bitmap resource to load.
//    Set this to NULL if you use lpszFilename.
//  lpszFilename - the filename of the bitmap file to load.
//    Set this to NULL if you use lpszResourceName.
//  nIDResource - the ID of the bitmap resource to load

BOOL CBitmapDialog :: LoadBitmap (LPCTSTR lpszResourceName, LPCTSTR lpszFilename)
{
    // Release the bitmap if it was created
    ReleaseBitmap ();

    if (lpszResourceName != NULL)
    {
        // Load the bitmap from a resource
        m_bmBitmap = new CBitmap;
        if (!m_bmBitmap->LoadBitmap (lpszResourceName))
            return FALSE;

        // Automatically delete the object
        m_bBitmapCreated = TRUE;
        m_bBitmapExists = TRUE;

        // Make the window transparent if needed
        MakeWindowRgn ();
    }
    else
    {
        // Load the bitmap from a file
        HBITMAP hbm = (HBITMAP) LoadImage (NULL, lpszFilename, IMAGE_BITMAP, 0, 0,
            LR_LOADFROMFILE|LR_CREATEDIBSECTION);
        if (hbm == NULL) return FALSE;

        // Get the CBitmap object
        CopyBitmapFrom (CBitmap::FromHandle(hbm));
        //m_bmBitmap = CBitmap::FromHandle (hbm);
    }

    return TRUE;
}

BOOL CBitmapDialog :: LoadBitmap (UINT nIDResource)
{
    // Release the bitmap if it was created
    ReleaseBitmap ();
    
    // Load the bitmap
    m_bmBitmap = new CBitmap;
    if (!m_bmBitmap->LoadBitmap (nIDResource))
        return FALSE;

    // Automatically delete the object
    m_bBitmapCreated = TRUE;
    m_bBitmapExists = TRUE;

    // Make the window transparent if needed
    MakeWindowRgn ();

    return TRUE;
}

//----------------------------------------------------------------
// CBitmapDialog :: CopyBitmapFrom - sets the bitmap to a copy
//  of a CBitmap.
//
// Parameters:
//  pBitmap - a pointer to the bitmap to make a copy of and use.

BOOL CBitmapDialog :: CopyBitmapFrom (CBitmap *pBitmap)
{
    // Release the bitmap if it was created
    ReleaseBitmap ();

    // Get the bitmap information
    BITMAP bmSrc;
    pBitmap->GetBitmap (&bmSrc);

    // Get a DC to the source bitmap
    CDC dcSrc;
    dcSrc.CreateCompatibleDC (NULL);
    CBitmap *bmSrcOld = dcSrc.SelectObject (pBitmap);

    // Create a new bitmap
    m_bmBitmap = new CBitmap;
    if (!m_bmBitmap->CreateCompatibleBitmap (&dcSrc, bmSrc.bmWidth, bmSrc.bmHeight))
        return FALSE;

    // Get a DC to the destination bitmap
    CDC dcDst;
    dcDst.CreateCompatibleDC (NULL);
    CBitmap *bmDstOld = dcDst.SelectObject (m_bmBitmap);

    // Copy the bitmap
    dcDst.BitBlt (0, 0, bmSrc.bmWidth, bmSrc.bmHeight, &dcSrc, 0, 0, SRCCOPY);

    // Release
    dcSrc.SelectObject (bmSrcOld);
    dcDst.SelectObject (bmDstOld);
    dcSrc.DeleteDC ();
    dcDst.DeleteDC ();

    // Automatically delete the object
    m_bBitmapCreated = TRUE;
    m_bBitmapExists = TRUE;

    // Make the window transparent if needed
    MakeWindowRgn ();

    return TRUE;
}

//----------------------------------------------------------------
// CBitmapDialog :: SetBitmap - sets the bitmap
//
// Parameters:
//  pBitmap - a pointer to the bitmap to use.
//
// NOTE: This function does not copy the bitmap.  You are responsible
//  for handling the bitmap.  Use CopyBitmapFrom() to copy a bitmap.

void CBitmapDialog :: SetBitmap (CBitmap *pBitmap)
{
    // Release the bitmap if it was created
    ReleaseBitmap ();

    // Set the bitmap
    m_bmBitmap = pBitmap;

    // The bitmap exists, but was not created
    m_bBitmapExists = TRUE;

    // Make the window transparent if needed
    MakeWindowRgn ();
}

//----------------------------------------------------------------
// CBitmapDialog :: ReleaseBitmap - releases a bitmap if it was
//  created using LoadBitmap or CopyBitmapFrom.

void CBitmapDialog :: ReleaseBitmap ()
{
    // Make sure that the bitmap was created using LoadBitmap or CopyBitmapFrom
    if (m_bBitmapCreated)
    {
        // Delete the bitmap
        m_bmBitmap->DeleteObject ();
        delete m_bmBitmap;

        // The bitmap has not been created yet
        m_bBitmapCreated = FALSE;
    }

    m_bBitmapExists = FALSE;
}

//----------------------------------------------------------------
// CBitmapDialog :: SetTransparent - sets the dialog's transparent
//  state.

void CBitmapDialog :: SetTransparent (BOOL bTransparent)
{
    m_bTransparent = bTransparent;
    MakeWindowRgn ();
}

void CBitmapDialog :: SetTransColor (COLORREF col)
{
    m_colTrans = col;
    MakeWindowRgn ();
}

//----------------------------------------------------------------
// CBitmapDialog :: MakeWindowRgn - makes a window region from
//  the bitmap and uses it if on transparent mode.

void CBitmapDialog :: MakeWindowRgn ()
{
    if (!m_bTransparent)
    {
        // Set the window region to the full window
        CRect rc;
        GetWindowRect (rc);
        CRgn rgn;
        rgn.CreateRectRgn (0, 0, rc.Width(), rc.Height());
        SetWindowRgn (rgn, TRUE);
    }
    else
    {
        // Set the region to the window rect minus the client rect
        CRect rcWnd;
        GetWindowRect (rcWnd);

        CRgn rgn;
        rgn.CreateRectRgn (rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom);

        CRect rcClient;
        GetClientRect (rcClient);
        ClientToScreen (rcClient);

        CRgn rgnClient;
        rgnClient.CreateRectRgn (rcClient.left, rcClient.top, rcClient.right,
            rcClient.bottom);

        // Subtract rgnClient from rgn
        rgn.CombineRgn (&rgn, &rgnClient, RGN_XOR);

        // Get a DC for the bitmap
        CDC dcImage;
        dcImage.CreateCompatibleDC (NULL);
        CBitmap *pOldBitmap = dcImage.SelectObject (m_bmBitmap);

        // Get the bitmap for width and height information
        BITMAP bm;
        m_bmBitmap->GetBitmap (&bm);

        // Get window width and height
        CRect rc;
        GetClientRect (rc);

        // Use the minimum width and height
        int width = min (bm.bmWidth, rc.Width());
        int height = min (bm.bmHeight, rc.Height());

        // Use RLE (run-length) style because it goes faster.
        // Row start is where the first opaque pixel is found.  Once
        // a transparent pixel is found, a line region is created.
        // Then row_start becomes the next opaque pixel.
        int row_start;

        // Go through all rows
        for (int y=0; y<height; y++)
        {
            // Start looking at the beginning
            row_start = 0;

            // Go through all columns
            int x=0;
            for (; x<width; x++)
            {
                // If this pixel is transparent
                if (dcImage.GetPixel(x, y) == m_colTrans)
                {
                    // If we haven't found an opaque pixel yet, keep searching
                    if (row_start == x) row_start ++;
                    else
                    {
                        // We have found the start (row_start) and end (x) of
                        // an opaque line.  Add it to the region.
                        CRgn rgnAdd;
                        rgnAdd.CreateRectRgn (rcClient.left+row_start,
                            rcClient.top+y, rcClient.left+x, rcClient.top+y+1);
                        rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
                        row_start = x+1;
                    }
                }
            }

            // If the last pixel is still opaque, make a region.
            if (row_start != x)
            {
                CRgn rgnAdd;
                rgnAdd.CreateRectRgn (rcClient.left+row_start, rcClient.top+y,
                    rcClient.left+x, rcClient.top+y+1);
                rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
            }
        }
        
        SetWindowRgn (rgn, TRUE);
    }
}

BEGIN_MESSAGE_MAP(CBitmapDialog, CDialog)
    //{{AFX_MSG_MAP(CBitmapDialog)
    ON_WM_ERASEBKGND()
    ON_WM_LBUTTONDOWN()
    ON_WM_CTLCOLOR()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CBitmapDialog message handlers

//----------------------------------------------------------------
// CBitmapDialog :: OnEraseBkgnd - normally erases the background.
//  We override this function to replace it with window drawing
//  code.

BOOL CBitmapDialog :: OnEraseBkgnd (CDC *pDC)
{
    // If no bitmap is loaded, behave like a normal dialog box
    if (!m_bBitmapExists)
        return CDialog :: OnEraseBkgnd (pDC);

    // Get the client rectangle of the window
    CRect rc;
    GetClientRect (rc);

    // Get a DC for the bitmap
    CDC dcImage;
    dcImage.CreateCompatibleDC (pDC);
    CBitmap *pOldBitmap = dcImage.SelectObject (m_bmBitmap);

    // Get bitmap width and height
    BITMAP bm;
    m_bmBitmap->GetBitmap (&bm);

    // Use the minimum width and height
    int width = min (bm.bmWidth, rc.Width());
    int height = min (bm.bmHeight, rc.Height());

    // Draw the bitmap as the window background
    pDC->BitBlt (0, 0, rc.Width(), rc.Height(), &dcImage, 0, 0, SRCCOPY);

    // Release
    dcImage.SelectObject (pOldBitmap);
    dcImage.DeleteDC ();

    // Return value: Nonzero if it erases the background.
    return TRUE;
}

//----------------------------------------------------------------
// CBitmapDialog :: OnLButtonDown - left mouse button is clicked
//  on the window

void CBitmapDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    
    CDialog::OnLButtonDown(nFlags, point);

    // Fool windows into thinking that we clicked on the caption
    if (m_bClickAnywhereMove)
        PostMessage (WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));
}

//----------------------------------------------------------------
// CBitmapDialog :: OnCtlColor - set the colors for controls

HBRUSH CBitmapDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    // TODO: Change any attributes of the DC here

    // Make static controls transparent
    if (m_bStaticTransparent && nCtlColor == CTLCOLOR_STATIC)
    {
        // Make sure that it's not a slider control
        char lpszClassName[256];
        GetClassName (pWnd->m_hWnd, lpszClassName, 255);
        if (strcmp (lpszClassName, TRACKBAR_CLASS) == 0)
            return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

        pDC->SetBkMode (TRANSPARENT);
        return m_brushHollow;
    }
    
    // TODO: Return a different brush if the default is not desired
    return hbr;
}

调用处:

BOOL Ctest12292Dlg::OnInitDialog()

{

...

    LoadBitmap(IDB_BITMAP7);
    SetTransparent (TRUE);
    SetTransColor (RGB(0,0,0));
    SetStaticTransparent (TRUE);
    SetClickAnywhereMove (TRUE);

...

}

 

PS:

ftp://hurcna:hurcna@a.hur.cn/down1/VC/free/%B2%BB%B9%E6%D4%F2%B6%D4%BB%B0%BF%F2%B5%C4%D3%D6%D2%BB%CA%B5%CF%D6.rar

ps2:如果是主对话框要打开不规则子对话框,则

GetWindowRect (rcWnd);可能导致rcWnd不是一(0,0)为左上角,改成GetClientRect (rcWnd);

ClientToScreen (rcClient);也会导致rcClient有问题,屏蔽就好了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值