• 로그인 함 해보끄나?

  • Sarangnamu.net June 17, 2003
    Home Login Profile Study Open Project Q&A Google Code
    CDialogSkin - 다이얼로그 스킨 입히기
    Last Modify : 27 December, 2010(01:54)
    // DialogSkin.cpp : implementation file
    //
    // DATE		: June 27, 2006
    // CODER	: Kurome (aucd29@gmail.com)
    //
    //
    // ----------------------------------------------------------
    // NOTE :August 5, 2006
    // ----------------------------------------------------------
    // * 다이얼로그에 입힐 스킨을 지정해주도록 하자!
    //
    // ----------------------------------------------------------
    // NOTE : August 9, 2006
    // ----------------------------------------------------------
    // * 1차적으로 완성...
    // * g_bWindowVersion <- 전역 변수로 윈도우xp 인지 아닌지 구분
    //   및 테마 사용 유무를 알려주도록 하자.
    
    #include "stdafx.h"
    #include "SMS_WIZARD.h"
    #include "DialogSkin.h"
    
    // CDialogSkin dialog
    
    IMPLEMENT_DYNAMIC(CDialogSkin, CDialog)
    
    CDialogSkin::CDialogSkin(CWnd* pParent /*=NULL*/)
    {
    
    }
    
    CDialogSkin::CDialogSkin(UINT uResourceID, CWnd* pParent)
    : CDialog(uResourceID, pParent)
    , m_bWindowPos(false)
    , m_szWindowText(_T(""))
    , m_x(0)
    , m_y(0)
    , m_bBtnActive(false)
    , m_bActive(true)
    , m_bBtnClose(false)
    , nBorderHeight(0)
    , nBorderGap(0)
    , nBorderLeftGap(0)
    , skinCen(0)
    {
    
    }
    
    CDialogSkin::~CDialogSkin()
    {
    }
    
    void CDialogSkin::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CDialogSkin, CDialog)
    	ON_WM_PAINT()
    	ON_WM_ACTIVATE()
    	ON_WM_NCMOUSEMOVE()
    	ON_WM_NCLBUTTONDOWN()
    	ON_WM_ERASEBKGND()
    	ON_WM_NCPAINT()
    	ON_WM_NCACTIVATE()
    END_MESSAGE_MAP()
    
    // CDialogSkin message handlers
    void CDialogSkin::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    
    	CDC* pDC = GetWindowDC();
    	
    	if (!m_bWindowPos)
    	{
    		GetWindowRect(&m_rect);
    		SetLoadImage();
    	}
    
    	CDC bitmapDC;
    	bitmapDC.CreateCompatibleDC(pDC);
    
    	CMemDC mDC(pDC, &m_rtTop);
    	CMemDC mLeftDC(pDC, &m_rtLeft);
    	CMemDC mRightDC(pDC, &m_rtRight);
    	CMemDC mBottomDC(pDC, &m_rtBottom);
    
    	m_pmDC = &mDC;
    
    	// Active
    	if (m_bActive)
    	{
    		// 상단.. 타이틀
    		bitmapDC.SelectObject(&frmLeft);
    		mDC.BitBlt(0, m_rtTop.top, bmLeft.bmWidth, bmLeft.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmCen);
    		mDC.StretchBlt(bmLeft.bmWidth, m_rtTop.top, skinCen, bmRight.bmHeight, &bitmapDC,
    			0, 0, bmCen.bmWidth, bmCen.bmHeight, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmRight);
    		mDC.BitBlt(skinCen + bmLeft.bmWidth, m_rtTop.top, bmRight.bmWidth, bmRight.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    
    		// 왼쪽 볼더
    		bitmapDC.SelectObject(&frmLeftBorder);
    		mLeftDC.StretchBlt(0, 0, 3, m_rtLeft.bottom, &bitmapDC, 0, 0, 3, 1, SRCCOPY);
    
    		// 오른쪽 볼더
    		mRightDC.StretchBlt(m_rtTop.right - 3, bmCen.bmHeight-1, 3, m_rtRight.bottom,
    			&bitmapDC, 0, 0, 3, 1, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmBottomLeft);
    		mBottomDC.BitBlt(0, nBorderHeight, 3, 3, &bitmapDC, 0, 0, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmBottomCen);
    		mBottomDC.StretchBlt(3, nBorderHeight, m_rtTop.right-6, 3, &bitmapDC, 0, 0, 1, 3, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmBottomRight);
    		mBottomDC.BitBlt(nBorderLeftGap, nBorderHeight, 3, 3, &bitmapDC, 0, 0, SRCCOPY);
    	}
    	else
    	{
    		// 상단.. 타이틀
    		bitmapDC.SelectObject(&frmGrayLeft);
    		mDC.BitBlt(0, m_rtTop.top, bmLeft.bmWidth, bmLeft.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmGrayCen);
    		mDC.StretchBlt(bmLeft.bmWidth, m_rtTop.top, skinCen, bmRight.bmHeight, &bitmapDC,
    			0, 0, bmCen.bmWidth, bmCen.bmHeight, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmGrayRight);
    		mDC.BitBlt(skinCen + bmLeft.bmWidth, m_rtTop.top, bmRight.bmWidth, bmRight.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    
    		// 왼쪽 볼더
    		bitmapDC.SelectObject(&frmGrayLeftVertical);
    		mLeftDC.StretchBlt(0, 0, 3, m_rtLeft.bottom, &bitmapDC, 0, 0, 3, 1, SRCCOPY);
    
    		// 오른쪽 볼더
    		mRightDC.StretchBlt(m_rtTop.right - 3, bmCen.bmHeight-1, 3, m_rtRight.bottom,
    			&bitmapDC, 0, 0, 3, 1, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmGrayBottomLeft);
    		mBottomDC.BitBlt(0, nBorderHeight, 3, 3, &bitmapDC, 0, 0, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmGrayBottomLeft);
    		mBottomDC.StretchBlt(3, nBorderHeight, m_rtTop.right-6, 3, &bitmapDC, 0, 0, 1, 3, SRCCOPY);
    
    		bitmapDC.SelectObject(&frmGrayBottomLeft);
    		mBottomDC.BitBlt(nBorderLeftGap, nBorderHeight, 3, 3, &bitmapDC, 0, 0, SRCCOPY);
    	}
    
    	CFont font;
    	LOGFONT lf;
    	memset(&lf, 0, sizeof(LOGFONT));
    	int nPlusPos = 0;
    
    	if (g_bWindowVersion == 1)
    	{
    		lf.lfHeight  = 16;
    		nPlusPos	+= 3;
    	}
    	else
    	{
    		lf.lfHeight = 13;
    	}
    
    	lf.lfWeight = FW_BOLD;
    	wsprintf(lf.lfFaceName, L"Tahoma");
    	font.CreateFontIndirect(&lf);
    	CFont* def_font = mDC.SelectObject(&font);
    	mDC.SetBkMode(TRANSPARENT);
    	mDC.SetTextColor(RGB(0, 0, 0));
    	mDC.TextOut(15, 5 + nPlusPos, m_szWindowText);	// 검정
    	mDC.SetTextColor(RGB(255, 255, 255));
    	mDC.TextOut(14, 4 + nPlusPos, m_szWindowText);	// 흰색
    	mDC.SelectObject(def_font);
    	font.DeleteObject();
    
    	DrawCloseButton(true);
    }
    
    BOOL CDialogSkin::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// 닫기 버튼을 비 활성화 시킨다.
    	CMenu* pMenu = this->GetSystemMenu(FALSE);
    	pMenu->ModifyMenu(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
    	pMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
    
    	// 나날히 늘어가는 잔머리..
    	// 안깜박이게 하려고... 윈도우 타이틀을 메모리에 넣었다가
    	// 현재 뿌리고 있는 건 지우고 Paint에서 다시 적게 했다.
    	GetWindowText(m_szWindowText);
    	SetWindowText(L"");
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    	// EXCEPTION: OCX Property Pages should return FALSE
    }
    
    void CDialogSkin::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
    {
    	CDialog::OnActivate(nState, pWndOther, bMinimized);
    
    	switch( nState )
    	{
    	case WA_INACTIVE:
    		m_bActive = false;
    		OnPaint();
    		break;
    	case WA_ACTIVE:
    	case WA_CLICKACTIVE:
    		m_bActive = true;
    		OnPaint();
    		break;
    	}
    }
    
    void CDialogSkin::SetLoadImage(void)
    {
    	// 타이틀 바 위치 설정
    	m_rtTop		 = m_rect;
    	int nPlusPos = 0;
    
    	// 타이틀 바 이미지 로드
    	// XP 테마 때문에 이면 이렇게.
    	if (g_bWindowVersion)
    	{
    		frmLeft.LoadBitmap(IDB_FRM_TOP_LEFT);
    		frmCen.LoadBitmap(IDB_FRM_TOP_CEN);
    		frmRight.LoadBitmap(IDB_FRM_TOP_RIGHT);
    
    		frmGrayLeft.LoadBitmap(IDB_FRM_GRAY_TOP_LEFT);
    		frmGrayCen.LoadBitmap(IDB_FRM_GRAY_TOP_CEN);
    		frmGrayRight.LoadBitmap(IDB_FRM_GRAY_TOP_RIGHT);
    		
    		nPlusPos += 3;
    	}
    	else
    	{
    		frmLeft.LoadBitmap(IDB_OLDFRM_LEFT);
    		frmCen.LoadBitmap(IDB_OLDFRM_CEN);
    		frmRight.LoadBitmap(IDB_OLDFRM_RIGHT);
    
    		frmGrayLeft.LoadBitmap(IDB_FRM_GRAY_OLDTOP_LEFT);
    		frmGrayCen.LoadBitmap(IDB_FRM_GRAY_OLDTOP_CEN);
    		frmGrayRight.LoadBitmap(IDB_FRM_GRAY_OLDTOP_RIGHT);
    	}
    
    	frmLeftBorder.LoadBitmap(IDB_FRM_RIGHT_BORDER);
    	frmRightBorder.LoadBitmap(IDB_FRM_RIGHT_BORDER);
    	frmGrayLeftVertical.LoadBitmap(IDB_FRM_GRAY_VERTICAL);
    
    	frmBottomLeft.LoadBitmap(IDB_FRM_BOTTOM_LEFT);
    	frmBottomCen.LoadBitmap(IDB_FRM_BOTTOM_RIGHT);
    	frmBottomRight.LoadBitmap(IDB_FRM_BOTTOM_RIGHT);
    
    	frmLeft.GetObject(sizeof(BITMAP), &bmLeft);
    	frmCen.GetObject(sizeof(BITMAP), &bmCen);
    	frmRight.GetObject(sizeof(BITMAP), &bmRight);
    
    	frmGrayBottomLeft.LoadBitmap(IDB_FRM_GRAY_BOTTOM_LEFT);
    	frmGrayBottomCen.LoadBitmap(IDB_FRM_GRAY_BOTTOM_CEN);
    	frmGrayBottomRight.LoadBitmap(IDB_FRM_GRAY_BOTTOM_RIGHT);
    
    	m_rtTop.top		 = 0;
    	m_rtTop.left	 = 0;
    	m_rtTop.bottom	 = bmLeft.bmHeight+m_rtTop.top;
    	m_rtTop.right	-= m_rect.left;
    
    	m_bWindowPos	 = true;
    
    	// 버튼들
    	m_btnClose.LoadBitmap(IDB_FRM_BTN_CLOSE);
    	m_btnCloseActive.LoadBitmap(IDB_FRM_BTN_CLOSE_ACTIVE);
    	m_btnCloseOver.LoadBitmap(IDB_FRM_BTN_CLOSE_OVER);
    	m_btnCloseDisable.LoadBitmap(IDB_FRM_BTN_CLOSE_DISABLE);
    
    	m_btnClose.GetObject(sizeof(BITMAP), &bmClose);
    
    	m_y = GetSystemMetrics(SM_CYFRAME) + nPlusPos;
    	m_x = (m_rect.right - m_rect.left) - m_y;
    
    	int x = m_x;
    
    	// 영역을 벗어났는지 아닌지 확인해주기 위한 영역 설정
    	m_hRgnClose		= CreateRectRgn(x, m_y, x + bmClose.bmWidth, m_y + bmClose.bmHeight);
    
    	nBorderHeight	= m_rect.bottom - m_rect.top - 4;
    	nBorderGap		= bmCen.bmHeight - 1;
    	nBorderLeftGap  = m_rtTop.right - 3;
    	skinCen			= m_rtTop.right - bmLeft.bmWidth - bmRight.bmWidth;
    
    	m_rtLeft.SetRect(0, nBorderGap, 3, nBorderHeight);
    	m_rtRight.SetRect(nBorderLeftGap, nBorderGap, m_rtTop.right, nBorderHeight);
    	m_rtBottom.SetRect(0, nBorderHeight, m_rtTop.right, nBorderHeight + 3);	
    }
    
    
    void CDialogSkin::DrawCloseButton(bool bDCType=false)
    {
    	CDC* pDC = GetWindowDC();
    	CDC bitmapDC;
    	bitmapDC.CreateCompatibleDC(pDC);
    	int x = m_x - bmClose.bmWidth;
    
    	if(!m_bActive)
    	{
    		bitmapDC.SelectObject(&m_btnCloseDisable);
    	}
    	else if (m_bBtnActive)
    	{
    		// 선택 시
    		bitmapDC.SelectObject(&m_btnCloseActive);
    		m_bBtnActive = false;
    		pDC->BitBlt(x, m_y, bmClose.bmWidth, bmClose.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    		return;
    	}
    	else if (m_nNcButtonOver == 3)
    	{
    		// 오버 시
    		bitmapDC.SelectObject(&m_btnCloseOver);
    		pDC->BitBlt(x, m_y, bmClose.bmWidth, bmClose.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    		return;
    	}
    	else
    	{
    		// 일반
    		bitmapDC.SelectObject(&m_btnClose);
    	}
    
    	m_pmDC->BitBlt(x, m_y, bmClose.bmWidth, bmClose.bmHeight, &bitmapDC, 0, 0, SRCCOPY);
    }
    
    void CDialogSkin::OnNcMouseMove(UINT nHitTest, CPoint point)
    {
    	//TRACE(L"NcMouseMove\n");
    	// 해당 영역에 올라가면
    	// None  : 0
    	// Min   : 1
    	// Close : 3
    	//
    	// m_nNcButtonOver
    	// Frame window 상에서는 none, min, max, close가 필요하지만
    	// 이건 차일드 윈도우라.. 필요가 없어서 지

    Comment


    입력하3 1498429658



    Locations of visitors to this page