#define DECLARE_MEMCLEAR_NEW_DELETE \ void * __cdecl operator new(size_t cb) { void *pv = malloc(cb); if (pv) ZeroMemory(pv, cb); return pv; } \ void __cdecl operator delete(void * pv) { free(pv); } class CVoid { }; class CBaseFT : public CVoid { public: DECLARE_MEMCLEAR_NEW_DELETE ULONG AddRef() { return((ULONG)InterlockedIncrement((LONG *)&_ulRefs)); } ULONG Release(); ULONG SubAddRef() { return((ULONG)InterlockedIncrement((LONG *)&_ulAllRefs)); } ULONG SubRelease(); CRITICAL_SECTION * GetPcs() { return(_pcs); } void SetPcs(CRITICAL_SECTION *pcs) { _pcs = pcs; } ULONG GetRefs() { return(_ulRefs); } ULONG GetAllRefs() { return(_ulAllRefs); } void EnterCriticalSection() { if (_pcs) ::EnterCriticalSection(_pcs); } void LeaveCriticalSection() { if (_pcs) ::LeaveCriticalSection(_pcs); } protected: CBaseFT(CRITICAL_SECTION * pcs = NULL); virtual ~CBaseFT(); virtual void Passivate(); ULONG InterlockedRelease() { return((ULONG)InterlockedDecrement((LONG *)&_ulRefs)); } private: CRITICAL_SECTION * _pcs; ULONG _ulRefs; ULONG _ulAllRefs; }; class CDDrawWrapper : public CBaseFT, public IDirectDrawSurface, public IDirectDrawPalette { typedef CBaseFT super; public: CDDrawWrapper(HBITMAP hbmDib); ~CDDrawWrapper(); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); STDMETHOD(QueryInterface)(REFIID iid, void** ppInterface); // IDirectDrawSurface STDMETHOD(AddAttachedSurface)(LPDIRECTDRAWSURFACE lpdds); STDMETHOD(AddOverlayDirtyRect)(LPRECT lprc); STDMETHOD(Blt)(LPRECT lprcDest, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dw, LPDDBLTFX lpfx); STDMETHOD(BltBatch)(LPDDBLTBATCH lpBlt, DWORD dwCount, DWORD dwFlags); STDMETHOD(BltFast)(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dwTrans); STDMETHOD(DeleteAttachedSurface)(DWORD dwFlags, LPDIRECTDRAWSURFACE lpdds); STDMETHOD(EnumAttachedSurfaces)(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn); STDMETHOD(EnumOverlayZOrders)(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn); STDMETHOD(Flip)(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags); STDMETHOD(GetAttachedSurface)(LPDDSCAPS lpCaps, LPDIRECTDRAWSURFACE FAR * lpdds); STDMETHOD(GetBltStatus)(DWORD dw); STDMETHOD(GetCaps)(LPDDSCAPS lpCaps); STDMETHOD(GetClipper)(LPDIRECTDRAWCLIPPER FAR* lpClipper); STDMETHOD(GetColorKey)(DWORD dw, LPDDCOLORKEY lpKey); STDMETHOD(GetDC)(HDC FAR * lphdc); STDMETHOD(GetFlipStatus)(DWORD dw); STDMETHOD(GetOverlayPosition)(LPLONG lpl1, LPLONG lpl2); STDMETHOD(GetPalette)(LPDIRECTDRAWPALETTE FAR* ppPal); STDMETHOD(GetPixelFormat)(LPDDPIXELFORMAT pPixelFormat); STDMETHOD(GetSurfaceDesc)(LPDDSURFACEDESC pSurfaceDesc); STDMETHOD(Initialize)(LPDIRECTDRAW pDD, LPDDSURFACEDESC pSurfaceDesc); STDMETHOD(IsLost)(); STDMETHOD(Lock)(LPRECT pRect, LPDDSURFACEDESC pSurfaceDesc, DWORD dwFlags, HANDLE hEvent); STDMETHOD(ReleaseDC)(HDC hdc); STDMETHOD(Restore)(); STDMETHOD(SetClipper)(LPDIRECTDRAWCLIPPER pClipper); STDMETHOD(SetColorKey)(DWORD dwFlags, LPDDCOLORKEY pDDColorKey); STDMETHOD(SetOverlayPosition)(LONG x, LONG y); STDMETHOD(SetPalette)(LPDIRECTDRAWPALETTE pDDPal); STDMETHOD(Unlock)(LPVOID pBits); STDMETHOD(UpdateOverlay)(LPRECT prc, LPDIRECTDRAWSURFACE pdds, LPRECT prc2, DWORD dw, LPDDOVERLAYFX pfx); STDMETHOD(UpdateOverlayDisplay)(DWORD dw); STDMETHOD(UpdateOverlayZOrder)(DWORD dw, LPDIRECTDRAWSURFACE pdds); // IDirectDrawPalette STDMETHOD(SetEntries)(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries); STDMETHOD(GetCaps)(LPDWORD lpdw); STDMETHOD(GetEntries)(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries); STDMETHOD(Initialize)(LPDIRECTDRAW lpdd, DWORD dwCount, LPPALETTEENTRY pEntries); protected: HBITMAP m_hbmDib; DIBSECTION m_dsSurface; DDCOLORKEY m_ddColorKey; LONG m_lPitch; RECT m_rcSurface; BYTE * m_pbBits; }; HBITMAP ImgCreateDib(LONG xWid, LONG yHei, BOOL fPal, int cBitsPerPix, int cEnt, PALETTEENTRY * ppe, BYTE ** ppbBits, int * pcbRow); HBITMAP ImgCreateDibFromInfo(BITMAPINFO * pbmi, UINT wUsage, BYTE ** ppbBits, int * pcbRow);