以下为“CDDraw.cpp” /*------------------------------------------- | CDDraw.cpp | CDDraw类的成员的源代码 | 版权所有 mochsh, 2004 ---------------------------------------------*/ #include"CDDraw.h"
typedef struct _DISPLAYMODE { DDSURFACEDESC2 * pddsdMode; DWORD dwNumMode; }DISPLAYMODE;
DISPLAYMODE dmModes;
static HRESULT WINAPI ModeEnumRecord( DDSURFACEDESC2 * pNewMode, VOID * pRecordInfo ); static BOOL WINAPI DDisplayEnumerate( GUID * pGUID, LPSTR , LPSTR , LPVOID , HMONITOR ); /**************************************** * 函数名: CDDraw(...) * 功能: 构造函数 * 版权所有 mochsh, 2004 *****************************************/ CDDraw::CDDraw() { //初始化变量 hWnd = NULL; bFullScr = TRUE; ScreenW = 640; ScreenH = 480; ScreenC = 16; lpDD = NULL; lpDDSPrimary = NULL; lpDDSBack = NULL; }
/**************************************** * 函数名: ~CDDraw() * 功能: 析构函数 * 版权所有 mochsh, 2003 *****************************************/ CDDraw::~CDDraw() { if(lpDD!=NULL){ if(lpDDSBack!=NULL){ lpDDSBack->Release(); lpDDSBack = NULL; } if(lpDDSPrimary!=NULL){ lpDDSPrimary->Release(); lpDDSPrimary = NULL; } lpDD->Release(); lpDD = NULL; } }
/************************************************** * 函数名: InitDDraw(...) * 功能: 初始化DDraw,并且创建主表面和翻转缓冲表面 * 版权所有 mochsh, 2003 ***************************************************/ BOOL CDDraw::InitDDraw(HWND hWd, BOOL bFScr, DWORD ScrW,DWORD ScrH, DWORD BitCount ) { //--------------------------按给出的条件初始化变量 hWnd=hWd; bFullScr=bFScr; if(bFScr){//全屏模式 if(ScrW <= 640) { ScreenW = 640; ScreenH = 480; } else if(ScrW <= 800){ ScreenW = 800; ScreenH = 600; } else if(ScrW > 800) { ScreenW = 1024; ScreenH = 768; } else {ScreenW=800; ScreenH = 600;} if(BitCount<=8) ScreenC = 8; else if(BitCount<=16)ScreenC = 16; else if(BitCount<=24)ScreenC = 24; else if(BitCount<=32)ScreenC = 32; else ScreenC=16;
//检查模式是否有效 CheckDisplayMode(); } else{//窗口模式 ScreenW=ScrW; ScreenH=ScrH; }
//--------------------------初始化DirectDraw环境 HRESULT ddrval; //创建DirectDraw对象 ddrval = DirectDrawCreateEx(NULL,(void **) &lpDD,IID_IDirectDraw7,NULL); if( FAILED(ddrval) ) { //创建DirectDraw对象出错时进到这里来 //在这里可以记录创建DirectDraw对象的出错信息 return FALSE; } //******全屏模式***********// if( bFullScr ){ //设置协作等级 ddrval = lpDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT ); if( FAILED( ddrval )){ //设置协作等级出错时进到这里来 //在这里可以记录设置协作等级的出错信息 return FALSE; }
//设置显示模式 ddrval = lpDD->SetDisplayMode( ScreenW,ScreenH,ScreenC,NULL,NULL); if( FAILED( ddrval ) ){ //设置显示模式出错时进到这里来 //在这里可以记录设置显示模式的出错信息 return FALSE; }
//创建主表面 DDSURFACEDESC2 ddsd; ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); if (ddrval!=DD_OK) { //创建主表面出错时进到这里来 //在这里可以记录创建主表面的出错信息 return FALSE; }
//创建后台缓冲表面 DDSCAPS2 ddscaps; ZeroMemory(&ddscaps,sizeof(ddscaps)); ddscaps.dwCaps=DDSCAPS_BACKBUFFER; ddrval=lpDDSPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack); if (ddrval!=DD_OK) { //获取后台缓冲表面出错时进到这里来 //在这里可以记录后台缓冲表面的出错信息 return FALSE; } return TRUE; } //******窗口模式***********// else{ //设置协作等级 ddrval=(HRESULT)lpDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
//创建主表面 DDSURFACEDESC2 ddsd; ZeroMemory( &ddsd, sizeof(ddsd) ); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; //创建主表面,并取得指向主表面的指针lpDDSPrimary ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); if( FAILED( ddrval )){ //创建主表面出错时进到这里来 //在这里可以记录创建主表面的出错信息 return FALSE; }
//使用裁剪器 UseClipper();
//创建后台缓冲表面 //:::::::ddsd前面已经声明 ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwWidth = ScreenW;//宽的分辨率 ddsd.dwHeight = ScreenH;//高的分辨率 //创建一后台缓冲表面 ddrval = lpDD->CreateSurface( &ddsd, &lpDDSBack, NULL ); if( FAILED( ddrval )){ //创建后台缓冲表面出错时进到这里来 //在这里可以记录创建后台缓冲表面的出错信息 return FALSE; } }
return TRUE; //--------------------------初始化DirectDraw环境完成 }
/************************************************** * 函数名: Flip(...) * 功能: 翻转表面==>显示 * 版权所有 mochsh, 2003 ***************************************************/ void CDDraw::Flip( LPRECT pRectWin ) { HRESULT ddrval=1;
if( lpDDSPrimary && lpDDSBack ) { //检查表面是否丢失 if (lpDDSPrimary->IsLost()==DDERR_SURFACELOST) lpDDSPrimary->Restore(); if (lpDDSBack->IsLost()==DDERR_SURFACELOST) lpDDSBack->Restore(); do{ if(bFullScr==1) ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); else ddrval = lpDDSPrimary->Blt( pRectWin,lpDDSBack,NULL,DDBLT_WAIT,NULL);
//翻转表面后的信息检测 if( ddrval == DD_OK ) break; else if( ddrval == DDERR_SURFACELOST ){ if( FAILED(lpDDSBack->Restore()) ) break; if( FAILED(lpDDSPrimary->Restore()) ) break; } else if( ddrval != DDERR_WASSTILLDRAWING ) break; }while( 1 ); } }
/********************************************** * 函数名: UseClipper(...) * 功能: 创建一个裁剪器,并将它附于主表面 * 版权所有 mochsh, 2003 ***********************************************/ HRESULT CDDraw::UseClipper( void ) { HRESULT ddrval; LPDIRECTDRAWCLIPPER lpClipper = NULL;
//创建一个剪裁器对象 ddrval = lpDD->CreateClipper(0, &lpClipper, NULL); if ( ddrval != DD_OK){ //调用CreateClipper创建剪裁器对象出错进到这来 //在这里可以记录出错信息 return ddrval; } //将裁剪器设置为hWnd指向的窗口的客户区的范围 ddrval = lpClipper->SetHWnd(0, hWnd); if ( ddrval != DD_OK){ //调用SetHWnd设置窗口句柄出错进到这来 //在这里可以记录出错信息 return ddrval; }
//将裁剪器附于主表面 ddrval = lpDDSPrimary->SetClipper(lpClipper); if ( ddrval != DD_OK){ //将裁剪器附于主表面出错进到这来 //在这里可以记录出错信息 return ddrval; }
//主表面已经自动增加了裁剪器的索引值,所以应将它释放 if( lpClipper != NULL ) { lpClipper -> Release(); lpClipper = NULL; }
return DD_OK; } /********************************************** * 函数名: LoadBMPSurface(...) * 功能: 将BitmapFile指定的位图 * 格式图像载入刚刚Surf指向的表面 * 版权所有 mochsh, 2003 ***********************************************/ BOOL CDDraw::LoadBMPSurface(LPDIRECTDRAWSURFACE7 &lpSurf, //要载入图像的表面指针 LPCSTR BitmapFile )//源图像的路径 { HDC hdcImage; HDC hdc; HBITMAP hbm; BITMAP bm; HRESULT ddrval;
if( lpSurf == NULL ) return FALSE; // 将位图作为文件来读取 hbm = (HBITMAP)LoadImage(NULL, BitmapFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if (hbm == NULL){ //载入图像失败时进到这里来 //在这里可以记录载入图像失败的信息 return FALSE; } //函数功能:创建一个与指定设备兼容的内存设备上下文环境(Device Context) //创建一个与应用程序的当前显示器兼容的内存设备上下文环境 hdcImage = CreateCompatibleDC(NULL); if (!hdcImage){ //创建设备上下文出错 return FALSE; } //选择位图对象到刚刚创建的内存设备上下文环境(DC) SelectObject(hdcImage, hbm);
//获取位图宽与高 GetObject(hbm, sizeof(bm), &bm);
//获取表面的宽与高 DDSURFACEDESC2 ddsd; ddsd.dwSize = sizeof(ddsd); lpSurf->GetSurfaceDesc(&ddsd); if( BitmapFile!=NULL ) { if ((ddrval = lpSurf->GetDC(&hdc)) == DD_OK) { //将源位图复制到表面,可以进行拉伸或收缩 StretchBlt( hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); lpSurf->ReleaseDC(hdc); } }
DeleteDC(hdcImage);
if( ddrval != DD_OK ) { //复制矩形块失败 return FALSE; }
return TRUE; }
/********************************************************** * 函数名: CreateBMPSurface(...) * 功能: 创建lpSurf指定的表面,并且将BitmapFile * 指定的位图格式图像载入刚刚创建的表面 * 参数说明: lpSurf : 要载入图像的表面指针 * W和H : 创建的表面的宽与高(为零表示和图像匹配) * BitmapFile : 源图像的路径 * MemoryFlag : 表面图像的存储方式 * 显存:DDSCAPS_VIDEOMEMORY * 系统内存:DDSCAPS_SYSTEMMEMORY * 注意: 当指定表面长宽时(W,H),表面的长宽可以不 * 等于指定图像的长宽 * 版权所有 mochsh, 2003 **************************************************/ BOOL CDDraw::CreateBMPSurface(LPDIRECTDRAWSURFACE7 &lpSurf, LONG W,LONG H, LPCSTR BitmapFile, DWORD MemoryFlag) { HBITMAP hbm; BITMAP bm; BOOL bResult;
// 将位图作为文件来读取 hbm = (HBITMAP)LoadImage(NULL, BitmapFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if (hbm == NULL){ //载入图像失败时进到这里来 //在这里可以记录载入图像失败的信息 return FALSE; }
//求出要创建的表面的宽与高 GetObject(hbm, sizeof(bm), &bm); W = W == 0 ? bm.bmWidth : W; H = H == 0 ? bm.bmHeight : H;
//根据上面的宽与高创建一屏外表面 bResult = CreateNULLSurface( lpSurf, W, H, DDSCAPS_SYSTEMMEMORY );
if( bResult != TRUE ) { //创建表面出错时进到这里来 //在这里可以记录创建表面的出错信息 } else if( BitmapFile!=NULL ) { //将BitmapFile指向的图像文件载入Surf表面 bResult = LoadBMPSurface( lpSurf, BitmapFile ); }
DeleteObject(hbm);
return bResult; }
/********************************************************* * 函数名: CreateNULLSurface(...) * 功能: 创建Surf指定的表面,是空表面 * 参数说明: lpSurf : 要创建的表面指针 * W和H : 创建的表面的宽与高 * MemoryFlag : 表面图像的存储方式 * 显存:DDSCAPS_VIDEOMEMORY * 系统内存:DDSCAPS_SYSTEMMEMORY * 版权所有 mochsh, 2003 **********************************************************/ BOOL CDDraw::CreateNULLSurface(LPDIRECTDRAWSURFACE7 &lpSurf, LONG W,LONG H, DWORD MemoryFlag) { DDSURFACEDESC2 ddsd; HRESULT ddrval;
//定义屏外表面要求 ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | MemoryFlag; ddsd.dwWidth = W; ddsd.dwHeight = H;
//创建一屏外表面 ddrval = lpDD->CreateSurface( &ddsd, &lpSurf, NULL ); if( ddrval != DD_OK ) return FALSE; return TRUE; }
[此贴子已经被作者于2005-3-18 20:23:45编辑过]