用DirectDraw封装的位图动画类 分类: VC++ 2013-07-22 16:31 365人阅读 评论(0) 收藏

头文件

  1. #pragma once   
  2. #include <vector>   
  3. using namespace std;  
  4. #include <DShow.h>   
  5. #include <uuids.h>   
  6. #define DXIMAGE_WIDTH   1024   
  7. #define DXIMAGE_HEIGHT  768   
  8. class CDXImage  
  9. {  
  10. public:  
  11.     CDXImage(void);  
  12.     ~CDXImage(void);  
  13. //    
  14. public:  
  15.     // 文件中载入位图   
  16.     BOOL LoadImageFromFile(char *pFileName, int cx, int cy);  
  17.     // 载入图像   
  18.     void LoadDXImage(char* pBits, int cx, int cy);  
  19.     // 显示图像   
  20.     void Display(CDC *pDC);  
  21.     // 初始化DirectDraw   
  22.     void InitDraw(HWND hWnd);  
  23.     // 恢复丢失的图面   
  24.     void RestoreAll(HWND hWnd);  
  25. protected:  
  26.     // 释放对象   
  27.     void ReleaseObject();  
  28. // DX objects   
  29. private:  
  30.     IDirectDraw7        *m_lpDD;                // DirectDraw Object   
  31.     IDirectDrawSurface7 *m_lpDDSPrimary;        // Primary Surface Object   
  32.     IDirectDrawSurface7 *m_lppDDSBackBuffer;    // BackBuffer Surface Object   
  33. // Image Object   
  34. private:  
  35.     vector<HBITMAP> m_vpBMPs; // BMP Objects Array   
  36.     HWND m_hWnd;  
  37. };  
#pragma once #include <vector> using namespace std; #include <DShow.h> #include <uuids.h> #define DXIMAGE_WIDTH 1024 #define DXIMAGE_HEIGHT 768 class CDXImage { public: CDXImage(void); ~CDXImage(void); // public: // 文件中载入位图 BOOL LoadImageFromFile(char *pFileName, int cx, int cy); // 载入图像 void LoadDXImage(char* pBits, int cx, int cy); // 显示图像 void Display(CDC *pDC); // 初始化DirectDraw void InitDraw(HWND hWnd); // 恢复丢失的图面 void RestoreAll(HWND hWnd); protected: // 释放对象 void ReleaseObject(); // DX objects private: IDirectDraw7 *m_lpDD; // DirectDraw Object IDirectDrawSurface7 *m_lpDDSPrimary; // Primary Surface Object IDirectDrawSurface7 *m_lppDDSBackBuffer; // BackBuffer Surface Object // Image Object private: vector<HBITMAP> m_vpBMPs; // BMP Objects Array HWND m_hWnd; };

源文件

  1. #include "StdAfx.h"   
  2. #include "DXImage.h"   
  3. CDXImage::CDXImage(void)  
  4. {  
  5.     // 成员变量初始化   
  6.     this->m_lpDD = NULL;  
  7.     this->m_lpDDSPrimary = NULL;  
  8.     this->m_lppDDSBackBuffer = NULL;  
  9.     this->m_hWnd = NULL;  
  10. }  
  11. CDXImage::~CDXImage(void)  
  12. {  
  13.     ReleaseObject();  
  14. }  
  15. /************************************************************************ 
  16.  * 函数名称:LoadDXImage 
  17.  * 函数功能:从DSP端接收图像数据 
  18.  * 函数参数: 
  19.  *          char *pBits : 图像数据 
  20.  *          int cx      : 图像宽度 
  21.  *          int cy      : 图像高度 
  22.  * 返回值:void 
  23. ************************************************************************/  
  24. void CDXImage::LoadDXImage(char *pBits, int cx,int cy)  
  25. {  
  26.       
  27. }  
  28. /************************************************************************ 
  29. * 函数名称:LoadImageFromFile 
  30. * 函数功能:从硬盘文件中读取图像 
  31. * 函数参数: 
  32. *           char *pFileName : 图像文件名 
  33. *           int cx          : 图像宽度 
  34. *           int cy          : 图像高度 
  35. * 返回值类型:BOOL 
  36.             true : 文件载入成功 
  37.             false: 文件载入失败 
  38. ************************************************************************/  
  39. BOOL CDXImage::LoadImageFromFile(char *pFileName, int cx, int cy)  
  40. {  
  41.     HBITMAP hbmp;  
  42.     hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), pFileName, IMAGE_BITMAP, cx, cy, LR_LOADFROMFILE);  
  43.     if (hbmp == NULL)  
  44.     {  
  45.         AfxMessageBox("Failed to Load Image /n Please Check the File Path!");  
  46.         return FALSE;  
  47.     }  
  48.     m_vpBMPs.push_back(hbmp);  
  49.     return TRUE;  
  50. }  
  51. /************************************************************************ 
  52. * 函数名称:InitDraw 
  53. * 函数功能:初始化DirectDraw 
  54. * 函数参数: 
  55. *           HWND hWnd : 图像显示窗口句柄 
  56. * 返回值类型:void 
  57. ************************************************************************/  
  58. void CDXImage::InitDraw(HWND hWnd)  
  59. {  
  60.     ASSERT(m_lpDD == NULL);  
  61.     ASSERT(m_lpDDSPrimary == NULL);  
  62.     ASSERT(m_lppDDSBackBuffer == NULL);  
  63.     ASSERT(m_vpBMPs.size() == 0);  
  64.     ASSERT(m_hWnd == NULL);  
  65.     m_hWnd = hWnd;  
  66.     // 创建DirectDraw对象   
  67.     HRESULT hr;  
  68.     hr = DirectDrawCreateEx(NULL, (VOID**)&m_lpDD, IID_IDirectDraw7, NULL);  
  69.     if (FAILED(hr))  
  70.     {  
  71.         AfxMessageBox("Failed to Create DirectDraw Object!");  
  72.         return;  
  73.     }  
  74.     hr = m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);  
  75.     if (FAILED(hr))  
  76.     {  
  77.         AfxMessageBox("Failed to Initialize DirectDraw");  
  78.         return;  
  79.     }  
  80.     // 创建主图面   
  81.     DDSURFACEDESC2 ddsd;  
  82.     memset(&ddsd, 0, sizeof(ddsd));  
  83.     ddsd.dwSize = sizeof(ddsd);  
  84.     ddsd.dwFlags = DDSD_CAPS;  
  85.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  
  86.     hr = m_lpDD->CreateSurface(&ddsd, &m_lpDDSPrimary, NULL);  
  87.     if (FAILED(hr))  
  88.     {  
  89.         AfxMessageBox("Failed to Create primary surface!");  
  90.         return;  
  91.     }  
  92.     // 创建裁剪   
  93.     IDirectDrawClipper *lpClipper = NULL;  
  94.     hr = m_lpDD->CreateClipper(NULL, &lpClipper, NULL);  
  95.     if (FAILED(hr))  
  96.     {  
  97.         AfxMessageBox("Failed to Create Clipper!");  
  98.         return;  
  99.     }  
  100.     hr = lpClipper->SetHWnd(0, hWnd);  
  101.     if (FAILED(hr))  
  102.     {  
  103.         AfxMessageBox("Failed to Create Window Clipper!");  
  104.         return;  
  105.     }  
  106.     hr = m_lpDDSPrimary->SetClipper(lpClipper);  
  107.     if (FAILED(hr))  
  108.     {  
  109.         AfxMessageBox("Failed to Set Clipper of Primary Surface!");  
  110.         return;  
  111.     }  
  112.     lpClipper->Release();  
  113.     // 创建辅助画面   
  114.     memset(&ddsd, 0, sizeof(ddsd));  
  115.     ddsd.dwSize = sizeof(ddsd);  
  116.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;  
  117.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;  
  118.     ddsd.dwWidth = DXIMAGE_WIDTH;  
  119.     ddsd.dwHeight = DXIMAGE_HEIGHT;  
  120.     hr = m_lpDD->CreateSurface(&ddsd, &m_lppDDSBackBuffer, NULL);  
  121.     if (FAILED(hr))  
  122.     {  
  123.         AfxMessageBox("Failed to Create Assistant Surface!");  
  124.         return;  
  125.     }  
  126. }  
  127. /************************************************************************ 
  128. * 函数名称:Display 
  129. * 函数功能:显示图像 
  130. * 函数参数: 
  131. *           CDC pDC : 图像显示设备上下文 
  132. * 返回值类型:void 
  133. ************************************************************************/  
  134. void CDXImage::Display(CDC *pDC = NULL)  
  135. {  
  136.     // 绘制辅助图面   
  137.     HRESULT hr;  
  138.     DDSURFACEDESC2 desc;  
  139.     memset(&desc, 0, sizeof(desc));  
  140.     desc.dwSize = sizeof(desc);  
  141.     hr = m_lppDDSBackBuffer->GetSurfaceDesc(&desc);  
  142.     if (FAILED(hr))  
  143.     {  
  144.         AfxMessageBox("Failed to Get Assistant Surface Descriptor");  
  145.         return;  
  146.     }  
  147.   
  148.     for (vector<HBITMAP>::iterator it = m_vpBMPs.begin(); it != m_vpBMPs.end(); it++)  
  149.     {  
  150.         // 获取设备DC   
  151.         HDC hDC;  
  152.         if (m_lppDDSBackBuffer->GetDC(&hDC) != DD_OK)  
  153.         {  
  154.             return;  
  155.         }  
  156.         // 保存DC   
  157.         CDC dc; //dbg   
  158.         dc.m_hDC = hDC;  
  159.         int nSavedDC = dc.SaveDC();  
  160.         CDC memDC;  
  161.         memDC.CreateCompatibleDC(&dc);  
  162.         HBITMAP hbmp = *it;  
  163.         memDC.SelectObject(hbmp);  
  164.         dc.BitBlt(0, 0, DXIMAGE_WIDTH, DXIMAGE_HEIGHT, &memDC, 0, 0, SRCCOPY);  
  165.         memDC.DeleteDC();  
  166.         DeleteObject(hbmp);  
  167.         //m_vpBMPs.erase(it);   
  168.           
  169.         CRect rcClient;  
  170.         GetClientRect(m_hWnd, &rcClient);  
  171.         ClientToScreen(m_hWnd, &rcClient.TopLeft());  
  172.         ClientToScreen(m_hWnd, &rcClient.BottomRight());  
  173.         dc.RestoreDC(nSavedDC);  
  174.         dc.m_hDC = NULL;  
  175.         m_lppDDSBackBuffer->ReleaseDC(hDC);  
  176.         m_lpDDSPrimary->Blt(&rcClient, m_lppDDSBackBuffer, NULL, DDBLT_WAIT, NULL);  
  177.     }  
  178. }  
  179. /************************************************************************ 
  180. * 函数名称:ReleaseObject 
  181. * 函数功能:释放DirectDraw对象 
  182. * 函数参数:无 
  183. * 返回值类型:void 
  184. ************************************************************************/  
  185. void CDXImage::ReleaseObject()  
  186. {  
  187.     // 删除对象   
  188.     if (m_lpDDSPrimary != NULL)  
  189.     {  
  190.         m_lpDDSPrimary->Release();  
  191.         m_lpDDSPrimary = NULL;  
  192.     }  
  193.     if (m_lppDDSBackBuffer != NULL)  
  194.     {  
  195.         m_lppDDSBackBuffer->Release();  
  196.         m_lppDDSBackBuffer = NULL;  
  197.     }  
  198.     if (m_lpDD != NULL)  
  199.     {  
  200.         m_lpDD->Release();  
  201.         m_lpDD = NULL;  
  202.     }  
  203. }  
  204. /************************************************************************ 
  205. * 函数名称:RestoreAll 
  206. * 函数功能:所有DirectDraw对象复位 
  207. * 函数参数: 
  208.             HWND hWnd : 图像显示设备句柄 
  209. * 返回值类型:void 
  210. ************************************************************************/  
  211. void CDXImage::RestoreAll(HWND hWnd)  
  212. {  
  213.     HRESULT hr;  
  214.     hr = m_lpDDSPrimary->Restore();  
  215.     if (hr == DDERR_WRONGMODE)  
  216.     {  
  217.         TRACE("Dispaly model changed");  
  218.         ReleaseObject();  
  219.         m_hWnd = hWnd;  
  220.         InitDraw(m_hWnd);  
  221.         return;  
  222.     }  
  223.     else if (FAILED(hr))  
  224.     {  
  225.         return;  
  226.     }  
  227.     if (FAILED(m_lppDDSBackBuffer->Restore()))  
  228.     {  
  229.         return;  
  230.     }  
  231. }  
#include "StdAfx.h" #include "DXImage.h" CDXImage::CDXImage(void) { // 成员变量初始化 this->m_lpDD = NULL; this->m_lpDDSPrimary = NULL; this->m_lppDDSBackBuffer = NULL; this->m_hWnd = NULL; } CDXImage::~CDXImage(void) { ReleaseObject(); } /************************************************************************ * 函数名称:LoadDXImage * 函数功能:从DSP端接收图像数据 * 函数参数: * char *pBits : 图像数据 * int cx : 图像宽度 * int cy : 图像高度 * 返回值:void ************************************************************************/ void CDXImage::LoadDXImage(char *pBits, int cx,int cy) { } /************************************************************************ * 函数名称:LoadImageFromFile * 函数功能:从硬盘文件中读取图像 * 函数参数: * char *pFileName : 图像文件名 * int cx : 图像宽度 * int cy : 图像高度 * 返回值类型:BOOL true : 文件载入成功 false: 文件载入失败 ************************************************************************/ BOOL CDXImage::LoadImageFromFile(char *pFileName, int cx, int cy) { HBITMAP hbmp; hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), pFileName, IMAGE_BITMAP, cx, cy, LR_LOADFROMFILE); if (hbmp == NULL) { AfxMessageBox("Failed to Load Image /n Please Check the File Path!"); return FALSE; } m_vpBMPs.push_back(hbmp); return TRUE; } /************************************************************************ * 函数名称:InitDraw * 函数功能:初始化DirectDraw * 函数参数: * HWND hWnd : 图像显示窗口句柄 * 返回值类型:void ************************************************************************/ void CDXImage::InitDraw(HWND hWnd) { ASSERT(m_lpDD == NULL); ASSERT(m_lpDDSPrimary == NULL); ASSERT(m_lppDDSBackBuffer == NULL); ASSERT(m_vpBMPs.size() == 0); ASSERT(m_hWnd == NULL); m_hWnd = hWnd; // 创建DirectDraw对象 HRESULT hr; hr = DirectDrawCreateEx(NULL, (VOID**)&m_lpDD, IID_IDirectDraw7, NULL); if (FAILED(hr)) { AfxMessageBox("Failed to Create DirectDraw Object!"); return; } hr = m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL); if (FAILED(hr)) { AfxMessageBox("Failed to Initialize DirectDraw"); return; } // 创建主图面 DDSURFACEDESC2 ddsd; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = m_lpDD->CreateSurface(&ddsd, &m_lpDDSPrimary, NULL); if (FAILED(hr)) { AfxMessageBox("Failed to Create primary surface!"); return; } // 创建裁剪 IDirectDrawClipper *lpClipper = NULL; hr = m_lpDD->CreateClipper(NULL, &lpClipper, NULL); if (FAILED(hr)) { AfxMessageBox("Failed to Create Clipper!"); return; } hr = lpClipper->SetHWnd(0, hWnd); if (FAILED(hr)) { AfxMessageBox("Failed to Create Window Clipper!"); return; } hr = m_lpDDSPrimary->SetClipper(lpClipper); if (FAILED(hr)) { AfxMessageBox("Failed to Set Clipper of Primary Surface!"); return; } lpClipper->Release(); // 创建辅助画面 memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = DXIMAGE_WIDTH; ddsd.dwHeight = DXIMAGE_HEIGHT; hr = m_lpDD->CreateSurface(&ddsd, &m_lppDDSBackBuffer, NULL); if (FAILED(hr)) { AfxMessageBox("Failed to Create Assistant Surface!"); return; } } /************************************************************************ * 函数名称:Display * 函数功能:显示图像 * 函数参数: * CDC pDC : 图像显示设备上下文 * 返回值类型:void ************************************************************************/ void CDXImage::Display(CDC *pDC = NULL) { // 绘制辅助图面 HRESULT hr; DDSURFACEDESC2 desc; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); hr = m_lppDDSBackBuffer->GetSurfaceDesc(&desc); if (FAILED(hr)) { AfxMessageBox("Failed to Get Assistant Surface Descriptor"); return; } for (vector<HBITMAP>::iterator it = m_vpBMPs.begin(); it != m_vpBMPs.end(); it++) { // 获取设备DC HDC hDC; if (m_lppDDSBackBuffer->GetDC(&hDC) != DD_OK) { return; } // 保存DC CDC dc; //dbg dc.m_hDC = hDC; int nSavedDC = dc.SaveDC(); CDC memDC; memDC.CreateCompatibleDC(&dc); HBITMAP hbmp = *it; memDC.SelectObject(hbmp); dc.BitBlt(0, 0, DXIMAGE_WIDTH, DXIMAGE_HEIGHT, &memDC, 0, 0, SRCCOPY); memDC.DeleteDC(); DeleteObject(hbmp); //m_vpBMPs.erase(it); CRect rcClient; GetClientRect(m_hWnd, &rcClient); ClientToScreen(m_hWnd, &rcClient.TopLeft()); ClientToScreen(m_hWnd, &rcClient.BottomRight()); dc.RestoreDC(nSavedDC); dc.m_hDC = NULL; m_lppDDSBackBuffer->ReleaseDC(hDC); m_lpDDSPrimary->Blt(&rcClient, m_lppDDSBackBuffer, NULL, DDBLT_WAIT, NULL); } } /************************************************************************ * 函数名称:ReleaseObject * 函数功能:释放DirectDraw对象 * 函数参数:无 * 返回值类型:void ************************************************************************/ void CDXImage::ReleaseObject() { // 删除对象 if (m_lpDDSPrimary != NULL) { m_lpDDSPrimary->Release(); m_lpDDSPrimary = NULL; } if (m_lppDDSBackBuffer != NULL) { m_lppDDSBackBuffer->Release(); m_lppDDSBackBuffer = NULL; } if (m_lpDD != NULL) { m_lpDD->Release(); m_lpDD = NULL; } } /************************************************************************ * 函数名称:RestoreAll * 函数功能:所有DirectDraw对象复位 * 函数参数: HWND hWnd : 图像显示设备句柄 * 返回值类型:void ************************************************************************/ void CDXImage::RestoreAll(HWND hWnd) { HRESULT hr; hr = m_lpDDSPrimary->Restore(); if (hr == DDERR_WRONGMODE) { TRACE("Dispaly model changed"); ReleaseObject(); m_hWnd = hWnd; InitDraw(m_hWnd); return; } else if (FAILED(hr)) { return; } if (FAILED(m_lppDDSBackBuffer->Restore())) { return; } }

用法:

适用于Win32平台

一、创建一个CDXImage类对象

  1. CDXImage m_DXImage;  
CDXImage m_DXImage;

二、初始化并载入位图

  1. m_DXImage.InitDraw(GetSafeHwnd());  // 初始化DX图像对象   
  2. m_DXImage.LoadImageFromFile("pics//0.bmp", 1024, 768);  
  3. m_DXImage.LoadImageFromFile("pics//2.bmp", 1024, 768);  
m_DXImage.InitDraw(GetSafeHwnd()); // 初始化DX图像对象 m_DXImage.LoadImageFromFile("pics//0.bmp", 1024, 768); m_DXImage.LoadImageFromFile("pics//2.bmp", 1024, 768);

三、显示位图

  1. m_DXImage.Display(NULL);  
m_DXImage.Display(NULL);

然后可借助定时器使用。

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/mao0504/p/4706887.html