基于窗口的DirectDraw编程

http://blog.csdn.net/lanyzh0909/article/details/6363378


DirectDraw在window下支持全屏模式(也叫独占模式)和窗口模式。DirectDraw基于全屏模式的编程例子在%_WINCEROOT%PUBLIC/DIRECTX/SDK/SAMPLES/DDRAW下有,读者可以去自己去查看,但是基于窗口下的DirectDraw编程例子确是很找到。下面我一步步介绍一下基于窗口的DirectDraw编程。
1、既然是基于窗口,首先我们就必须先创建一个窗口,先调用RegisterClass注册窗口类,再调用CreateWindowsEx创建一个窗口,用m_hAttach保存窗口句柄。

2、调用DirectDrawCreate创建一个DirectDraw对象

[cpp]  view plain copy
  1. //创建DirectDraw对象  
  2. hRet = DirectDrawCreate(NULL, &m_pDD, NULL);  
  3. if (hRet != DD_OK)  
  4. {  
  5.   goto Err;  
  6. }  

3、设置协作级别,通过m_pDD调用SetCooperativeLevel接口,将俩个参数设置为m_hAttach和DDSCL_NORMAL

[cpp]  view plain copy
  1. //设置协作级别  
  2.  hRet = m_pDD->SetCooperativeLevel(m_hAttach, DDSCL_NORMAL);  
  3. if (hRet != DD_OK)  
  4. {  
  5.     goto Err;  
  6. }  

4、创建主屏页和离屏页,主屏页就相当与显示器,当你往主屏上绘制什么东西显示器上将显示相应的东西。离屏也就相当于内存DC,我们首先在离屏页上绘制好图形,然后通过Blt到主页上去。

[cpp]  view plain copy
  1. DDSURFACEDESC ddsd;  
  2. memset(&ddsd, 0, sizeof(ddsd));  
  3. ddsd.dwSize = sizeof(ddsd);  
  4. ddsd.dwFlags = DDSD_CAPS;  
  5. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  
  6.   
  7. //创建主页  
  8. hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);  
  9. if (hRet != DD_OK)  
  10. {  
  11.     goto Err;  
  12. }  
  13. //创建离屏页时,必须指定页面的长、宽  
  14. RECT rcClient ={0};  
  15. GetClientRect(m_hAttach,&rcClient);  
  16. ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  17. ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  18. ddsd.dwHeight = rcClient.bottom - rcClient.top;  
  19. ddsd.dwWidth = rcClient.right - rcClient.left;  
  20.   
  21. hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSBack, NULL);  
  22. if (hRet != DD_OK)  
  23. {  
  24.     goto Err;  
  25. }  

5、创建裁剪器,裁剪器的作用就是将显示的内容限制在窗口区域内,超出的将不能显示。

 

[cpp]  view plain copy
  1. //创建裁剪器  
  2. hRet = m_pDD->CreateClipper(0, &m_lpddClipper, NULL);  
  3.  if (hRet != DD_OK)  
  4. {  
  5.      goto Err;  
  6. }  
  7. //将裁剪器和窗口关联  
  8. m_lpddClipper->SetHWnd(0,m_hAttach);  
  9.   
  10. //将裁剪器与图面相关联  
  11. m_pDDSPrimary->SetClipper(m_lpddClipper);  

6、完成上面步骤后,我们就可以开始在绘图了。在处理WM_PAINT消息时调用OnPaint()
现在可以编译和运行程序了,能看到Test.bmp已经显示在窗口的客户区域中。

[cpp]  view plain copy
  1. void OnPaint()  
  2. {  
  3.     HRESULT hRet;  
  4.     HBITMAP hbm;  
  5.     BITMAP bmInfo;  
  6.     DDSURFACEDESC ddsd;  
  7.     LPDIRECTDRAWSURFACE pDDSBitmap;  
  8.     DDBLTFX  ddbltfx;  
  9.   
  10.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  11.     ddbltfx.dwSize = sizeof(ddbltfx);  
  12.     ddbltfx.dwROP = SRCCOPY;  
  13.     ddbltfx.ddckSrcColorkey;  
  14.   
  15.     // Load our bitmap resource.  
  16.     //hbm = DDGetBitmapHandle(GetModuleHandle(NULL),pszFileName);  
  17.     hbm = SHLoadDIBitmap(TEXT("Test.bmp"));  
  18.     if (hbm == NULL)  
  19.     {  
  20.         return;  
  21.     }  
  22.   
  23.     GetObject(hbm,sizeof(bmInfo),&bmInfo);  
  24.   
  25.     memset(&ddsd, 0, sizeof(ddsd));  
  26.     ddsd.dwSize = sizeof(ddsd);  
  27.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  28.     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  29.     ddsd.dwHeight = bmInfo.bmHeight;  
  30.     ddsd.dwWidth  = bmInfo.bmWidth;  
  31.   
  32.     //创建位图离屏页  
  33.     hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);  
  34.     if (hRet != DD_OK)  
  35.     {  
  36.         return;  
  37.     }  
  38.   
  39.     DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);  
  40.   
  41.   
  42.     if(pcol != NULL)  
  43.     {  
  44.         DDSetColorKey(pDDSBitmap,*pcol);  
  45.         m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);  
  46.     }  
  47.     else  
  48.     {  
  49.         m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);  
  50.     }  
  51.   
  52.     ReleaseRes(pDDSBitmap);  
  53.     if(FAILED(m_pDDSPrimary->IsLost()))  
  54.     {  
  55.         //在其它程序改变显示模式导致页的丢失时,要对页面的恢复  
  56.         if(!RestoreResource())  
  57.         {  
  58.             return;  
  59.         }  
  60.     }  
  61.     //注意,这里应该将窗口坐标转化为屏幕坐标  
  62.     RECT rcClient = {0};  
  63.     ChangeClientToSreen(rcClient);  
  64.     //调用以下这句就能显示在屏幕上  
  65.     m_pDDSPrimary->Blt(&rcClient,m_pDDSBack,NULL,DDBLT_ROP ,&ddbltfx);  
  66.   
  67.     return;  
  68. }  

下面是我自己封装的一个DirectDraw类,

//DirectDraw.h

[cpp]  view plain copy
  1. #pragma once  
  2. #include <windows.h>  
  3. #include <Ddraw.h>  
  4. #include "D://OS//WINCE600//PUBLIC//DIRECTX//SDK//SAMPLES//DDRAW//INCLUDE//ddutil.h"  
  5.   
  6. #define ReleaseRes(x) if(x != NULL){ x->Release(); x = NULL;}  
  7.   
  8. class CDirectDraw  
  9. {  
  10. public:  
  11.     /****************************************************** 
  12.     *函数介绍:初始化类成员变量 
  13.     *入口参数:hWnd,隶属于的窗口句柄 
  14.                dwMode,模式 
  15.     *出口参数:无 
  16.     *返回值: TRUE - 成功, FALSE - 失败 
  17.     ******************************************************/  
  18.     BOOL Init(HWND hWnd,DWORD dwMode);  
  19.   
  20.     /****************************************************** 
  21.     *函数介绍:将指定的图片加载到后台缓冲页中 
  22.     *入口参数:prcDes,   目标显示图片区域 
  23.                pFileName,显示图片名称 
  24.                prcSrc,    显示图片中区域 
  25.                pcolTra,   透明颜色 
  26.     *出口参数:无 
  27.     *返回值: TRUE - 成功, FALSE - 失败 
  28.     ******************************************************/  
  29.     BOOL DrawImageToBackSurface(LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);  
  30.   
  31.     /****************************************************** 
  32.     *函数介绍:将文本绘制到后台缓冲页中 
  33.     *入口参数:prcDes,   目标显示文本区域 
  34.                pszText,  显示文本内容 
  35.                pfName,    字体名称 
  36.                ifSize,   字体大小 
  37.                uFormat,   对齐方式 
  38.                pcol,     字体颜色指针  
  39.     *出口参数:无 
  40.     *返回值: TRUE - 成功, FALSE - 失败 
  41.     ******************************************************/  
  42.     BOOL DrawTextToBackSuface(LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat = DT_LEFT,LPCOLORREF pcol = NULL);  
  43.   
  44.     /****************************************************** 
  45.     *函数介绍:创建一个离屏页 
  46.     *入口参数: 
  47.                iWidth, 宽度 
  48.                iHeight,高度 
  49.                 
  50.     *出口参数:pDDS,保存离屏页的指针 
  51.     *返回值: TRUE - 成功, FALSE - 失败 
  52.     ******************************************************/  
  53.     BOOL CreateOffScreenSuface(LPDIRECTDRAWSURFACE *pDDS, int iWidth, int iHeight);  
  54.   
  55.     /****************************************************** 
  56.     *函数介绍:图片加到指定的页中 
  57.     *入口参数:pDDS,     页指针 
  58.                prcDes,   目标显示图片区域 
  59.                pFileName,显示图片名称 
  60.                prcSrc,    显示图片中区域 
  61.                pcolTra,   透明颜色 
  62.                 
  63.     *出口参数:无 
  64.     *返回值: TRUE - 成功, FALSE - 失败 
  65.     ******************************************************/  
  66.     BOOL DrawImageToSurface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);  
  67.   
  68.     /****************************************************** 
  69.     *函数介绍:将文本绘制到指定的页中 
  70.     *入口参数:pDDS,     指定的页指针 
  71.                prcDes,   目标显示文本区域 
  72.                pszText,  显示文本内容 
  73.                pfName,    字体名称 
  74.                ifSize,   字体大小 
  75.                uFormat,   对齐方式 
  76.                pcol,     字体颜色指针  
  77.     *出口参数:无 
  78.     *返回值: TRUE - 成功, FALSE - 失败 
  79.     ******************************************************/  
  80.     BOOL DrawTextToSuface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat = DT_LEFT,LPCOLORREF pcol = NULL);  
  81.       
  82.     /****************************************************** 
  83.     *函数介绍:将指定的页中的内容绘制到后台缓冲页 
  84.     *入口参数: 
  85.                prcDes,   目标显示图片区域 
  86.                pDDS,     页指针 
  87.                prcSrc,    显示图片中区域 
  88.                pcolTra,   透明颜色 
  89.     *出口参数:无 
  90.     *返回值:  TRUE - 成功, FALSE - 失败 
  91.     ******************************************************/  
  92.     BOOL BltBackSurface(LPRECT prcDes,LPDIRECTDRAWSURFACE pDDS,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);  
  93.   
  94.     /****************************************************** 
  95.     *函数介绍:拷贝后台页到指定的页中 
  96.     *入口参数: 
  97.                pDDS,   目标页指针 
  98.                prcDes, 目标页区域 
  99.                prcSrc,  源页区域 
  100.     *出口参数:无 
  101.     *返回值:  TRUE - 成功, FALSE - 失败 
  102.     ******************************************************/  
  103.     BOOL CopyBackSurface(LPDIRECTDRAWSURFACE pDDS, LPRECT prcDes, LPRECT prcSrc);  
  104.   
  105.     /****************************************************** 
  106.     *函数介绍:获取后台页指针 
  107.     *入口参数:无 
  108.     *出口参数:无 
  109.     *返回值:  成功 - 返回后台页指针,失败 - 返回NULL 
  110.     ******************************************************/  
  111.     LPDIRECTDRAWSURFACE GetBufferSurface();  
  112.   
  113.     /****************************************************** 
  114.     *函数介绍:获取主页指针 
  115.     *入口参数:无 
  116.     *出口参数:无 
  117.     *返回值:  成功 - 返回主页指针,失败 - 返回NULL 
  118.     ******************************************************/  
  119.     LPDIRECTDRAWSURFACE GetPrimarySurface();  
  120.   
  121.     /****************************************************** 
  122.     *函数介绍:更新主页 
  123.     *入口参数:无 
  124.     *出口参数:无 
  125.     *返回值:  无 
  126.     ******************************************************/  
  127.     void UpDatePrimarySurface();  
  128.   
  129. public:  
  130.     CDirectDraw();  
  131.     virtual ~CDirectDraw();  
  132.   
  133. protected:  
  134.     /****************************************************** 
  135.     *函数介绍:释放资源 
  136.     *入口参数:无 
  137.     *出口参数:无 
  138.     *返回值:  无 
  139.     ******************************************************/  
  140.     void ReleaseResource();  
  141.   
  142.     /****************************************************** 
  143.     *函数介绍:恢复资源 
  144.     *入口参数:无 
  145.     *出口参数:无 
  146.     *返回值:  无 
  147.     ******************************************************/  
  148.     HRESULT RestoreResource();  
  149.   
  150.     /****************************************************** 
  151.     *函数介绍:将客户坐标转换为屏幕坐标 
  152.     *入口参数:rc,客户坐标区域 
  153.     *出口参数:rc,屏幕坐标区域 
  154.     *返回值:  无 
  155.     ******************************************************/  
  156.     void ChangeClientToSreen(RECT &rc);  
  157.   
  158.     /************************************************************************/  
  159.     /* 
  160.     函数名: CreateFont 
  161.     描  述: 获取字体句柄 
  162.     参  数: TCHAR*    : [in] 字体类型 
  163.     UINT8   : [in] 字体大小 
  164.     返  回: HFONT 
  165.     */  
  166.     /************************************************************************/  
  167.     HFONT CreateFont(LPCTSTR pszFaceName, UINT8 nSize, BOOL bBold, BOOL bAntiAliasing);  
  168. private:  
  169.     LPDIRECTDRAW                m_pDD ;       // DirectDraw object  
  170.     LPDIRECTDRAWSURFACE         m_pDDSPrimary;// DirectDraw primary surface  
  171.     LPDIRECTDRAWSURFACE         m_pDDSBack;   // DirectDraw back surface  
  172.     LPDIRECTDRAWCLIPPER         m_lpddClipper;// DirectDraw clipper  
  173.     HWND m_hAttach;  
  174. };  

//DirectDraw.cpp

[cpp]  view plain copy
  1. #include "DirectDraw.h"  
  2.   
  3. #pragma comment(lib,"ddraw.lib")  
  4. #pragma comment(lib,"D://OS//WINCE600//PUBLIC//DIRECTX//SDK//LIB//ARMV4I//RETAIL//ddutil.lib")  
  5.   
  6.   
  7.   
  8. CDirectDraw::CDirectDraw():  
  9. m_pDD(NULL),  
  10. m_pDDSPrimary(NULL),  
  11. m_pDDSBack(NULL),  
  12. m_lpddClipper(NULL),  
  13. m_hAttach(NULL)  
  14. {  
  15.       
  16. }  
  17.   
  18. CDirectDraw::~CDirectDraw()  
  19. {  
  20.     ReleaseResource();  
  21. }  
  22.   
  23. BOOL CDirectDraw::Init(HWND hWnd,DWORD dwMode)  
  24. {  
  25.     HRESULT hRet;   
  26.     DDSURFACEDESC ddsd;  
  27.     RECT rcClient ={0};  
  28.   
  29.     //保存窗口句柄  
  30.     m_hAttach = hWnd;  
  31.   
  32.     //创建DirectDraw对象  
  33.     hRet = DirectDrawCreate(NULL, &m_pDD, NULL);  
  34.     if (hRet != DD_OK)  
  35.     {  
  36.         goto Err;  
  37.     }  
  38.     //设置协作级别  
  39.     hRet = m_pDD->SetCooperativeLevel(m_hAttach,dwMode );  
  40.     if (hRet != DD_OK)  
  41.     {  
  42.         goto Err;  
  43.     }  
  44.   
  45.     memset(&ddsd, 0, sizeof(ddsd));  
  46.     ddsd.dwSize = sizeof(ddsd);  
  47.     ddsd.dwFlags = DDSD_CAPS;  
  48.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  
  49.       
  50.     //创建主页  
  51.      hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);  
  52.     if (hRet != DD_OK)  
  53.     {  
  54.         goto Err;  
  55.     }  
  56.       
  57.     GetClientRect(m_hAttach,&rcClient);  
  58.   
  59.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  60.     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  61.     ddsd.dwHeight = rcClient.bottom - rcClient.top;  
  62.     ddsd.dwWidth = rcClient.right - rcClient.left;  
  63.   
  64.     //创建离屏页  
  65.     hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSBack, NULL);  
  66.     if (hRet != DD_OK)  
  67.     {  
  68.         goto Err;  
  69.     }  
  70.   
  71.     //创建裁剪器  
  72.     hRet = m_pDD->CreateClipper(0, &m_lpddClipper, NULL);  
  73.     if (hRet != DD_OK)  
  74.     {  
  75.         goto Err;  
  76.     }  
  77.     //将裁剪器和窗口关联  
  78.     m_lpddClipper->SetHWnd(0,m_hAttach);  
  79.   
  80.     //将裁剪器与图面相关联  
  81.     m_pDDSPrimary->SetClipper(m_lpddClipper);  
  82.   
  83.     return TRUE;  
  84.   
  85. Err:  //错误处理,释放内存  
  86.     m_hAttach = NULL;  
  87.     ReleaseResource();  
  88.     return FALSE;  
  89.   
  90.           
  91. }  
  92.   
  93. BOOL CDirectDraw::DrawImageToBackSurface(LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcol)  
  94. {  
  95.     HRESULT hRet;  
  96.     HBITMAP hbm;  
  97.     BITMAP bmInfo;  
  98.     DDSURFACEDESC ddsd;  
  99.     LPDIRECTDRAWSURFACE pDDSBitmap;  
  100.     DDBLTFX  ddbltfx;  
  101.   
  102.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  103.     ddbltfx.dwSize = sizeof(ddbltfx);  
  104.     ddbltfx.dwROP = SRCCOPY;  
  105.     ddbltfx.ddckSrcColorkey;  
  106.   
  107.     // Load our bitmap resource.  
  108.     //hbm = DDGetBitmapHandle(GetModuleHandle(NULL),pszFileName);  
  109.     hbm = SHLoadDIBitmap(pszFileName);  
  110.     if (hbm == NULL)  
  111.     {  
  112.         return FALSE;  
  113.     }  
  114.   
  115.     GetObject(hbm,sizeof(bmInfo),&bmInfo);  
  116.   
  117.   
  118.     memset(&ddsd, 0, sizeof(ddsd));  
  119.     ddsd.dwSize = sizeof(ddsd);  
  120.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  121.     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  122.     ddsd.dwHeight = bmInfo.bmHeight;  
  123.     ddsd.dwWidth  = bmInfo.bmWidth;  
  124.       
  125.     //创建位图离屏页  
  126.      hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);  
  127.     if (hRet != DD_OK)  
  128.     {  
  129.         return FALSE;  
  130.     }  
  131.   
  132.     DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);  
  133.   
  134.   
  135.     if(pcol != NULL)  
  136.     {  
  137.         DDSetColorKey(pDDSBitmap,*pcol);  
  138.         m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);  
  139.     }  
  140.     else  
  141.     {  
  142.         m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);  
  143.     }  
  144.   
  145.     ReleaseRes(pDDSBitmap);  
  146.   
  147.       
  148.     return TRUE;  
  149. }  
  150.   
  151.   
  152.   
  153. BOOL CDirectDraw::DrawTextToBackSuface(LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat,LPCOLORREF pcol)  
  154. {  
  155.     HFONT hf = CreateFont(pfName,ifSize,FALSE,TRUE);  
  156.     HDC hdc;  
  157.     m_pDDSBack ->GetDC(&hdc);  
  158.     HGDIOBJ hOldf = SelectObject(hdc,hf);  
  159.     SetBkMode(hdc,TRANSPARENT);  
  160.     pcol == NULL ? SetTextColor(hdc,RGB(0,0,0)) : SetTextColor(hdc,*pcol);  
  161.     DrawText(hdc,pszText,-1,prcDes,uFormat);  
  162.     SelectObject(hdc,hOldf);  
  163.     m_pDDSBack->ReleaseDC(hdc);  
  164.   
  165.     DeleteObject(hf);  
  166.   
  167.     return TRUE;  
  168. }  
  169.   
  170. void CDirectDraw::UpDatePrimarySurface()  
  171. {  
  172.       
  173.     if(FAILED(m_pDDSPrimary->IsLost()))  
  174.     {  
  175.         if(!RestoreResource())  
  176.         {  
  177.             return;  
  178.         }  
  179.     }  
  180.   
  181.     DDBLTFX  ddbltfx;  
  182.   
  183.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  184.     ddbltfx.dwSize = sizeof(ddbltfx);  
  185.     ddbltfx.dwROP = SRCCOPY;  
  186.     ddbltfx.ddckSrcColorkey;  
  187.   
  188.     //注意,这里应该将窗口坐标转化为屏幕坐标  
  189.     RECT rcClient = {0};  
  190.     ChangeClientToSreen(rcClient);  
  191.     m_pDDSPrimary->Blt(&rcClient,m_pDDSBack,NULL,DDBLT_ROP ,&ddbltfx);  
  192. }  
  193.   
  194. LPDIRECTDRAWSURFACE CDirectDraw::GetBufferSurface()  
  195. {  
  196.     return m_pDDSBack;  
  197. }  
  198.   
  199.   
  200. LPDIRECTDRAWSURFACE CDirectDraw::GetPrimarySurface()  
  201. {  
  202.     return m_pDDSPrimary;  
  203. }  
  204.   
  205.   
  206. void CDirectDraw::ChangeClientToSreen(RECT &rc)  
  207. {  
  208.     GetClientRect(m_hAttach,&rc);  
  209.     ClientToScreen(m_hAttach,(LPPOINT)&rc);  
  210.     ClientToScreen(m_hAttach,(LPPOINT)&rc + 1);  
  211. }  
  212.   
  213.   
  214. HRESULT CDirectDraw::RestoreResource()  
  215. {  
  216.     HRESULT hRet;  
  217.   
  218.     hRet = m_pDDSPrimary->Restore();  
  219.     if (hRet == DD_OK)  
  220.     {  
  221.         hRet = m_pDDSBack->Restore();  
  222.     }  
  223.   
  224.     return hRet;  
  225. }  
  226.   
  227. void CDirectDraw::ReleaseResource()  
  228. {  
  229.     //释放离屏页  
  230.     ReleaseRes(m_pDDSBack);  
  231.   
  232.     //解除裁剪器和主页的关联  
  233.     if (m_pDDSPrimary != NULL)   
  234.     {  
  235.         m_pDDSPrimary ->SetClipper(NULL);  
  236.     }  
  237.       
  238.     //是否裁剪器  
  239.     ReleaseRes(m_lpddClipper);  
  240.   
  241.     //释放主屏页  
  242.     ReleaseRes(m_pDDSPrimary);  
  243.   
  244.     //释放DirectDraw  
  245.     ReleaseRes(m_pDD);  
  246. }  
  247.   
  248.   
  249. HFONT CDirectDraw::CreateFont(LPCTSTR pszFaceName, UINT8 nSize, BOOL bBold, BOOL bAntiAliasing)  
  250. {  
  251.     LOGFONT LogFont;  
  252.   
  253.     LogFont.lfHeight = nSize;  
  254.     LogFont.lfWidth = 0;  
  255.     LogFont.lfEscapement = 0;  
  256.     LogFont.lfOrientation = 0;  
  257.     if( bBold ) LogFont.lfWeight = FW_BOLD;  
  258.     else        LogFont.lfWeight = FW_NORMAL;  
  259.     LogFont.lfItalic = 0;  
  260.     LogFont.lfUnderline = 0;  
  261.     LogFont.lfStrikeOut = 0;  
  262.     LogFont.lfCharSet = DEFAULT_CHARSET;  
  263.     LogFont.lfOutPrecision = 0;  
  264.     LogFont.lfClipPrecision = 0;  
  265.     if( bAntiAliasing ) LogFont.lfQuality = ANTIALIASED_QUALITY;  
  266.     else                LogFont.lfQuality = 0;  
  267.     LogFont.lfPitchAndFamily = 0;  
  268.     wcscpy(LogFont.lfFaceName, pszFaceName);  
  269.   
  270.     return CreateFontIndirect(&LogFont);  
  271. }  
  272.   
  273.   
  274. BOOL CDirectDraw::CreateOffScreenSuface(LPDIRECTDRAWSURFACE *pDDS, int iWidth, int iHeight)  
  275. {  
  276.     HRESULT hRet;  
  277.     DDSURFACEDESC ddsd;  
  278.     memset(&ddsd, 0, sizeof(ddsd));  
  279.     ddsd.dwSize = sizeof(ddsd);  
  280.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  281.     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  282.     ddsd.dwHeight = iHeight;  
  283.     ddsd.dwWidth  = iWidth;  
  284.   
  285.     //创建位图离屏页  
  286.      hRet = m_pDD->CreateSurface(&ddsd,pDDS, NULL);  
  287.     if (hRet != DD_OK)  
  288.     {  
  289.         return FALSE;  
  290.     }  
  291.   
  292.     return TRUE;  
  293. }  
  294.   
  295.   
  296. BOOL CDirectDraw::DrawImageToSurface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcol)  
  297. {  
  298.     if(pDDS == NULL)  
  299.         return FALSE;  
  300.   
  301.     HRESULT hRet;  
  302.     HBITMAP hbm;  
  303.     BITMAP bmInfo;  
  304.     DDSURFACEDESC ddsd;  
  305.     LPDIRECTDRAWSURFACE pDDSBitmap;  
  306.     DDBLTFX  ddbltfx;  
  307.   
  308.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  309.     ddbltfx.dwSize = sizeof(ddbltfx);  
  310.     ddbltfx.dwROP = SRCCOPY;  
  311.     ddbltfx.ddckSrcColorkey;  
  312.   
  313.     hbm = SHLoadDIBitmap(pszFileName);  
  314.     if (hbm == NULL)  
  315.     {  
  316.         return FALSE;  
  317.     }  
  318.   
  319.     GetObject(hbm,sizeof(bmInfo),&bmInfo);  
  320.   
  321.     memset(&ddsd, 0, sizeof(ddsd));  
  322.     ddsd.dwSize = sizeof(ddsd);  
  323.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
  324.     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;  
  325.     ddsd.dwHeight = bmInfo.bmHeight;  
  326.     ddsd.dwWidth  = bmInfo.bmWidth;  
  327.       
  328.     //创建位图离屏页  
  329.      hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);  
  330.     if (hRet != DD_OK)  
  331.     {  
  332.         return FALSE;  
  333.     }  
  334.   
  335.     DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);  
  336.   
  337.   
  338.     if(pcol != NULL)  
  339.     {  
  340.         DDSetColorKey(pDDSBitmap,*pcol);  
  341.         pDDS->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);  
  342.     }  
  343.     else  
  344.     {  
  345.         pDDS->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);  
  346.     }  
  347.   
  348.     ReleaseRes(pDDSBitmap);  
  349.   
  350.     return TRUE;  
  351. }  
  352.   
  353. BOOL CDirectDraw::DrawTextToSuface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat,LPCOLORREF pcol)  
  354. {  
  355.     if(pDDS == NULL)  
  356.         return FALSE;  
  357.   
  358.     HFONT hf = CreateFont(pfName,ifSize,FALSE,TRUE);  
  359.     HDC hdc;  
  360.     pDDS ->GetDC(&hdc);  
  361.     HGDIOBJ hOldf = SelectObject(hdc,hf);  
  362.     SetBkMode(hdc,TRANSPARENT);  
  363.     pcol == NULL ? SetTextColor(hdc,RGB(0,0,0)) : SetTextColor(hdc,*pcol);  
  364.     DrawText(hdc,pszText,-1,prcDes,uFormat);  
  365.     SelectObject(hdc,hOldf);  
  366.     pDDS->ReleaseDC(hdc);  
  367.   
  368.     DeleteObject(hf);  
  369.   
  370.     return TRUE;  
  371. }  
  372.   
  373. BOOL CDirectDraw::BltBackSurface(LPRECT prcDes,LPDIRECTDRAWSURFACE pDDS,LPRECT prcSrc,LPCOLORREF pcol)  
  374. {  
  375.     if(pDDS == NULL)  
  376.         return FALSE;  
  377.   
  378.     DDBLTFX  ddbltfx;  
  379.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  380.     ddbltfx.dwSize = sizeof(ddbltfx);  
  381.     ddbltfx.dwROP = SRCCOPY;  
  382.   
  383.   
  384.    if(pcol != NULL)  
  385.     {  
  386.         DDSetColorKey(pDDS,*pcol);  
  387.         m_pDDSBack->Blt(prcDes,pDDS,prcSrc,DDBLT_KEYSRC,NULL);  
  388.     }  
  389.     else  
  390.     {  
  391.         m_pDDSBack->Blt(prcDes,pDDS,prcSrc,DDBLT_ROP ,&ddbltfx);  
  392.     }  
  393.   
  394.    return TRUE;  
  395. }  
  396.   
  397. BOOL CDirectDraw::CopyBackSurface(LPDIRECTDRAWSURFACE pDDS, LPRECT prcDes, LPRECT prcSrc)  
  398. {  
  399.     if(pDDS == NULL || m_pDDSBack == NULL)  
  400.         return FALSE;  
  401.   
  402.     DDBLTFX  ddbltfx;  
  403.     memset(&ddbltfx, 0, sizeof(ddbltfx));  
  404.     ddbltfx.dwSize = sizeof(ddbltfx);  
  405.     ddbltfx.dwROP = SRCCOPY;  
  406.   
  407.     pDDS->Blt(prcDes,m_pDDSBack,prcSrc,DDBLT_ROP ,&ddbltfx);  
  408.     return TRUE;  
  409.   
  410. }  

测试例子:

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include "MyDDraw.h"  
  3. #include <windows.h>  
  4. #include <commctrl.h>  
  5. #include "DirectDraw.h"  
  6.   
  7. // Global Variables:  
  8. HINSTANCE           g_hInst;  
  9. CDirectDraw g_DDraw;  
  10.   
  11. ATOM            MyRegisterClass(HINSTANCELPTSTR);  
  12. BOOL            InitInstance(HINSTANCEint);  
  13. LRESULT CALLBACK    WndProc(HWNDUINTWPARAMLPARAM);  
  14.   
  15. int WINAPI WinMain(HINSTANCE hInstance,  
  16.                    HINSTANCE hPrevInstance,  
  17.                    LPTSTR    lpCmdLine,  
  18.                    int       nCmdShow)  
  19. {  
  20.     MSG msg;  
  21.     if (!InitInstance(hInstance, nCmdShow))   
  22.     {  
  23.         return FALSE;  
  24.     }  
  25.   
  26.     while (GetMessage(&msg, NULL, 0, 0))   
  27.     {  
  28.         TranslateMessage(&msg);  
  29.         DispatchMessage(&msg);  
  30.     }  
  31.   
  32.     return (int) msg.wParam;  
  33. }  
  34.   
  35. ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)  
  36. {  
  37.     WNDCLASS wc;  
  38.   
  39.     wc.style         = CS_HREDRAW | CS_VREDRAW;  
  40.     wc.lpfnWndProc   = WndProc;  
  41.     wc.cbClsExtra    = 0;  
  42.     wc.cbWndExtra    = 0;  
  43.     wc.hInstance     = hInstance;  
  44.     wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYDDRAW));  
  45.     wc.hCursor       = 0;  
  46.     wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);  
  47.     wc.lpszMenuName  = 0;  
  48.     wc.lpszClassName = szWindowClass;  
  49.   
  50.     return RegisterClass(&wc);  
  51. }  
  52.   
  53.   
  54. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)  
  55. {  
  56.     HWND hWnd;  
  57.     TCHAR szTitle[255];     // title bar text  
  58.     TCHAR szWindowClass[255];   // main window class name  
  59.   
  60.     g_hInst = hInstance; // Store instance handle in our global variable  
  61.   
  62.   
  63.     if (!MyRegisterClass(hInstance, szWindowClass))  
  64.     {  
  65.         return FALSE;  
  66.     }  
  67.   
  68.     hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,  
  69.         0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);  
  70.   
  71.     if (!hWnd)  
  72.     {  
  73.         return FALSE;  
  74.     }  
  75.   
  76.   
  77.     ShowWindow(hWnd, nCmdShow);  
  78.     UpdateWindow(hWnd);  
  79.   
  80.     //  
  81.     g_DDraw.Init(hWnd,DDSCL_NORMAL);  
  82.     g_DDraw.DrawImageToBackSurface(NULL,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//BT_Background.bmp",NULL);  
  83.     g_DDraw.UpDatePrimarySurface();  
  84.   
  85.   
  86.     return TRUE;  
  87. }  
  88.   
  89. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  90. {  
  91.     PAINTSTRUCT ps;  
  92.     HDC hdc;  
  93.   
  94.     switch (message)   
  95.     {  
  96.       
  97.         case WM_LBUTTONDOWN:  
  98.             {  
  99.                 RECT rc ={90, 153, 90+142, 153+174};  
  100.                 RECT rc1 ={0,0,142, 174};  
  101.                 COLORREF cr = RGB(255,255,255);  
  102.                 g_DDraw.DrawImageToBackSurface(&rc,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//Search_BT_Down.bmp",&rc1);  
  103.                 g_DDraw.DrawTextToBackSuface(&rc,L"搜索",L"方正兰亭黑简体",30, DT_CENTER |DT_BOTTOM,&cr);  
  104.   
  105.                 g_DDraw.UpDatePrimarySurface();  
  106.                 break;  
  107.             }  
  108.   
  109.         case WM_LBUTTONUP:  
  110.             {  
  111.                 RECT rc ={90, 153, 90+142, 153+174};  
  112.                 RECT rc1 ={0,0,142, 174};  
  113.                 COLORREF cr = RGB(255,255,255);  
  114.                 g_DDraw.DrawImageToBackSurface(&rc,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//Search_BT_Normal.bmp",&rc1);  
  115.                 g_DDraw.DrawTextToBackSuface(&rc,L"搜索",L"方正兰亭黑简体",30, DT_CENTER |DT_BOTTOM,&cr);  
  116.                   
  117.                 g_DDraw.UpDatePrimarySurface();  
  118.                 break;  
  119.             }  
  120.         case WM_CREATE:  
  121.         case WM_ERASEBKGND:  
  122.             return 0;  
  123.             break;  
  124.         case WM_PAINT:  
  125.             hdc = BeginPaint(hWnd, &ps);  
  126.               
  127.             // TODO: Add any drawing code here...  
  128.             EndPaint(hWnd, &ps);  
  129.             g_DDraw.UpDatePrimarySurface();  
  130.             break;  
  131.         default:  
  132.             return DefWindowProc(hWnd, message, wParam, lParam);  
  133.     }  
  134.     return 0;  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值