建置一個 WINCE 下的 XML BASE 的人機介面引擎 ---- 繪圖引擎篇 (1)

本BLOG所有原創之原始程式碼皆為本人創作,非經本人同意不得轉載,非經本人授權不得使用在營利用途

前言

由於我本身的工作一直和寫引擎級的程式有不解之緣,每至一家公司在離開之前
至少都會留下一套引擎庫 ,大至分散式交易,三層式報表,物件式資料庫 ,
小至 Script Parse ,車用導航引擎,PND 的人機介面引擎 ,都是一手包辦 ,幾年下來也有不少心得
其中也看了不少技術 MFC/WIN32 ,ATL/WTL ,COM ,DCOM ,ADO ,ODBC ,SQL ,TCP/IP .....
以後有空將會慢慢整理出來,也算是整理一下,好看看未來下一步還有什好玩的技術沒碰過


緣由
眾所皆知,想要在 WINCE 寫一個生動的 UI 需要花費不少心力
一來是 WINCE 本身對 RESOURCE 支援有限 ,而一些好用的 Package 
如 WebBrowse,flashplayer ... 等這些不是效能有待加強,就是授權費的問題

因此便有一個以 XML 為基礎,可以和 DHTML 般可以用 XML 就可以組成人機介面的一套程式庫計劃產生


可能有人會說,直接用WebBrowse Control + HTML 不就好了,何必花那麼多工夫?

的確在 Windows 干台下UI 用 WebBrowse 是一個好的選擇,但是那是在Windows 不是 WinCE,

在WinCE 下的 WebBrowse Control 不是可以免費使用,而是隨出貨量計價,這一來如果有個可以不會便用到 Microsoft一些需要授權費的技術,

但也可以辦到人機介面一些互動,國際化,元件化,可程式化的引擎計劃就此開始了 


但是寫這引擎是簡單 ,但是如何說明這些技術細節,對我而言可是難的很,因為範圍廣且多,不知由那開頭,所以只好先胡亂開場好了 ,反正人機介面

最主要就是在人機互動上,而人機互動是建在繪圖引擎和腳本引擎,就由這開始好了



繪圖引擎篇


繪圖引擎與元件


談到繪圖引擎在 WIN32 CE下一定跳不開 GDI ,Alpha API ,DirectDraw ,GAPI ,GDI-SUB這些
尤其是 double buff ,如果是在 CE 6.0 以前還可以直接切進 kernel mode 寫進
video memory ,那 double buff 更是重要 ,不過這都是過去的事了 ,如果目標是定在
WINCE 6.0 那能用的且相容性最好的還是 GDI+double buff ,但是要支持那些格式BMP? JPG? GIF? TIFF? PNG?
動畫要不要支持? 而且如何畫出圖片? 要不要有 Alpha? MutilLayer? 這就是第一個要解決的課題 ,而如何支持各種編碼格式的方案
是什麼方法? 答案就是解碼裝置化 ,也就是只要定一組 Image Interface 而 DeCoder 也依 Image Interface

規則實作,就可以辦到 ,不多說先看看 Interface 是如何定的 ,而在 COM 世界中要說明 INTERFACE 最簡單最清楚的就是用 IDL

我們先來看 和 IMAGE 引擎有關的IDL 部份


介面定義


interface IHLXAnimation : IDispatch{
    [id(1), helpstring("method Next")] HRESULT Next([out,retval] LONG* result);
    [id(2), helpstring("method frameCount")] HRESULT frameCount([out,retval] LONG* count);
    [id(3), helpstring("method First")] HRESULT First([out,retval] LONG* result);
};


interface IHLXImage : IDispatch{
[id(1), helpstring("method load")] HRESULT load([in] BSTR strFileName, [out,retval] VARIANT_BOOL* retval);
[id(2), helpstring("method close")] HRESULT close(void);
[id(3), helpstring("method Draw")] HRESULT Draw([in] OLE_HANDLE hdcDraw , [in] LONG left, [in] LONG top,[in]LONG x ,[in]LONG y,[in]LONG width ,[in]LONG height);
[id(4), helpstring("method Width")] HRESULT Width([out,retval] LONG* result);
[id(5), helpstring("method Height")] HRESULT Height(LONG* result);
[id(6), helpstring("method Transparent")] HRESULT Transparent([in] OLE_HANDLE hdcDraw, [in] LONG left, [in] LONG top, [in] LONG x, [in] LONG y, [in] LONG width, [in] LONG height, [in] OLE_COLOR TransparentColor);
[id(7), helpstring("method Alpha")] HRESULT Alpha([in] OLE_HANDLE hdcDraw, [in] LONG left, [in] LONG top, [in] LONG x, [in] LONG y, [in] LONG width, [in] LONG height, [in] LONG alpha);
[propget, id(8), helpstring("property AlphaMode")] HRESULT AlphaMode([out, retval] LONG* lAlpha);
[propput, id(8), helpstring("property AlphaMode")] HRESULT AlphaMode([in] LONG lAlpha );
};


interface IHLXImage2 : IHLXImage{
[id(1), helpstring("method DrawBuff")] HRESULT DrawBuff([in]OLE_HANDLE hdcDraw ,[in]VARIANT pDrawFrame, [in]LONG x ,[in]LONG y,[in]LONG width ,[in]LONG height);
[id(2), helpstring("method length")] HRESULT length(void);
[id(3), helpstring("method next")] HRESULT next([in]LONG step ,[out,retval]LONG* postion);
[id(4), helpstring("method prev")] HRESULT prev([in]LONG step ,[out,retval]LONG* postion);
[propget, id(5), helpstring("property postion")] HRESULT postion([out, retval] LONG* pVal);
[propput, id(5), helpstring("property postion")] HRESULT postion([in] LONG newVal);

[id(6), helpstring("method first")] HRESULT first(void);
[id(7), helpstring("method last")] HRESULT last(void);
};


interface IImageMerge : IUnknown{
[id(1), helpstring("method DrawLayer")] HRESULT DrawLayer([in]IHLXImage* Image , [in] LONG left, [in] LONG top );
[id(2), helpstring("method Clone")] HRESULT Clone([out,retval]IHLXImage** Image );

};


Event 部份


dispinterface _IHLXImageEvents
{
properties:
methods:
[id(1), helpstring("method OnViewChange")] HRESULT OnViewChange( [in]LONG id );
};



實作部份的定義


interface IPNGDecoder : IDispatch{
};


interface IGIFDecoder : IDispatch{
};


interface IBMPDecoder : IDispatch{
};

interface IIMGDecoder : IDispatch{
};

coclass HLXImage
{
[default] interface IHLXImage;
};


coclass PNGDecoder
{
[default] interface IPNGDecoder;
};


coclass GIFDecoder
{
[default] interface IGIFDecoder;
interface IHLXImage;
interface IHLXAnimation;
};


coclass BMPDecoder
{
[default] interface IBMPDecoder;
interface IImageMerge;
interface IHLXImage;
};


coclass IMGDecoder
{
[default] interface IIMGDecoder;
interface IImageMerge;
interface IHLXImage;
interface IHLXAnimation;
};



在實作碼部份 先來看看其中 IMGDecoder 的實作

IMGDecoder.h

class ATL_NO_VTABLE CIMGDecoder :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CIMGDecoder, &CLSID_IMGDecoder>,
	public ISupportErrorInfo,
	public IImageMerge,
	public IDispatchImpl<IIMGDecoder, &IID_IIMGDecoder, &LIBID_HLXDocvwLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
	public IDispatchImpl<IHLXAnimation, &__uuidof(IHLXAnimation), &LIBID_HLXDocvwLib, /* wMajor = */ 1, /* wMinor = */ 0>,
	public IDispatchImpl<IHLXImage, &__uuidof(IHLXImage), &LIBID_HLXDocvwLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
	CIMGDecoder()
	{
	}

#ifdef _CE_DCOM
	DECLARE_REGISTRY_RESOURCEID(IDR_IMGDECODER)
#endif


	BEGIN_COM_MAP(CIMGDecoder)
		COM_INTERFACE_ENTRY(IIMGDecoder)
		COM_INTERFACE_ENTRY(IImageMerge)
		COM_INTERFACE_ENTRY2(IDispatch, IHLXAnimation)
		COM_INTERFACE_ENTRY(ISupportErrorInfo)
		COM_INTERFACE_ENTRY(IHLXAnimation)
		COM_INTERFACE_ENTRY(IHLXImage)
	END_COM_MAP()

	// ISupportsErrorInfo
	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		m_lAlpha = -1;
		m_hImage = NULL;
		return S_OK;
	}

	void FinalRelease()
	{
		close();
	}

public:

protected:
	LONG	m_lAlpha;
	HBITMAP			m_hImage;
#ifdef	_WIN32_WCE
	ImageInfo		m_info;
#endif
	// IHLXAnimation Methods
public:
	STDMETHOD(Next)( LONG* result)
	{
		// Add your function implementation here.
		if( result )
			*result = 0;
		return S_FALSE;
	}
	STDMETHOD(frameCount)( LONG * count)
	{
		// Add your function implementation here.
		if( count )
		{
			*count =0;
			if( m_hImage != NULL )
				*count =1;
			return S_OK;
		}
		return S_FALSE;
	}

	STDMETHOD(First)( LONG* result )
	{
		// Add your function implementation here.
		if( result )
			*result = 0;
		return S_OK;
	}

	// IHLXImage Methods
public:
	STDMETHOD(load)( BSTR strFileName,  VARIANT_BOOL * retval)
	{
		// Add your function implementation here.
#ifdef	_WIN32_WCE
		HDC	hDC=NULL;
		HDC	hMEMDC=NULL;
		HBITMAP	hOld;
		CComPtr<IImagingFactory>	spImageFactory;
		CComPtr<IImage>				spImage;
		
		close();
		if( retval != NULL &&
			SUCCEEDED(spImageFactory.CoCreateInstance(CLSID_ImagingFactory)) &&
			SUCCEEDED(spImageFactory->CreateImageFromFile(strFileName,&spImage)) &&
			spImage != NULL )
		{
			spImage->GetImageInfo(&m_info);
			if( (hDC=::GetDC(NULL)) )
			{
				RECT	rect={0,0,m_info.Width,m_info.Height};

				if( (m_hImage=CreateBitmap(hDC,m_info,m_lAlpha!=-1)) )
				{
					BITMAP	bm;
					
					::GetObject(m_hImage,sizeof(BITMAP),&bm);
					if( m_lAlpha !=-1 && bm.bmBits )
					{
						BitmapData				bitmapData;
						CComPtr<IBitmapImage>	pBitmapImage;

						bitmapData.Width = m_info.Width;
						bitmapData.Height = m_info.Height;
						bitmapData.PixelFormat = m_info.PixelFormat;
						pBitmapImage = NULL;
	
						spImageFactory->CreateBitmapFromImage(spImage, m_info.Width, m_info.Height, PIXFMT_32BPP_PARGB,InterpolationHintAveraging, &pBitmapImage);
						if( pBitmapImage != NULL )
						{
							pBitmapImage->LockBits(&rect, ImageLockModeRead,PIXFMT_32BPP_PARGB, &bitmapData);
							memcpy(bm.bmBits, bitmapData.Scan0, m_info.Width * m_info.Height * 4);
							pBitmapImage->UnlockBits(&bitmapData);
							pBitmapImage = NULL;
							*retval = VARIANT_TRUE;
						}						
					}
					else 
					{
						if( (hMEMDC=::CreateCompatibleDC(hDC)) )
						{
							hOld=(HBITMAP)::SelectObject(hMEMDC,m_hImage);
							spImage->Draw(hMEMDC,&rect,NULL);
							::SelectObject(hMEMDC,hOld);
							::DeleteDC(hMEMDC);
							*retval = VARIANT_TRUE;
						}
					}
				}
				::ReleaseDC(NULL,hDC);
			}
			return S_OK;
		}
#endif
		return S_FALSE;
	}

	STDMETHOD(close)()
	{
		// Add your function implementation here.
		if( m_hImage != NULL )
			::DeleteObject(m_hImage);
		m_hImage = NULL;
		return S_OK;
	}

	STDMETHOD(Draw)( OLE_HANDLE hdcDraw,  LONG left,  LONG top,  LONG x,  LONG y,  LONG width,  LONG height)
	{
		// Add your function implementation here.
#ifdef	_WIN32_WCE
		HDC		hMemDC;
		HGDIOBJ	hldObject;

		if( m_hImage != NULL && (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
		{
			hldObject=::SelectObject(hMemDC,m_hImage);
			if( m_lAlpha != -1 )
			{
				BLENDFUNCTION	bl;

				bl.BlendOp = AC_SRC_OVER;
				bl.BlendFlags = 0;
				bl.SourceConstantAlpha = BYTE(m_lAlpha);
				if( m_info.PixelFormat == PIXFMT_32BPP_ARGB )
					bl.AlphaFormat = AC_SRC_ALPHA;
				else
					bl.AlphaFormat = 0;
				if( width == -1 || width > LONG(m_info.Width) )
					width = m_info.Width;
				if( height == -1 || height > LONG(m_info.Height) )
					height = m_info.Height;
				::AlphaBlend((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,bl);					
			}
			else
				::BitBlt((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,SRCCOPY);
			::SelectObject(hMemDC,hldObject);
			::DeleteDC(hMemDC);

		}
#endif
		return S_OK;
	}

	STDMETHOD(Width)( LONG * result)
	{
		// Add your function implementation here.
#ifdef	_WIN32_WCE
		if( m_hImage != NULL )
		{
			*result=m_info.Width;
			return S_OK;
		}
#endif
		return S_FALSE;
	}

	STDMETHOD(Height)(LONG * result)
	{
		// Add your function implementation here.
#ifdef	_WIN32_WCE
		if( m_hImage != NULL )
		{
			*result=m_info.Height;
			return S_OK;
		}
#endif
		return S_FALSE;
	}

	STDMETHOD(Transparent)( OLE_HANDLE hdcDraw,  LONG left,  LONG top,  LONG x,  LONG y,  LONG width,  LONG height,  OLE_COLOR TransparentColor)
	{
		// Add your function implementation here.
#ifdef	_WIN32_WCE
		HDC		hMemDC;
		HGDIOBJ	hldObject;

		if( m_hImage != NULL && (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
		{
			hldObject=::SelectObject(hMemDC,m_hImage);
			::TransparentImage((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,TransparentColor);
			::SelectObject(hMemDC,hldObject);
			::DeleteDC(hMemDC);

		}
#endif
		return S_OK;
	}

	STDMETHOD(Alpha)( OLE_HANDLE hdcDraw,  LONG left,  LONG top,  LONG x,  LONG y,  LONG width,  LONG height,  LONG alpha)
	{
		// Add your function implementation here.
		HDC		hMemDC;
		HGDIOBJ	hldObject;
		BLENDFUNCTION bm;

		if( (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
		{
			bm.BlendOp=AC_SRC_OVER;
			bm.BlendFlags=0;	
			bm.AlphaFormat=0; 
			bm.SourceConstantAlpha=BYTE(alpha);

			hldObject=::SelectObject(hMemDC,m_hImage);
#ifdef	_WIN32_WCE
			::AlphaBlend((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,bm); 
#endif
			::SelectObject(hMemDC,hldObject);
			::DeleteDC(hMemDC);
		}
		return S_OK;
	}
	STDMETHOD(get_AlphaMode)(LONG* pVal);
	STDMETHOD(put_AlphaMode)(LONG newVal);

	STDMETHOD(Clone)(IHLXImage** pImage );

	STDMETHOD(DrawLayer)( IHLXImage* Image ,LONG left ,LONG top )
	{
		LONG	width,height;
		HDC		hMemDC;
		HGDIOBJ	hldObject;

		if( m_hImage == NULL || Image == NULL )
			return S_FALSE;

		Image->Width(&width);
		Image->Height(&height);
		if( (hMemDC=::CreateCompatibleDC(NULL)) )
		{
			hldObject=::SelectObject(hMemDC,m_hImage);			
			Image->Draw((OLE_HANDLE)hMemDC,left,top,0,0,width,height);
			::SelectObject(hMemDC,hldObject);
			::DeleteDC(hMemDC);
			return S_OK;
		}
		return S_FALSE;
	}
#ifdef	_WIN32_WCE
	HBITMAP	CreateBitmap( HDC hDC ,ImageInfo& info ,bool bAlpha )
	{
		if( bAlpha && (info.PixelFormat==PIXFMT_32BPP_ARGB) )
		{
			BITMAPINFO*	pbinfo;

			if( (pbinfo=(BITMAPINFO*)_alloca(sizeof(BITMAPINFO)+4*sizeof(INT))) == NULL )
				return FALSE ;

			pbinfo->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
			pbinfo->bmiHeader.biWidth = info.Width ;
			pbinfo->bmiHeader.biHeight = -info.Height ;
			pbinfo->bmiHeader.biPlanes = 1;
			pbinfo->bmiHeader.biBitCount = 32;
			pbinfo->bmiHeader.biCompression = BI_ALPHABITFIELDS;
			pbinfo->bmiHeader.biSizeImage = 0 ;
			pbinfo->bmiHeader.biXPelsPerMeter = 11811;
			pbinfo->bmiHeader.biYPelsPerMeter = 11811;
			pbinfo->bmiHeader.biClrUsed = 0;
			pbinfo->bmiHeader.biClrImportant = 0;

			int *pMask = (int*)&(pbinfo->bmiColors[0]) ;
			*pMask++ = 0x00FF0000 ;
			*pMask++ = 0x0000FF00 ;
			*pMask++ = 0x000000FF ;
			*pMask++ = 0xFF000000 ;
			return CreateDIBSection(hDC, pbinfo, DIB_RGB_COLORS, NULL , NULL, 0);
		}
		return ::CreateCompatibleBitmap(hDC,info.Width,info.Height);
	}


#endif
};

OBJECT_ENTRY_AUTO(__uuidof(IMGDecoder), CIMGDecoder)

IMGDecoder.cpp

STDMETHODIMP CIMGDecoder::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IIMGDecoder
	};

	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CIMGDecoder::get_AlphaMode(LONG* pVal)
{
	// TODO: Add your implementation code here
	if( pVal )
	{
		*pVal = m_lAlpha;
		return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CIMGDecoder::put_AlphaMode(LONG newVal)
{
	// TODO: Add your implementation code here
	m_lAlpha = newVal;
	if( m_lAlpha > 255 )
		m_lAlpha = 255;
	return S_OK;
}

STDMETHODIMP CIMGDecoder::Clone(IHLXImage** pImage )
{
	CComObject<CBMPDecoder>*	pNewImage;

	if( m_hImage == NULL || pImage == NULL )
		return FALSE;

	pNewImage = new CComObject<CBMPDecoder>;
	if( pNewImage != NULL )
	{		
		pNewImage->FinalConstruct();
		if( m_lAlpha != -1 )
			pNewImage->put_AlphaMode(m_lAlpha);
		pNewImage->Attach(m_hImage);	
		return pNewImage->QueryInterface(IID_IHLXImage,(LPVOID*)pImage);
	}
	return S_FALSE;
}

BMPDecoder.h

class ATL_NO_VTABLE CBMPDecoder :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CBMPDecoder, &CLSID_BMPDecoder>,
	public IImageMerge,
	public IDispatchImpl<IHLXImage, &IID_IHLXImage, &LIBID_HLXDocvwLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
	public IDispatchImpl<IBMPDecoder, &IID_IBMPDecoder, &LIBID_HLXDocvwLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
	CBMPDecoder()
	{
	}

#ifdef _CE_DCOM
	DECLARE_REGISTRY_RESOURCEID(IDR_BMPDECODER)
#endif


BEGIN_COM_MAP(CBMPDecoder)
	COM_INTERFACE_ENTRY(IBMPDecoder)
	COM_INTERFACE_ENTRY(IImageMerge)
	COM_INTERFACE_ENTRY(IHLXImage)
	COM_INTERFACE_ENTRY2(IDispatch,IHLXImage)
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		m_lAlpha = -1;
		m_hBitmap = NULL;
		return S_OK;
	}

	void FinalRelease()
	{
		close();
	}

protected:
	LONG	m_lAlpha;
	BITMAP	m_bm;
	HBITMAP	m_hBitmap;

public:
	STDMETHOD(load)(BSTR strFileName, VARIANT_BOOL* retval);
	STDMETHOD(close)(void);
	STDMETHOD(Draw)(OLE_HANDLE hdcDraw,LONG left, LONG top,LONG x ,LONG y,LONG width ,LONG height);
	STDMETHOD(Width)(LONG* result);
	STDMETHOD(Height)(LONG* result);
	STDMETHOD(Transparent)(OLE_HANDLE hdcDraw,LONG left, LONG top, LONG x, LONG y, LONG width, LONG height, OLE_COLOR TransparentColor);
	STDMETHOD(Alpha)(OLE_HANDLE hdcDraw, LONG left, LONG top, LONG x, LONG y, LONG width, LONG height, LONG alpha);
	STDMETHOD(get_AlphaMode)(LONG* pVal);
	STDMETHOD(put_AlphaMode)(LONG newVal);

	STDMETHOD(Clone)(IHLXImage** pImage );
	STDMETHOD(DrawLayer)( IHLXImage* Image ,LONG left ,LONG top );

	bool Attach( HBITMAP hBmp );
};

OBJECT_ENTRY_AUTO(__uuidof(BMPDecoder), CBMPDecoder)

BMPDecoder.cpp

STDMETHODIMP CBMPDecoder::load(BSTR strFileName, VARIANT_BOOL* retval)
{
	// TODO: Add your implementation code here

#ifdef _WIN32_WCE
	if( (m_hBitmap=(HBITMAP)::SHLoadDIBitmap( strFileName )) )
	{
		::GetObject(m_hBitmap,sizeof(BITMAP),&m_bm);
		*retval = VARIANT_TRUE;
		return S_OK;
	}
#endif
	return S_FALSE;
}

STDMETHODIMP CBMPDecoder::close(void)
{
	// TODO: Add your implementation code here
	if( m_hBitmap != NULL )
		DeleteObject(m_hBitmap);
	m_hBitmap = NULL;
	return S_OK;
}

STDMETHODIMP CBMPDecoder::Draw(OLE_HANDLE hdcDraw,LONG left,LONG top,LONG x ,LONG y,LONG width ,LONG height)
{
	// TODO: Add your implementation code here	

	HDC		hMemDC;
	HGDIOBJ	hldObject;

	if( m_hBitmap != NULL && (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
	{
		hldObject=::SelectObject(hMemDC,m_hBitmap);
#ifdef	_WIN32_WCE
		if( m_lAlpha != -1 )
		{
			BLENDFUNCTION	bl;

			bl.BlendOp = AC_SRC_OVER;
			bl.BlendFlags = 0;
			bl.SourceConstantAlpha = BYTE(m_lAlpha);
			bl.AlphaFormat = 0;
			if( width > LONG(m_bm.bmWidth) )
				width = m_bm.bmWidth;
			if( height > LONG(m_bm.bmHeight) )
				height = m_bm.bmHeight;
			::AlphaBlend((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,bl);					
		}
		else
			::BitBlt((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,SRCCOPY);
#endif
		::SelectObject(hMemDC,hldObject);
		::DeleteDC(hMemDC);

	}
	return S_OK;
}

STDMETHODIMP CBMPDecoder::Width(LONG* result)
{
	// TODO: Add your implementation code here
	*result = 0;
	if( m_hBitmap != NULL )
		*result = m_bm.bmWidth;
	return S_OK;
}

STDMETHODIMP CBMPDecoder::Height(LONG* result)
{
	// TODO: Add your implementation code here

	*result = 0;
	if( m_hBitmap != NULL )
		*result = m_bm.bmHeight;
	return S_OK;
}

STDMETHODIMP CBMPDecoder::Transparent(OLE_HANDLE hdcDraw, LONG left, LONG top, LONG x, LONG y, LONG width, LONG height, OLE_COLOR TransparentColor)
{
	// TODO: Add your implementation code here
#ifdef	_WIN32_WCE
	HDC		hMemDC;
	HGDIOBJ	hldObject;

	if( (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
	{
		hldObject=::SelectObject(hMemDC,m_hBitmap);
		::TransparentImage((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,TransparentColor);
		::SelectObject(hMemDC,hldObject);
		::DeleteDC(hMemDC);

	}
#endif
	return S_OK;
}

STDMETHODIMP CBMPDecoder::Alpha(OLE_HANDLE hdcDraw, LONG left, LONG top, LONG x, LONG y, LONG width, LONG height, LONG alpha)
{
	// TODO: Add your implementation code here

	HDC		hMemDC;
	HGDIOBJ	hldObject;
	BLENDFUNCTION bm;

	if( (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) )
	{
		bm.BlendOp=AC_SRC_OVER;
		bm.BlendFlags=0;	
		bm.AlphaFormat=0; 
		bm.SourceConstantAlpha=BYTE(alpha);

		hldObject=::SelectObject(hMemDC,m_hBitmap);
#ifdef	_WIN32_WCE
		::AlphaBlend((HDC)hdcDraw,left,top,width,height,hMemDC,x,y,width,height,bm); 
#endif
		::SelectObject(hMemDC,hldObject);
		::DeleteDC(hMemDC);

	}
	return S_OK;
}


STDMETHODIMP CBMPDecoder::get_AlphaMode(LONG* pVal)
{
	// TODO: Add your implementation code here
	if( pVal )
	{
		*pVal = m_lAlpha;
		return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CBMPDecoder::put_AlphaMode(LONG newVal)
{
	// TODO: Add your implementation code here
	m_lAlpha = newVal;
	if( m_lAlpha > 255 )
		m_lAlpha = 255;
	return S_OK;
}

bool CBMPDecoder::Attach( HBITMAP hbm )
{
    HDC hdcSrc,hdcDst;
    HBITMAP hbmOld, hbmOld2;
    BITMAP bm;

	if( hbm )
	{
		close();
	    hdcSrc = CreateCompatibleDC(NULL);
		hdcDst = CreateCompatibleDC(NULL);
		GetObject(hbm, sizeof(bm), &m_bm);
		if( (m_hBitmap=CreateBitmap( m_bm.bmWidth, m_bm.bmHeight, m_bm.bmPlanes,m_bm.bmBitsPixel,NULL)) )
		{
			hbmOld = (HBITMAP)SelectObject(hdcSrc, hbm);
			hbmOld2 = (HBITMAP)SelectObject(hdcDst, m_hBitmap);
			BitBlt(hdcDst, 0, 0, m_bm.bmWidth, m_bm.bmHeight, hdcSrc, 0, 0, SRCCOPY);
			SelectObject(hdcDst, hbmOld2);
			SelectObject(hdcSrc, hbmOld);
		}
		if( hdcSrc )
			DeleteDC(hdcSrc);
		if( hdcDst )
			DeleteDC(hdcDst);
	}
	return true;
}

STDMETHODIMP CBMPDecoder::Clone(IHLXImage** pImage )
{
	CComObject<CBMPDecoder>*	pNewImage;

	if( m_hBitmap == NULL || pImage == NULL )
		return FALSE;

	pNewImage = new CComObject<CBMPDecoder>;
	if( pNewImage != NULL )
	{
		pNewImage->FinalConstruct();
		if( m_lAlpha != -1 )
			pNewImage->put_AlphaMode(m_lAlpha);
		pNewImage->Attach(m_hBitmap);
		return pNewImage->QueryInterface(IID_IHLXImage,(LPVOID*)pImage);
	}
	return S_FALSE;
}

STDMETHODIMP CBMPDecoder::DrawLayer( IHLXImage* Image ,LONG left ,LONG top )
{
	LONG	width,height;
	HDC		hMemDC;
	HGDIOBJ	hldObject;

	if( m_hBitmap == NULL || Image == NULL )
		return S_FALSE;

	Image->Width(&width);
	Image->Height(&height);
	if( (hMemDC=::CreateCompatibleDC(NULL)) )
	{
		hldObject=::SelectObject(hMemDC,m_hBitmap);
		Image->Draw((OLE_HANDLE)hMemDC,left,top,0,0,width,height);
		::SelectObject(hMemDC,hldObject);
		::DeleteDC(hMemDC);
		return S_OK;
	}
	return S_FALSE;
}

先把這2個引擎內建而且最重要的 DeCoder Driver 列出

而要如何利用來達成引擎要求的功能的說明留至下篇再繼績


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值