📄 tearing ddraw.cpp
字号:
// CChildView DirectDraw Auxiliary Functions.
//
#include "stdafx.h"
#include "Tearing Demo.h"
#include "ChildView.h"
#include "DDExcept.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HRESULT CChildView::CreateSecondarySurface(int cx, int cy, IDirectDrawSurface** ppDDS)
{
// Check our pointer
ASSERT(ppDDS != NULL);
if ( ppDDS == NULL ) {
// NULL input pointer...
return E_POINTER;
} // if
// Complete the surface description structure
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = cx;
ddsd.dwHeight = cy;
// Create the surface
CComPtr<IDirectDrawSurface> pIDDSTemp;
HRESULT hr = m_pIDirectDraw->CreateSurface(&ddsd,&pIDDSTemp,NULL);
if ( FAILED(hr) ) {
// Some error
*ppDDS = NULL;
return hr;
} // if
// Return the surface
*ppDDS = pIDDSTemp;
(*ppDDS)->AddRef();
return hr;
}
HRESULT CChildView::LoadDDBitmap(UINT nID, IDirectDrawSurface** ppDDS)
{
// Check our pointer
ASSERT(ppDDS != NULL);
if ( ppDDS == NULL ) {
// NULL input pointer...
return E_POINTER;
} // if
// Pull the bitmap from resources
CBitmap bmImage;
VERIFY(bmImage.LoadBitmap(nID));
// Determine its size
BITMAP bm;
bmImage.GetBitmap(&bm);
// Create a surface to contain the bitmap
CComPtr<IDirectDrawSurface> pIDDSTemp;
HRESULT hr = CreateSecondarySurface(bm.bmWidth,bm.bmHeight,&pIDDSTemp);
if ( FAILED(hr) ) {
// Some error
*ppDDS = NULL;
return hr;
} // if
// Copy the bitmap to the surface
hr = CopyDDBitmap(&bmImage,pIDDSTemp);
if ( FAILED(hr) ) {
// Some error
*ppDDS = NULL;
return hr;
} // if
// Return the surface
*ppDDS = pIDDSTemp;
(*ppDDS)->AddRef();
return hr;
}
HRESULT CChildView::CopyDDBitmap(CBitmap* pbmImage, IDirectDrawSurface* pDDS)
{
// Restore the surface
pDDS->Restore();
// Create a memory DC to contain the bitmap
CDC dcImage;
dcImage.CreateCompatibleDC(NULL);
CBitmap* pBitmapMono = (CBitmap*)dcImage.SelectObject(pbmImage);
// Determine its size
BITMAP bm;
pbmImage->GetBitmap(&bm);
// Complete the surface description
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pDDS->GetSurfaceDesc(&ddsd);
// Copy in the bitmap
HDC hdc = NULL;
HRESULT hr = pDDS->GetDC(&hdc);
if ( SUCCEEDED(hr) ) {
::StretchBlt(hdc,0,0,ddsd.dwWidth,ddsd.dwHeight,dcImage,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
pDDS->ReleaseDC(hdc);
} // if
// Clean up
dcImage.SelectObject(pBitmapMono);
return hr;
}
HRESULT CChildView::LoadDDPalette(UINT idBitmap, IDirectDrawPalette** ppDDP)
{
// Create a standard 332 palette as the default
PALETTEENTRY ape[256];
for ( int i = 0; i < 256; i++ ) {
ape[i].peRed = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
ape[i].peBlue = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
ape[i].peFlags = (BYTE)0;
} // for
// Locate the bitmap resource. Note this assumes the
// bitmap is stored as a program resource (and not as
// a disk file).
HRSRC hBitmap = NULL;
if ( (hBitmap = ::FindResource(NULL,MAKEINTRESOURCE(idBitmap),RT_BITMAP))) {
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)::LockResource(::LoadResource(NULL,hBitmap));
if ( lpbi != NULL ) {
// Locate the color information, which is stored past
// the BITMAPINFOHEADER.
RGBQUAD* prgb = (RGBQUAD*)((BYTE*)lpbi + lpbi->biSize);
// Determine how many palettized colors we're
// talking about.
int iNumColors;
if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
iNumColors = 0;
else if (lpbi->biBitCount > 8)
iNumColors = 0;
else if (lpbi->biClrUsed == 0)
iNumColors = 1 << lpbi->biBitCount;
else
iNumColors = lpbi->biClrUsed;
// Pull the color information
for( i = 0; i < iNumColors; i++ ) {
ape[i].peRed = prgb[i].rgbRed;
ape[i].peGreen = prgb[i].rgbGreen;
ape[i].peBlue = prgb[i].rgbBlue;
ape[i].peFlags = 0;
} // for
} // if
} // if
// Create a new DirectDraw palette
CComPtr<IDirectDrawPalette> pIDDPTemp;
HRESULT hr = m_pIDirectDraw->CreatePalette(DDPCAPS_8BIT,ape,&pIDDPTemp,NULL);
if ( FAILED(hr) ) {
// Some error
*ppDDP = NULL;
return hr;
} // if
// Return the palette
*ppDDP = pIDDPTemp;
(*ppDDP)->AddRef();
return hr;
}
HRESULT CChildView::Blt(int iCurX)
{
// For demo purposes, I hard-coded the bitmap size.
HRESULT hr = S_OK;
try {
// Clear the secondary surface
DDBLTFX ddbltfx;
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = 0; // black
hr = m_lpDDSSecondary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx);
if ( FAILED( hr ) ) {
// Some error
throw new CDDException(TRUE,"Error clearing secondary surface");
} // if
// Copy the can to the secondary surface
hr = m_lpDDSSecondary->Blt(CRect(iCurX,CANY,iCurX+CANWIDTH,CANY+CANHEIGHT),m_lpDDSCan.p,NULL,
DDBLT_WAIT,NULL);
if ( FAILED( hr ) ) {
// Some error
throw new CDDException(TRUE,"Error bltting can to secondary surface");
} // if
if ( m_bFlip ) {
// Flip the page...
hr = m_lpDDSPrimary->Flip(NULL,DDFLIP_WAIT);
if ( FAILED( hr ) ) {
// Some error
throw new CDDException(TRUE,"Error flipping page");
} // if
} // if
else {
// Copy the secondary surface to the primary
hr = m_lpDDSPrimary->Blt(CRect(0,0,640,480),m_lpDDSSecondary.p,NULL,
DDBLT_WAIT,NULL);
if ( FAILED( hr ) ) {
// Some error
throw new CDDException(TRUE,"Error secondary to primary surface");
} // if
} // else
} // try
catch (CDDException* dde) {
// Intercept our special exception and
// tell user of error
dde->ReportError(MB_OK | MB_ICONERROR,hr);
// Delete the exception
dde->Delete();
} // catch
catch (...) {
// Do nothing
/* nothing */;
} // catch
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -