📄 tddrawbase.cpp
字号:
//---------------------------------------------------------------------------
#include "TDDrawBase.h"
#include <tchar.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "DDRAW.LIB"
//---------------------------------------------------------------------------
TDDrawSurface::TDDrawSurface(TDDrawDisplay *lpddd)
{
_DDrawDisplay = lpddd;
_DDrawSurface = NULL;
_bColorKeyed = false;
_dwColorKey = 0;
_dwColorKeyFlags = DDCKEY_SRCBLT;
}
//---------------------------------------------------------------------------
TDDrawSurface::~TDDrawSurface()
{
Destroy();
}
//---------------------------------------------------------------------------
HRESULT TDDrawSurface::Create(LPDIRECTDRAWSURFACE7 pdds)
{
Destroy();
_DDrawSurface = pdds;
if(_DDrawSurface)
{
_DDrawSurface->AddRef();
//Get the DDSURFACEDESC structure for this surface
_SurfaceDesc.dwSize = sizeof(_SurfaceDesc);
_DDrawSurface->GetSurfaceDesc( &_SurfaceDesc );
}
return S_OK;
}
//---------------------------------------------------------------------------
HRESULT TDDrawSurface::Create(DDSURFACEDESC2* pddsd)
{
Destroy();
HRESULT hr;
if(FAILED(hr=_DDrawDisplay->DirectDraw->CreateSurface(pddsd,&_DDrawSurface,NULL)))
return hr;
_SurfaceDesc.dwSize = sizeof(_SurfaceDesc); //Prepare the DDSURFACEDESC structure
_DDrawSurface->GetSurfaceDesc(&_SurfaceDesc); //Get the DDSURFACEDESC structure for this surface
return S_OK;
}
//---------------------------------------------------------------------------
HRESULT TDDrawSurface::Create(int dwWidth, int dwHeight)
{
Destroy();
if(!_DDrawDisplay->DirectDraw)
return E_POINTER;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if(FAILED(hr=Create(&ddsd)))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Create a Surface from a bitmap resource or bitmap file. Use MAKEINTRESOURCE() to pass a constant into strBMP.
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::CreateSurfaceFromBitmap(TCHAR* strBMP, DWORD dwWidth, DWORD dwHeight )
{
HRESULT hr;
HBITMAP hBMP;
BITMAP bmp;
if((!_DDrawDisplay->DirectDraw) || (!strBMP))
return E_INVALIDARG;
//Try to load the bitmap as a resource, if that fails, try it as a file
if((hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),strBMP,IMAGE_BITMAP,dwWidth,dwHeight,LR_CREATEDIBSECTION))==NULL)
{
if((hBMP=(HBITMAP)LoadImage(NULL,strBMP,IMAGE_BITMAP,dwWidth,dwHeight,LR_LOADFROMFILE|LR_CREATEDIBSECTION))==NULL)
return E_FAIL;
}
GetObject(hBMP, sizeof(bmp), &bmp ); //Get size of the bitmap
if(FAILED(hr=Create(bmp.bmWidth,bmp.bmHeight)))
return hr;
hr = DrawBitmap(hBMP,0,0,0,0); //Draw the bitmap on this surface
DeleteObject(hBMP);
if(FAILED(hr))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Creates a DirectDrawSurface from a text string using hFont or the default GDI font if hFont is NULL.
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::CreateSurfaceFromText( HFONT hFont, TCHAR* strText, COLORREF crBackground, COLORREF crForeground)
{
HRESULT hr;
SIZE sizeText;
if((!_DDrawDisplay->DirectDraw) || (!strText))
return E_INVALIDARG;
HDC hDC = GetDC(NULL);
if(hFont)
SelectObject(hDC, hFont);
GetTextExtentPoint32(hDC, strText, _tcslen(strText), &sizeText);
ReleaseDC(NULL, hDC);
if(FAILED(hr=Create(sizeText.cx, sizeText.cy)))
return hr;
if(FAILED(hr=DrawText(hFont, strText, 0, 0, crBackground, crForeground)))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Draws a bitmap over an entire DirectDrawSurface, stretching the bitmap if nessasary
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::DrawBitmap(HBITMAP hBMP, DWORD dwBMPOriginX, DWORD dwBMPOriginY, DWORD dwBMPWidth, DWORD dwBMPHeight)
{
BITMAP bmp;
DDSURFACEDESC2 ddsd;
HRESULT hr;
if((!hBMP) || (!_DDrawSurface))
return E_INVALIDARG;
if(FAILED(hr=_DDrawSurface->Restore())) //Make sure this surface is restored.
return hr;
ddsd.dwSize = sizeof(ddsd);
_DDrawSurface->GetSurfaceDesc(&ddsd); //Get the surface.description
if(ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC)
return E_NOTIMPL;
HDC hDCImage = CreateCompatibleDC(NULL); //Select bitmap into a memoryDC so we can use it.
if(!hDCImage)
return E_FAIL;
SelectObject(hDCImage, hBMP);
GetObject(hBMP, sizeof(bmp), &bmp); // Get size of the bitmap
dwBMPWidth = ( dwBMPWidth == 0 ) ? bmp.bmWidth : dwBMPWidth; //Use the passed size, unless zero
dwBMPHeight = ( dwBMPHeight == 0 ) ? bmp.bmHeight : dwBMPHeight; //Use the passed size, unless zero
HDC hDC;
if(!FAILED(hr=_DDrawSurface->GetDC(&hDC)))
{
StretchBlt(hDC,0,0,ddsd.dwWidth, ddsd.dwHeight,hDCImage, dwBMPOriginX, dwBMPOriginY,dwBMPWidth,dwBMPHeight,SRCCOPY);
hr = _DDrawSurface->ReleaseDC(hDC);
}
DeleteDC(hDCImage);
if(FAILED(hr))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Draws a text string on a DirectDraw surface using hFont or the default GDI font if hFont is NULL.
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::DrawText(HFONT hFont, TCHAR* strText, DWORD dwOriginX, DWORD dwOriginY, COLORREF crBackground, COLORREF crForeground)
{
HDC hDC = NULL;
HRESULT hr;
if((!_DDrawSurface) || (!strText))
return E_INVALIDARG;
if(FAILED(hr = _DDrawSurface->Restore())) //Make sure this surface is restored.
return hr;
if(FAILED(hr = _DDrawSurface->GetDC(&hDC)))
return hr;
SetBkColor(hDC, crBackground); //Set the background and foreground color
SetTextColor(hDC, crForeground);
if(hFont)
SelectObject( hDC, hFont );
TextOut(hDC, dwOriginX, dwOriginY, strText, _tcslen(strText)); //Use GDI to draw the text on the surface
if(FAILED(hr = _DDrawSurface->ReleaseDC(hDC)))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Load a bitmap from a file or resource into a DirectDraw surface. normaly used to re-load a surface after a restore.
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::DrawBitmap(TCHAR* strBMP, DWORD dwWidth, DWORD dwHeight)
{
HBITMAP hBMP;
HRESULT hr;
if((!_DDrawSurface) || (!strBMP))
return E_INVALIDARG;
//Try to load the bitmap as a resource, if that fails, try it as a file
if((hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL), strBMP, IMAGE_BITMAP, dwWidth, dwHeight, LR_CREATEDIBSECTION))==NULL)
{
if((hBMP=(HBITMAP)LoadImage(NULL,strBMP,IMAGE_BITMAP,dwWidth,dwHeight,LR_LOADFROMFILE|LR_CREATEDIBSECTION))==NULL)
return E_FAIL;
}
hr=DrawBitmap(hBMP,0,0,0,0); //Draw the bitmap on this surface
DeleteObject(hBMP);
if(FAILED(hr))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::SetColorKey(DWORD dwKeyFlags, DWORD dwColorKey)
{
if(!_DDrawSurface)
return E_POINTER;
_bColorKeyed = true;
_dwColorKey = dwColorKey;
_dwColorKeyFlags = dwKeyFlags;
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = ConvertGDIColor(_dwColorKey);
ddck.dwColorSpaceHighValue = ConvertGDIColor(_dwColorKey);
return _DDrawSurface->SetColorKey(_dwColorKeyFlags, &ddck);
}
//-----------------------------------------------------------------------------
// Desc: Converts a GDI color (0x00bbggrr) into the equivalent color on a DirectDrawSurface using its pixel format.
//-----------------------------------------------------------------------------
DWORD TDDrawSurface::ConvertGDIColor( COLORREF dwGDIColor )
{
if(!_DDrawSurface)
return 0x00000000;
DDSURFACEDESC2 ddsd;
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
HRESULT hr;
if(dwGDIColor != CLR_INVALID) //Use GDI SetPixel to color match for us
if(_DDrawSurface->GetDC(&hdc)==DD_OK)
{
rgbT = GetPixel(hdc,0,0); //Save current pixel value
SetPixel(hdc, 0, 0, dwGDIColor); //Set our value
_DDrawSurface->ReleaseDC(hdc);
}
ddsd.dwSize = sizeof(ddsd); //Now lock the surface so we can read back the converted color
hr=_DDrawSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
if(hr==DD_OK)
{
dw = *(DWORD*)ddsd.lpSurface;
if(ddsd.ddpfPixelFormat.dwRGBBitCount < 32) //Mask it to bpp
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;
_DDrawSurface->Unlock(NULL);
}
if(dwGDIColor != CLR_INVALID) //Now put the color that was there back.
if(_DDrawSurface->GetDC(&hdc)==DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
_DDrawSurface->ReleaseDC(hdc);
}
return dw;
}
//-----------------------------------------------------------------------------
// Name: TDDrawSurface::GetBitMaskInfo()
// Desc: Returns the number of bits and the shift in the bit mask
//-----------------------------------------------------------------------------
HRESULT TDDrawSurface::GetBitMaskInfo(DWORD dwBitMask, DWORD* pdwShift, DWORD* pdwBits)
{
DWORD dwShift = 0;
DWORD dwBits = 0;
if((!pdwShift) || (!pdwBits))
return E_INVALIDARG;
if(dwBitMask)
{
while((dwBitMask & 1) == 0)
{
dwShift++;
dwBitMask >>= 1;
}
}
while((dwBitMask & 1) != 0)
{
dwBits++;
dwBitMask >>= 1;
}
*pdwShift = dwShift;
*pdwBits = dwBits;
return S_OK;
}
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TDDrawDisplay::TDDrawDisplay(HWND hWnd)
{
_hWindow = hWnd;
_ScrWidth = 0;
_ScrHeight = 0;
_DirectDraw = NULL;
_FrontBuffer = NULL;
_BackBuffer = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -