• 로그인 함 해보끄나?

  • Sarangnamu.net June 17, 2003
    Home Login Profile Study Open Project Q&A Google Code
    CButtonEx
    Last Modify : 27 December, 2010(01:58)
    * GDI+ 를 지원하므로 JPEG, BMP, PNG 안가리고 모두 읽어 들일 수 있다.
    * 우선은 XML로 수동적으로 읽어들이고 있으나 추후에는 링크드 리스트를 이용해서 주욱 긁어 오게 하면 되고...
    * 이미지 9개로 거의 모든 버튼에 크기를 커버 가능하다. (세로로 늘일 경우는 다소 깨지긴 하지만. -_ - 한마디로 귀차나서 만든 클래스이다.)
    
    // ButtonEx.cpp : implementation file
    //
    
    // DATE		: February 13, 2007
    // CODER	: Kurome (aucd29@gmail.com)
    // VERSION	: 1.0
    //
    //
    
    // Require
    // ----------------------------------------------------------
    // GDI+
    // installation Guide : http://sarangnamu.net/basic/basic_view.php?no=1369
    // Manual(kor) : http://winapi.co.kr/project/library/gdiplus/gdiplus.htm
    //
    // CParserXML
    // Link : http://www.sarangnamu.net/basic/basic_view.php?no=2825
    //
    // CRectEx
    // Link : http://www.sarangnamu.net/basic/basic_view.php?no=2828
    //
    
    // ----------------------------------------------------------
    // NOTE : February 13, 2007
    // ----------------------------------------------------------
    // * 디자인 회의 하다가 버튼 클래스가지고 -_ - 디자이너가
    //   스크립트를 논하며 머라 하길래 -_- 버튼 클래스 만든다. 
    //   성격있는 최씨 -_ -ㅎ삐뚤어져 주겠어
    //
    // ----------------------------------------------------------
    // NOTE : February 21, 2007
    // ----------------------------------------------------------
    // * GDI+ 의 단점인 느린 로딩 -_ - 을 해결하기 위해서
    //   CButtonLoadImage를 생성.. 조금 나아지긴 했다. 아직 느린
    //   게 보이긴 하는데 -_ -;;;;;
    // 
    // * 머랄까 음... 로딩된 이미지를 Distructor에서 Free를 해
    //   주려고 했는데 오류가 난다. 왜 그런 것일까??? 우선은 주
    //   석질을 했다.
    //
    // * 한 개의 이미지를 적용했을 경우 버튼이 이미지 크기로 변경
    //   한다. (어차피 해당 사이즈를 이용하기 위해서 니깐)
    //
    
    
    #include "stdafx.h"
    #include "GDIPLUS_TEST.h"
    #include "ButtonEx.h"
    #include "ParserXML.h"
    
    // CButtonEx
    
    IMPLEMENT_DYNAMIC(CButtonEx, CButton)
    
    CButtonEx::CButtonEx()
    : m_szFont(L"Tahoma")
    , m_nFontSize(11)
    , m_bLoadImage(false)
    , m_pLoadImage(NULL)
    , m_nPressMove(0)
    , m_bMouseOver(false)
    , m_nLeftMargin(0)
    , m_nFontStyle(FontStyleRegular)
    , m_bFullImage(false)
    {
    	// 가운데/중간 정렬
    	gdiStringFormat.SetAlignment(StringAlignmentCenter);
    	gdiStringFormat.SetLineAlignment(StringAlignmentCenter);
    
    	// 폰트 색
    	m_crFontColor = Color(0, 0, 0);	// 검정
    
    	// 변수 초기화
    	memset(m_nOneImage, 0, sizeof(m_nOneImage));
    	memset(m_resize_rect, 0, sizeof(m_resize_rect));
    }
    
    CButtonEx::~CButtonEx()
    {
    	if (m_pLoadImage)
    	{
    		// 이미지를 추가했을 때만 지우자.
    		if (m_nLeftMargin)
    		{
    			delete m_imgBtnIcon;
    		}
    
    		// 브러시/폰트 등등
    		delete m_brFontColor;
    		delete m_memBitmap;
    		delete m_mDC;
    		delete m_Font;
    		delete m_Position;
    	}
    }
    
    
    BEGIN_MESSAGE_MAP(CButtonEx, CButton)
    	ON_WM_PAINT()
    	ON_WM_ERASEBKGND()
    	ON_WM_LBUTTONDOWN()
    	ON_WM_LBUTTONUP()
    	ON_WM_LBUTTONDBLCLK()
    	ON_WM_MOUSEMOVE()
    END_MESSAGE_MAP()
    
    // CButtonEx message handlers
    
    
    void CButtonEx::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    
    	if (m_pLoadImage)
    	{
    		InitObject();
    
    		Graphics objG(dc);
    		objG.DrawImage(m_memBitmap, 0, 0);	
    	}
    	else
    	{
    		// 이미지 객체에 링크가 없을 경우는 고냥
    		// 버튼 위치만 보여주자.
    		Graphics objG(dc);
    		Pen penBlack(Color(0, 0, 0));
    		Font fontBlack(m_szFont, m_nFontSize, m_nFontStyle, UnitPixel);
    		SolidBrush brushBlack(Color(0, 0, 0));
    
    		GetClientRect(&rect);
    		GetWindowText(m_szWindowText);
    		objG.DrawRectangle(&penBlack, 0, 0, rect.Width()-1, rect.Height()-1);
    		PointF ptfPos(static_cast<REAL>(static_cast<float>(rect.Width()-1) / 2.0f),
    			static_cast<REAL>(static_cast<float>(rect.Height()-1) / 2.0f));
    		objG.DrawString(m_szWindowText, -1, &fontBlack, ptfPos, &gdiStringFormat, &brushBlack);
    	}
    }
    
    BOOL CButtonEx::OnEraseBkgnd(CDC* pDC)
    {
    	return true;
    }
    
    void CButtonEx::SetFontStyle(CString szFont, REAL nFontSize, int nFontStyle)
    {
    	//FontStyleRegular    = 0,
    	//FontStyleBold       = 1,
    	//FontStyleItalic     = 2,
    	//FontStyleBoldItalic = 3,
    	//FontStyleUnderline  = 4,
    	//FontStyleStrikeout  = 8
    
    	m_szFont	 = szFont;
    	m_nFontSize  = nFontSize;
    	m_nFontStyle = nFontStyle;
    }
    
    void CButtonEx::InitObject(void)
    {
    	// 이미지를 불러 들이고
    	if (!m_bLoadImage)
    	{
    		if (m_pLoadImage->m_szOneImage.GetLength() && m_resize_rect.Width())
    		{
    			// 통이미지 일경우 버튼의 크기를 이미지 사이즈로 맞춘다.
    			m_nOneImage[0] = static_cast<int>(m_pLoadImage->m_imgFull[0]->GetWidth());
    			m_nOneImage[1] = static_cast<int>(m_pLoadImage->m_imgFull[0]->GetHeight());
    
    			MoveWindow(m_resize_rect.left, m_resize_rect.top, m_nOneImage[0], m_nOneImage[1]);
    			//rect.SetRect(0, 0, m_nOneImage[0], m_nOneImage[1]);
    			GetClientRect(&rect);
    		}
    		else
    		{
    			GetClientRect(&rect);
    		}
    		
    		try
    		{
    			// 브러시
    			m_brFontColor = new SolidBrush(m_crFontColor);
    
    			//
    			m_memBitmap = new Bitmap(rect.Width(), rect.Height());
    			m_mDC		= new Graphics(m_memBitmap);
    			m_Font		= new Font(m_szFont, m_nFontSize, m_nFontStyle, UnitPixel);
    			m_Position	= new PointF(static_cast<REAL>(static_cast<float>(rect.Width()) / 2.0f),
    									 static_cast<REAL>(static_cast<float>(rect.Height()) / 2.0f));
    
    			if (m_nLeftMargin)
    			{
    				gdiStringFormat.SetAlignment(StringAlignmentNear);
    				(*m_Position).X = static_cast<REAL>(m_imgBtnIcon->GetWidth() + m_nLeftMargin + 20);
    			}
    		}
    		catch (CMemoryException* e)
    		{
    			e->ReportError();
    			e->Delete();
    		}
    
    		// 윈도우 텍스트 가져오기
    		GetWindowText(m_szWindowText);
    
    		// 버튼 그리기
    		DrawButton(NORMAL_BUTTON);
    
    		m_bLoadImage = true;
    	}
    }
    
    void CButtonEx::CenterDraw(Image* pImg, int* pnLeftWidth, int* pnRightPos)
    {
    	int i;
    
    	for (i=*pnLeftWidth; i<*pnRightPos; ++i)
    	{
    		m_mDC->DrawImage(pImg, i, 0, 1, rect.Height());	
    	}
    }
    
    void CButtonEx::DrawButton(int nType)
    {
    	if (!m_pLoadImage->m_szOneImage.GetLength())
    	{
    		int nRightPos, nLeftWidth, nRightWidth;
    
    		nRightPos   = rect.Width() - static_cast<int>(m_pLoadImage->m_imgNormal[_RIGHT]->GetWidth());
    		nLeftWidth  = m_pLoadImage->m_imgNormal[_LEFT]->GetWidth();
    		nRightWidth = m_pLoadImage->m_imgNormal[_RIGHT]->GetWidth();
    
    		switch(nType)
    		{
    		case NORMAL_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgNormal[_LEFT], 0, 0, nLeftWidth, rect.Height());
    			m_mDC->DrawImage(m_pLoadImage->m_imgNormal[_RIGHT], nRightPos, 0, nRightWidth, rect.Height());
    			CenterDraw(m_pLoadImage->m_imgNormal[_CENTER], &nLeftWidth, &nRightPos);
    			break;
    
    		case OVER_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgOver[_LEFT], 0, 0, nLeftWidth, rect.Height());
    			m_mDC->DrawImage(m_pLoadImage->m_imgOver[_RIGHT], nRightPos, 0, nRightWidth, rect.Height());
    			CenterDraw(m_pLoadImage->m_imgOver[_CENTER], &nLeftWidth, &nRightPos);
    			break;
    
    		case ACTIVE_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgActive[_LEFT], 0, 0, nLeftWidth, rect.Height());
    			m_mDC->DrawImage(m_pLoadImage->m_imgActive[_RIGHT], nRightPos, 0, nRightWidth, rect.Height());
    			CenterDraw(m_pLoadImage->m_imgActive[_CENTER], &nLeftWidth, &nRightPos);
    			break;
    
    		default:
    			break;
    		}
    	}
    	else
    	{
    		switch(nType)
    		{
    		case NORMAL_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgFull[0], 0, 0, rect.Width(), rect.Height());
    			break;
    
    		case OVER_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgFull[1], 0, 0, rect.Width(), rect.Height());
    			break;
    
    		case ACTIVE_BUTTON:
    			m_mDC->DrawImage(m_pLoadImage->m_imgFull[2], 0, 0, rect.Width(), rect.Height());
    			break;
    
    		default:
    			break;
    		}
    	}
    	
    	// 중간에 아이콘 넣을 경우
    	if (m_nLeftMargin)
    	{
    		int nIconPos;
    		nIconPos = static_cast<int>((rect.Height() / 2.0) - (m_imgBtnIcon->GetHeight() / 2.0) );
    
    		if (m_nPressMove && nType == ACTIVE_BUTTON)
    		{
    			m_mDC->DrawImage(m_imgBtnIcon, m_nLeftMargin + static_cast<int>(m_nPressMove), nIconPos + static_cast<int>(m_nPressMove));
    		}
    		else
    		{
    			m_mDC->DrawImage(m_imgBtnIcon, m_nLeftMargin, nIconPos);
    		}
    	}
    
    	// 버튼 문구 적어주시고 m_nPressMove 에 값이 존재하면
    	// 그 만큼 이동 해주도록 하자.
    	if (m_szWindowText.GetLength())
    	{
    		if (m_nPressMove && nType == ACTIVE_BUTTON)
    		{
    			PointF MovePosition((*m_Position).X + m_nPressMove, (*m_Position).Y + m_nPressMove);
    			m_mDC->DrawString(m_szWindowText, -1, m_Font, MovePosition, &gdiStringFormat, m_brFontColor);
    		}
    		else
    		{
    			m_mDC->DrawString(m_szWindowText, -1, m_Font, *m_Position, &gdiStringFormat, m_brFontColor);
    		}
    	}
    }
    
    void CButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	if (m_pLoadImage)
    	{
    		m_bMouseOver = true;
    		DrawButton(ACTIVE_BUTTON);	
    		Invalidate();
    	}
    	
    	CButton::OnLButtonDown(nFlags, point);
    }
    
    void CButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
    {
    	if (m_pLoadImage)
    	{
    		DrawButton(NORMAL_BUTTON);
    		Invalidate();
    	}
    
    	CButton::OnLButtonUp(nFlags, point);
    
    	if (m_pLoadImage)
    	{
    		ReleaseCapture();
    		m_bMouseOver = false;
    	}
    }
    
    void CButtonEx::SetActiveMoveText(REAL nDistance)
    {
    	m_nPressMove = nDistance;
    }
    
    void CButtonEx::OnLButtonDblClk(UINT nFlags, CPoint point)
    {
    	if (m_pLoadImage)
    	{
    		OnLButtonDown(nFlags, point);
    	}
    
    	CButton::OnLButtonDblClk(nFlags, point);
    }
    
    void CButtonEx::OnMouseMove(UINT nFlags, CPoint point)
    {
    	if (m_pLoadImage)
    	{
    		// 마우스가 버튼 위치를 떠났을 때
    		if (rect.PtInRect(point) == false)
    		{
    			DrawButton(NORMAL_BUTTON);
    			Invalidate();
    
    			if (!m_bMouseOver)
    			{
    				ReleaseCapture();
    			}
    		}
    		else
    		{
    			if (m_bMouseOver)
    			{
    				// 마우스는 클릭한 상태에서 버튼 위치일 경우
    				DrawButton(ACTIVE_BUTTON);
    				Invalidate();
    			}
    			else
    			{
    				// 마우스는 클릭하지 않은 상태 에서의 버튼 위치 일 경우	
    				DrawButton(OVER_BUTTON);
    				Invalidate();
    				SetCapture();
    			}
    		}
    	}
    
    	CButton::OnMouseMove(nFlags, point);
    }
    
    void CButtonEx::ButtonIcon(CString szButtonIcon, int nLeftMargin)
    {
    	try
    	{
    		m_imgBtnIcon  = new Image(szButtonIcon);
    		m_nLeftMargin = nLeftMargin;
    	}
    	catch (CMemoryException* e)
    	{
    		e->ReportError();
    		e->Delete();
    	}
    }
    
    void CButtonEx::SetLoadImage(CButtonLoadImage* img)
    {
    	// CButtonLoadImage 에서 불러들인 이미지를 링크한다.
    	m_pLoadImage = img;
    }
    
    
    void CButtonEx::Resize(CRect rect)
    {
    	m_resize_rect = rect;
    }
    
    DOWNLOAD : gdiplus_test.rar
    Filesize : 0.1Mb

    Comment


    입력하3 1508772269



    Locations of visitors to this page