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

来源:互联网 发布:微信模板发送java 编辑:程序博客网 时间:2024/06/05 19:27

本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_DCOMDECLARE_REGISTRY_RESOURCEID(IDR_IMGDECODER)#endifBEGIN_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()// ISupportsErrorInfoSTDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);DECLARE_PROTECT_FINAL_CONSTRUCT()HRESULT FinalConstruct(){m_lAlpha = -1;m_hImage = NULL;return S_OK;}void FinalRelease(){close();}public:protected:LONGm_lAlpha;HBITMAPm_hImage;#ifdef_WIN32_WCEImageInfom_info;#endif// IHLXAnimation Methodspublic: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 Methodspublic:STDMETHOD(load)( BSTR strFileName,  VARIANT_BOOL * retval){// Add your function implementation here.#ifdef_WIN32_WCEHDChDC=NULL;HDChMEMDC=NULL;HBITMAPhOld;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)) ){RECTrect={0,0,m_info.Width,m_info.Height};if( (m_hImage=CreateBitmap(hDC,m_info,m_lAlpha!=-1)) ){BITMAPbm;::GetObject(m_hImage,sizeof(BITMAP),&bm);if( m_lAlpha !=-1 && bm.bmBits ){BitmapDatabitmapData;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;}#endifreturn 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_WCEHDChMemDC;HGDIOBJhldObject;if( m_hImage != NULL && (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) ){hldObject=::SelectObject(hMemDC,m_hImage);if( m_lAlpha != -1 ){BLENDFUNCTIONbl;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;elsebl.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);}#endifreturn S_OK;}STDMETHOD(Width)( LONG * result){// Add your function implementation here.#ifdef_WIN32_WCEif( m_hImage != NULL ){*result=m_info.Width;return S_OK;}#endifreturn S_FALSE;}STDMETHOD(Height)(LONG * result){// Add your function implementation here.#ifdef_WIN32_WCEif( m_hImage != NULL ){*result=m_info.Height;return S_OK;}#endifreturn 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_WCEHDChMemDC;HGDIOBJhldObject;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);}#endifreturn 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.HDChMemDC;HGDIOBJhldObject;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 ){LONGwidth,height;HDChMemDC;HGDIOBJhldObject;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_WCEHBITMAPCreateBitmap( 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 hereif( pVal ){*pVal = m_lAlpha;return S_OK;}return S_FALSE;}STDMETHODIMP CIMGDecoder::put_AlphaMode(LONG newVal){// TODO: Add your implementation code herem_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_DCOMDECLARE_REGISTRY_RESOURCEID(IDR_BMPDECODER)#endifBEGIN_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:LONGm_lAlpha;BITMAPm_bm;HBITMAPm_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_WCEif( (m_hBitmap=(HBITMAP)::SHLoadDIBitmap( strFileName )) ){::GetObject(m_hBitmap,sizeof(BITMAP),&m_bm);*retval = VARIANT_TRUE;return S_OK;}#endifreturn S_FALSE;}STDMETHODIMP CBMPDecoder::close(void){// TODO: Add your implementation code hereif( 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 hereHDChMemDC;HGDIOBJhldObject;if( m_hBitmap != NULL && (hMemDC=::CreateCompatibleDC((HDC)hdcDraw)) ){hldObject=::SelectObject(hMemDC,m_hBitmap);#ifdef_WIN32_WCEif( m_lAlpha != -1 ){BLENDFUNCTIONbl;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_WCEHDChMemDC;HGDIOBJhldObject;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);}#endifreturn 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 hereHDChMemDC;HGDIOBJhldObject;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 hereif( pVal ){*pVal = m_lAlpha;return S_OK;}return S_FALSE;}STDMETHODIMP CBMPDecoder::put_AlphaMode(LONG newVal){// TODO: Add your implementation code herem_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 ){LONGwidth,height;HDChMemDC;HGDIOBJhldObject;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 列出

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