• 로그인 함 해보끄나?

  • Sarangnamu.net June 17, 2003
    Home Login Profile Study Open Project Q&A Google Code
    CImageLoader
    Last Modify : 27 December, 2010(12:32)
    <?xml version="1.0"?>
    <image>
    	<normal>
    		<left>normal_left.bmp</left>
    		<center>normal_cen.bmp</center>
    		<right>normal_right.bmp</right>
    	</normal>
    	<over>
    		<left>over_left.bmp</left>
    		<center>over_cen.bmp</center>
    		<right>over_right.bmp</right>
    	</over>
    	<active>
    		<left>active_left.bmp</left>
    		<center>active_cen.bmp</center>
    		<right>active_right.bmp</right>
    	</active>
    	<btnOneImage>
    		<normal>btn_save_blue.bmp</normal>
    		<over>btn_save_cyan.bmp</over>
    		<active>btn_save_magenta.bmp</active>
    	</btnOneImage>
    	<blockImage>btn_save_blue.bmp</blockImage>
    	<buttonIcon>btnIcon.bmp</buttonIcon>	
    </image>
    
    CImageLoader g_img;
    g_img.LoadXML(L"./Images", L"ImagesInfo.xml");
    
    CPaintDC dc(this);
    
    CDC mDC;
    mDC.CreateCompatibleDC(&dc);
    mDC.SelectObject(g_img.FindBitmap(L"buttonIcon"));
    dc.BitBlt(0, 0, 300, 300, &mDC, 0, 0, SRCCOPY);
    
    CBitmap* p = g_img.FindBitmap(L"normal");
    mDC.SelectObject(p++);
    dc.BitBlt(80, 0, 300, 300, &mDC, 0, 0, SRCCOPY);
    
    mDC.SelectObject(p++);
    dc.BitBlt(90, 0, 300, 300, &mDC, 0, 0, SRCCOPY);
    
    mDC.SelectObject(p);
    dc.BitBlt(100, 0, 300, 300, &mDC, 0, 0, SRCCOPY);
    
    // DATE		: February 22, 2007
    // CODER	: Kurome (ccd@apsat.co.kr)
    //
    //
    //
    
    // Require
    // --------------------------------------------------------
    // CParserXML
    // http://www.sarangnamu.net/basic/basic_view.php?no=2825
    //
    
    // NOTE	: February 22, 2007
    // --------------------------------------------------------
    // * 이미지를 손쉽게 로딩할 수 있게 하자.
    //   기존에 RESOURCE 부분에 넣고 수정하고 그러는거 너무
    //   불편하니깐...
    //
    // * GDI, GDI+ 모두 지원
    //
    // BUGFIX : February 27, 2007
    // --------------------------------------------------------
    // * LENGTH 값 안넣은거 수정
    // * GDI+ 에 메모리 해제 관련 수정
    // 
    // BUGFIX : March 5, 2007
    // --------------------------------------------------------
    // * Memory leak 수정
    // * 잘못된 방식의 메모리 할당 수정
    //
    
    #include "StdAfx.h"
    #include "ImageLoader.h"
    
    CImageLoader::CImageLoader(void)
    : m_bGdiPlus(false)
    {
    }
    
    CImageLoader::~CImageLoader(void)
    {
    	if (m_bGdiPlus)
    	{
    #ifdef _GDIPLUS_H
    		DeleteImagesGdiplus();
    #endif;
    	}
    	else
    	{
    		DeleteImages();
    	}
    }
    
    void CImageLoader::LoadXML(CString szDir, CString szFile, bool bGdiPlus)
    {
    	// XML 파일일 로드한다.
    	m_szDir	   = szDir;
    	m_bGdiPlus = bGdiPlus;
    	Load(szDir + L"/" + szFile);
    	ReadData();
    }
    
    void CImageLoader::ReadData(void)
    {
    	BSTR nodeName;
    
    	m_hr = m_pDocument->get_documentElement(&m_pElement);
    	if (FAILED(m_hr) || m_pElement == NULL)
    	{
    		AfxMessageBox(L"Empty document!");
    	}
    
    	// ROOT 노드에 이름을 알아오자
    	m_pElement->get_nodeName(&nodeName);
    	TRACE(L"------------------------------------------\n");
    	TRACE(L"ROOT NODE : %s\n", CString(nodeName));
    	TRACE(L"------------------------------------------\n");
    
    	// CHILD 를 위해서 준비중
    	MSXML::IXMLDOMNode* pChild = NULL;
    	m_hr = m_pElement->get_firstChild(&pChild);
    
    	if (!m_bGdiPlus)
    	{
    		FindChildNode(pChild);
    	}
    	else 
    	{
    #ifdef _GDIPLUS_H
    		FindChildNodeGdiPlus(pChild);
    #endif;
    	}
    
    	SysFreeString(nodeName);
    }
    
    void CImageLoader::LoadImages(CImageData* pImg, int nIndex, CString szPath)
    {
    	if (szPath.GetLength() == 0)
    	{
    		// 파일명이 없으면NULL을 입력해두자.		
    		return;
    	}
    
    	// 파일이 존재하면 해당 파일을 읽어 들이자.
    	// 이곳에서 첫 splash window 와 연동하여 로딩 파일을
    	// 보여주면 좋을 것 같기도 하다! 추가적으로 구현해야할 부분이겠지
    	//
    	if (!pImg->m_pBmp[nIndex].Attach((HBITMAP)LoadImage(NULL,m_szDir + L"/" + szPath,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)))
    	{
    		CString szError;
    
    		szError.Format(L"Error : File Not Found (%s) <ImageLoader>", m_szDir + L"/" + szPath);
    		AfxMessageBox(szError);
    		exit(1);
    	}
    }
    
    CBitmap* CImageLoader::FindBitmap(CString szName)
    {
    	// 원하는 것 찾고 리턴하기
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    		
    		if (pImg->m_szName == szName)
    		{
    			return pImg->m_pBmp;
    		}
    	}
    
    	CString szError;
    	szError.Format(L"Element Not Found (%s) <ImageLoader>", szName);
    	AfxMessageBox(szError);
    
    	return NULL;
    }
    
    void CImageLoader::DeleteImages(void)
    {
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	// 동적 할당한 이미지를 찾아서 지우고
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    
    		if (pImg->m_nLength == 1)
    		{
    			DeleteObject(pImg->m_pBmp);
    			delete pImg->m_pBmp;
    		}
    		else
    		{
    			delete[] pImg->m_pBmp;
    		}
    	}
    
    	// 링크드리스트 지우자.
    	m_list.RemoveAll();
    }
    
    void CImageLoader::FindChildNode(MSXML::IXMLDOMNode* pChild)
    {
    	BSTR nodeType, nodeChildName;
    
    	while (true)
    	{
    		pChild->get_nodeTypeString(&nodeType);
    
    		if (!wcscmp(nodeType, L"element"))
    		{
    			TRACE(L"ELEMENT ");
    			pChild->get_nodeName(&nodeChildName);
    
    			// 이미지의 이름을 설정하고
    			CImageData img;
    			img.m_szName = CString(nodeChildName);
    
    			// 해당 노드에 자식 노드를 검사해서 갯수 체크하고
    			MSXML::IXMLDOMNodeList* nodeChild2;
    			MSXML::IXMLDOMNode* listItem = NULL;
    			m_hr = pChild->get_childNodes(&nodeChild2);
    
    			if (SUCCEEDED(m_hr) && nodeChild2 != NULL)
    			{
    				long nLength = 0;
    				nodeChild2->get_length(&nLength);
    				TRACE(L"NAME %s, LENGTH :%ld\n", img.m_szName, nLength);
    
    				// 해당 노드에 비트맵 수를 체크한 뒤에
    				// 메모리를 할당한다.
    				if (nLength == 1)
    				{
    					img.m_pBmp = new CBitmap;
    				}
    				else 
    				{
    					img.m_pBmp = new CBitmap[nLength];
    				}
    				img.m_nLength = nLength;
    
    				CString szNodeText;
    				BSTR nodeText;
    
    				// 노드에 값인 이미지 경로를 가져와서 불러들이자.
    				int i;
    				TRACE(L"------------------------------------------\n");
    				for (i=0; i<nLength; ++i)
    				{
    					listItem = NULL;
    					m_hr = nodeChild2->get_item(i, &listItem);
    					listItem->get_text(&nodeText);
    					szNodeText = CString(nodeText);
    					TRACE(L"NODE TEXT : %d : %s\n", i+1, szNodeText);
    
    					// 이미지를 로딩 하자.
    					LoadImages(&img, i, szNodeText);
    				}
    				TRACE(L"------------------------------------------\n");
    
    				m_list.AddTail(img);
    				SysFreeString(nodeText);
    			}
    		}
    		/*else if (!wcscmp(nodeType, L"text"))
    		{
    		TRACE(L"text\n");
    		}
    		else if (!wcscmp(nodeType, L"comment"))
    		{
    		TRACE(L"comment\n");
    		}
    		else
    		{
    		TRACE(L"others\n");
    		}*/
    
    		m_hr = pChild->get_nextSibling(&pChild);
    
    		if (FAILED(m_hr) || pChild == NULL)
    		{
    			break;
    		}
    	}
    
    	SysFreeString(nodeType);
    	SysFreeString(nodeChildName);
    }
    
    int CImageLoader::GetCount(void)
    {
    	return static_cast<int>(m_list.GetCount());
    }
    
    int CImageLoader::GetTargetCount(CString szName)
    {
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    
    		if (pImg->m_szName == szName)
    		{
    			return pImg->m_nLength;
    		}
    	}
    
    	return 0;
    }
    
    CPoint CImageLoader::GetImageInfo(CBitmap* pBmp)
    {
    	BITMAP bm;
    	pBmp->GetObject(sizeof(BITMAP), &bm); 
    
    	return CPoint(bm.bmWidth, bm.bmHeight);
    }
    
    CImageData* CImageLoader::FindImageData(CString szName)
    {
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    
    		if (pImg->m_szName == szName)
    		{
    			return pImg;
    		}
    	}
    
    	CString szError;
    	szError.Format(L"Element Not Found (%s) <ImageLoader>", szName);
    	AfxMessageBox(szError);
    	exit(1);
    
    	return NULL;
    }
    
    #ifdef _GDIPLUS_H
    Image** CImageLoader::FindImages(CString szName)
    {
    	// 원하는 것 찾고 리턴하기
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    
    		if (pImg->m_szName == szName)
    		{
    		//	TRACE("width %d, height:%d\n", pImg->m_pImg[0]->GetWidth(), pImg->m_pImg[0]->GetHeight());
    			return pImg->m_pImg;
    		}
    	}
    
    	CString szError;
    	szError.Format(L"Element Not Found (%s) <ImageLoader>", szName);
    	AfxMessageBox(szError);
    
    	return NULL;
    }
    
    void CImageLoader::LoadImagesGdiplus(CImageData* pImg, int nIndex, CString szPath)
    {
    	if (szPath.GetLength() == 0)
    	{
    		// 파일명이 없으면NULL을 입력해두자.		
    		return;
    	}
    
    	pImg->m_pImg[nIndex] = NULL;
    	pImg->m_pImg[nIndex] = Image::FromFile(m_szDir + L"/" + szPath);
    	if (pImg->m_pImg[nIndex] == NULL)
    	{
    		CString szError;
    
    		szError.Format(L"Error : File Not Found (%s) <ImageLoader plus>", m_szDir + L"/" + szPath);
    		AfxMessageBox(szError);
    		exit(1);
    	}
    }
    
    void CImageLoader::FindChildNodeGdiPlus(MSXML::IXMLDOMNode* pChild)
    {
    	BSTR nodeType, nodeChildName;
    
    	while (true)
    	{
    		pChild->get_nodeTypeString(&nodeType);
    
    		if (!wcscmp(nodeType, L"element"))
    		{
    			TRACE(L"ELEMENT ");
    			pChild->get_nodeName(&nodeChildName);
    
    			// 이미지의 이름을 설정하고
    			CImageData img;
    			img.m_szName = CString(nodeChildName);
    
    			// 해당 노드에 자식 노드를 검사해서 갯수 체크하고
    			MSXML::IXMLDOMNodeList* nodeChild2;
    			MSXML::IXMLDOMNode* listItem = NULL;
    			m_hr = pChild->get_childNodes(&nodeChild2);
    
    			if (SUCCEEDED(m_hr) && nodeChild2 != NULL)
    			{
    				long nLength = 0;
    				nodeChild2->get_length(&nLength);
    				TRACE(L"NAME %s, LENGTH :%ld\n", img.m_szName, nLength);
    
    				// 해당 노드에 비트맵 수를 체크한 뒤에
    				// 메모리를 할당한다.
    				if (nLength == 1)
    				{
    					img.m_pImg = new Image*;
    				}
    				else
    				{
    					img.m_pImg = new Image* [nLength];
    				}
    				img.m_nLength = nLength;
    
    				CString szNodeText;
    				BSTR nodeText;
    
    				// 노드에 값인 이미지 경로를 가져와서 불러들이자.
    				int i;
    				TRACE(L"------------------------------------------\n");
    				for (i=0; i<nLength; ++i)
    				{
    					listItem  = NULL;
    					m_hr	  = nodeChild2->get_item(i, &listItem);
    					listItem->get_text(&nodeText);
    					szNodeText = CString(nodeText);
    					TRACE(L"NODE TEXT(%d) : %s\n", i+1, szNodeText);
    
    					// 이미지를 로딩 하자.
    					LoadImagesGdiplus(&img, i, szNodeText);
    				}
    				TRACE(L"------------------------------------------\n");
    
    				m_list.AddTail(img);
    				SysFreeString(nodeText);
    			}
    		}
    
    		m_hr = pChild->get_nextSibling(&pChild);
    		if (FAILED(m_hr) || pChild == NULL)
    		{
    			break;
    		}
    	}
    
    	SysFreeString(nodeType);
    	SysFreeString(nodeChildName);
    }
    
    void CImageLoader::DeleteImagesGdiplus(void)
    {
    	POSITION pos = m_list.GetHeadPosition();
    	CImageData* pImg;
    
    	// 동적 할당한 이미지를 찾아서 지우고
    	while (pos)
    	{
    		pImg = &m_list.GetNext(pos);
    
    		TRACE(L"DELETE : %s %d\n", pImg->m_szName, pImg->m_nLength);
    		
    		if (pImg->m_nLength == 1)
    		{
    			delete pImg->m_pImg;
    		}
    		else
    		{
    			delete[] pImg->m_pImg;
    		}
    	}
    
    	// 링크드리스트 지우자.
    	m_list.RemoveAll();
    }
    
    #endif;
    
    #pragma once
    
    #include "parserxml.h"
    #include <afxtempl.h>
    
    class CImageData
    {
    public:
    	CString m_szName;
    	CBitmap* m_pBmp;
    	int m_nLength;
    
    	// GDI PLUS를 셋팅 했을 때에만 적용된다.
    #ifdef _GDIPLUS_H
    	Image** m_pImg;
    #endif;
    };
    
    class CImageLoader :
    	public CParserXML
    {
    protected:
    	CString m_szDir;
    	void ReadData(void);
    	void LoadImages(CImageData* pImg, int nIndex, CString szPath);
    	void DeleteImages(void);
    #ifdef _GDIPLUS_H
    	void DeleteImagesGdiplus(void);
    	void LoadImagesGdiplus(CImageData* pImg, int nIndex, CString szPath);
    #endif;
    	bool m_bGdiPlus;
    	
    public:
    	CImageLoader(void);
    	~CImageLoader(void);
    	CList<CImageData, CImageData&> m_list;
    	void LoadXML(CString szDir, CString szFile, bool bGdiPlus = false);
    	CBitmap* FindBitmap(CString szName);
    #ifdef _GDIPLUS_H
    	Image** FindImages(CString szName);
    	void FindChildNodeGdiPlus(MSXML::IXMLDOMNode* pChild);
    #endif;
    	void FindChildNode(MSXML::IXMLDOMNode* pChild);
    	int GetCount(void);
    	int GetTargetCount(CString szName);
    	CPoint GetImageInfo(CBitmap* pBmp);
    	CImageData* FindImageData(CString szName);
    };
    

    Comment


    입력하3 1508772444



    Locations of visitors to this page