本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 列出
而要如何利用來達成引擎要求的功能的說明留至下篇再繼績