基于窗口的DirectDraw编程

本文详细介绍如何使用DirectDraw在窗口模式下进行编程,包括创建窗口、DirectDraw对象、设置协作级别、创建主屏页和离屏页等步骤,并提供了一个完整的示例程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

//创建DirectDraw对象
hRet = DirectDrawCreate(NULL, &m_pDD, NULL);
if (hRet != DD_OK)
{
  goto Err;
}

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

//设置协作级别
 hRet = m_pDD->SetCooperativeLevel(m_hAttach, DDSCL_NORMAL);
if (hRet != DD_OK)
{
    goto Err;
}

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

DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

//创建主页
hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);
if (hRet != DD_OK)
{
 goto Err;
}
//创建离屏页时,必须指定页面的长、宽
RECT rcClient ={0};
GetClientRect(m_hAttach,&rcClient);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
ddsd.dwHeight = rcClient.bottom - rcClient.top;
ddsd.dwWidth = rcClient.right - rcClient.left;

hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSBack, NULL);
if (hRet != DD_OK)
{
 goto Err;
}

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

//创建裁剪器
hRet = m_pDD->CreateClipper(0, &m_lpddClipper, NULL);
 if (hRet != DD_OK)
{
     goto Err;
}
//将裁剪器和窗口关联
m_lpddClipper->SetHWnd(0,m_hAttach);

//将裁剪器与图面相关联
m_pDDSPrimary->SetClipper(m_lpddClipper);

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

void OnPaint()
{
 HRESULT hRet;
 HBITMAP hbm;
 BITMAP bmInfo;
 DDSURFACEDESC ddsd;
 LPDIRECTDRAWSURFACE pDDSBitmap;
 DDBLTFX  ddbltfx;

 memset(&ddbltfx, 0, sizeof(ddbltfx));
 ddbltfx.dwSize = sizeof(ddbltfx);
 ddbltfx.dwROP = SRCCOPY;
 ddbltfx.ddckSrcColorkey;

 // Load our bitmap resource.
 //hbm = DDGetBitmapHandle(GetModuleHandle(NULL),pszFileName);
 hbm = SHLoadDIBitmap(TEXT("Test.bmp"));
 if (hbm == NULL)
 {
  return;
 }

 GetObject(hbm,sizeof(bmInfo),&bmInfo);

 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
 ddsd.dwHeight = bmInfo.bmHeight;
 ddsd.dwWidth  = bmInfo.bmWidth;

 //创建位图离屏页
 hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);
 if (hRet != DD_OK)
 {
  return;
 }

 DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);


 if(pcol != NULL)
 {
  DDSetColorKey(pDDSBitmap,*pcol);
  m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);
 }
 else
 {
  m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);
 }

 ReleaseRes(pDDSBitmap);
 if(FAILED(m_pDDSPrimary->IsLost()))
 {
  //在其它程序改变显示模式导致页的丢失时,要对页面的恢复
  if(!RestoreResource())
  {
   return;
  }
 }
 //注意,这里应该将窗口坐标转化为屏幕坐标
 RECT rcClient = {0};
 ChangeClientToSreen(rcClient);
 //调用以下这句就能显示在屏幕上
 m_pDDSPrimary->Blt(&rcClient,m_pDDSBack,NULL,DDBLT_ROP ,&ddbltfx);

 return;
}

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

//DirectDraw.h

#pragma once
#include <windows.h>
#include <Ddraw.h>
#include "D://OS//WINCE600//PUBLIC//DIRECTX//SDK//SAMPLES//DDRAW//INCLUDE//ddutil.h"

#define ReleaseRes(x) if(x != NULL){ x->Release(); x = NULL;}

class CDirectDraw
{
public:
 /******************************************************
 *函数介绍:初始化类成员变量
 *入口参数:hWnd,隶属于的窗口句柄
      dwMode,模式
 *出口参数:无
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL Init(HWND hWnd,DWORD dwMode);

 /******************************************************
 *函数介绍:将指定的图片加载到后台缓冲页中
 *入口参数:prcDes,   目标显示图片区域
      pFileName,显示图片名称
      prcSrc,    显示图片中区域
      pcolTra,   透明颜色
 *出口参数:无
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL DrawImageToBackSurface(LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);

 /******************************************************
 *函数介绍:将文本绘制到后台缓冲页中
 *入口参数:prcDes,   目标显示文本区域
      pszText,  显示文本内容
      pfName,    字体名称
      ifSize,   字体大小
      uFormat,   对齐方式
      pcol,     字体颜色指针
 *出口参数:无
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL DrawTextToBackSuface(LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat = DT_LEFT,LPCOLORREF pcol = NULL);

 /******************************************************
 *函数介绍:创建一个离屏页
 *入口参数:
      iWidth, 宽度
      iHeight,高度
     
 *出口参数:pDDS,保存离屏页的指针
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL CreateOffScreenSuface(LPDIRECTDRAWSURFACE *pDDS, int iWidth, int iHeight);

 /******************************************************
 *函数介绍:图片加到指定的页中
 *入口参数:pDDS,     页指针
      prcDes,   目标显示图片区域
      pFileName,显示图片名称
      prcSrc,    显示图片中区域
      pcolTra,   透明颜色
     
 *出口参数:无
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL DrawImageToSurface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);

 /******************************************************
 *函数介绍:将文本绘制到指定的页中
 *入口参数:pDDS,     指定的页指针
      prcDes,   目标显示文本区域
      pszText,  显示文本内容
      pfName,    字体名称
      ifSize,   字体大小
      uFormat,   对齐方式
      pcol,     字体颜色指针
 *出口参数:无
 *返回值: TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL DrawTextToSuface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat = DT_LEFT,LPCOLORREF pcol = NULL);
 
 /******************************************************
 *函数介绍:将指定的页中的内容绘制到后台缓冲页
 *入口参数:
      prcDes,   目标显示图片区域
      pDDS,     页指针
      prcSrc,    显示图片中区域
      pcolTra,   透明颜色
 *出口参数:无
 *返回值:  TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL BltBackSurface(LPRECT prcDes,LPDIRECTDRAWSURFACE pDDS,LPRECT prcSrc,LPCOLORREF pcolTra = NULL);

 /******************************************************
 *函数介绍:拷贝后台页到指定的页中
 *入口参数:
      pDDS,   目标页指针
      prcDes, 目标页区域
      prcSrc,  源页区域
 *出口参数:无
 *返回值:  TRUE - 成功, FALSE - 失败
 ******************************************************/
 BOOL CopyBackSurface(LPDIRECTDRAWSURFACE pDDS, LPRECT prcDes, LPRECT prcSrc);

 /******************************************************
 *函数介绍:获取后台页指针
 *入口参数:无
 *出口参数:无
 *返回值:  成功 - 返回后台页指针,失败 - 返回NULL
 ******************************************************/
 LPDIRECTDRAWSURFACE GetBufferSurface();

 /******************************************************
 *函数介绍:获取主页指针
 *入口参数:无
 *出口参数:无
 *返回值:  成功 - 返回主页指针,失败 - 返回NULL
 ******************************************************/
 LPDIRECTDRAWSURFACE GetPrimarySurface();

 /******************************************************
 *函数介绍:更新主页
 *入口参数:无
 *出口参数:无
 *返回值:  无
 ******************************************************/
 void UpDatePrimarySurface();

public:
 CDirectDraw();
 virtual ~CDirectDraw();

protected:
 /******************************************************
 *函数介绍:释放资源
 *入口参数:无
 *出口参数:无
 *返回值:  无
 ******************************************************/
 void ReleaseResource();

 /******************************************************
 *函数介绍:恢复资源
 *入口参数:无
 *出口参数:无
 *返回值:  无
 ******************************************************/
 HRESULT RestoreResource();

 /******************************************************
 *函数介绍:将客户坐标转换为屏幕坐标
 *入口参数:rc,客户坐标区域
 *出口参数:rc,屏幕坐标区域
 *返回值:  无
 ******************************************************/
 void ChangeClientToSreen(RECT &rc);

 /************************************************************************/
 /*
 函数名: CreateFont
 描  述: 获取字体句柄
 参  数: TCHAR* : [in] 字体类型
 UINT8 : [in] 字体大小
 返  回: HFONT
 */
 /************************************************************************/
 HFONT CreateFont(LPCTSTR pszFaceName, UINT8 nSize, BOOL bBold, BOOL bAntiAliasing);
private:
 LPDIRECTDRAW                m_pDD ;       // DirectDraw object
 LPDIRECTDRAWSURFACE         m_pDDSPrimary;// DirectDraw primary surface
 LPDIRECTDRAWSURFACE         m_pDDSBack;   // DirectDraw back surface
 LPDIRECTDRAWCLIPPER   m_lpddClipper;// DirectDraw clipper
 HWND m_hAttach;
};

//DirectDraw.cpp

#include "DirectDraw.h"

#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"D://OS//WINCE600//PUBLIC//DIRECTX//SDK//LIB//ARMV4I//RETAIL//ddutil.lib")

 

CDirectDraw::CDirectDraw():
m_pDD(NULL),
m_pDDSPrimary(NULL),
m_pDDSBack(NULL),
m_lpddClipper(NULL),
m_hAttach(NULL)
{
 
}

CDirectDraw::~CDirectDraw()
{
 ReleaseResource();
}

BOOL CDirectDraw::Init(HWND hWnd,DWORD dwMode)
{
 HRESULT hRet;
 DDSURFACEDESC ddsd;
 RECT rcClient ={0};

 //保存窗口句柄
 m_hAttach = hWnd;

 //创建DirectDraw对象
 hRet = DirectDrawCreate(NULL, &m_pDD, NULL);
    if (hRet != DD_OK)
 {
  goto Err;
 }
 //设置协作级别
    hRet = m_pDD->SetCooperativeLevel(m_hAttach,dwMode );
    if (hRet != DD_OK)
 {
  goto Err;
 }

 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_CAPS;
 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
 //创建主页
  hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);
    if (hRet != DD_OK)
 {
  goto Err;
 }
 
 GetClientRect(m_hAttach,&rcClient);

 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
 ddsd.dwHeight = rcClient.bottom - rcClient.top;
 ddsd.dwWidth = rcClient.right - rcClient.left;

 //创建离屏页
 hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSBack, NULL);
    if (hRet != DD_OK)
 {
  goto Err;
 }

 //创建裁剪器
 hRet = m_pDD->CreateClipper(0, &m_lpddClipper, NULL);
    if (hRet != DD_OK)
 {
  goto Err;
 }
 //将裁剪器和窗口关联
 m_lpddClipper->SetHWnd(0,m_hAttach);

 //将裁剪器与图面相关联
 m_pDDSPrimary->SetClipper(m_lpddClipper);

 return TRUE;

Err:  //错误处理,释放内存
 m_hAttach = NULL;
 ReleaseResource();
 return FALSE;

  
}

BOOL CDirectDraw::DrawImageToBackSurface(LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcol)
{
 HRESULT hRet;
 HBITMAP hbm;
 BITMAP bmInfo;
 DDSURFACEDESC ddsd;
 LPDIRECTDRAWSURFACE pDDSBitmap;
 DDBLTFX  ddbltfx;

    memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwROP = SRCCOPY;
 ddbltfx.ddckSrcColorkey;

 // Load our bitmap resource.
 //hbm = DDGetBitmapHandle(GetModuleHandle(NULL),pszFileName);
 hbm = SHLoadDIBitmap(pszFileName);
 if (hbm == NULL)
 {
  return FALSE;
 }

 GetObject(hbm,sizeof(bmInfo),&bmInfo);


 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
 ddsd.dwHeight = bmInfo.bmHeight;
 ddsd.dwWidth  = bmInfo.bmWidth;
 
 //创建位图离屏页
  hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);
    if (hRet != DD_OK)
 {
  return FALSE;
 }

 DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);


 if(pcol != NULL)
 {
  DDSetColorKey(pDDSBitmap,*pcol);
  m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);
 }
 else
 {
  m_pDDSBack->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);
 }

 ReleaseRes(pDDSBitmap);

 
 return TRUE;
}

 

BOOL CDirectDraw::DrawTextToBackSuface(LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat,LPCOLORREF pcol)
{
 HFONT hf = CreateFont(pfName,ifSize,FALSE,TRUE);
 HDC hdc;
 m_pDDSBack ->GetDC(&hdc);
 HGDIOBJ hOldf = SelectObject(hdc,hf);
 SetBkMode(hdc,TRANSPARENT);
 pcol == NULL ? SetTextColor(hdc,RGB(0,0,0)) : SetTextColor(hdc,*pcol);
 DrawText(hdc,pszText,-1,prcDes,uFormat);
 SelectObject(hdc,hOldf);
 m_pDDSBack->ReleaseDC(hdc);

 DeleteObject(hf);

 return TRUE;
}

void CDirectDraw::UpDatePrimarySurface()
{
 
 if(FAILED(m_pDDSPrimary->IsLost()))
 {
  if(!RestoreResource())
  {
   return;
  }
 }

 DDBLTFX  ddbltfx;

    memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwROP = SRCCOPY;
 ddbltfx.ddckSrcColorkey;

 //注意,这里应该将窗口坐标转化为屏幕坐标
 RECT rcClient = {0};
 ChangeClientToSreen(rcClient);
 m_pDDSPrimary->Blt(&rcClient,m_pDDSBack,NULL,DDBLT_ROP ,&ddbltfx);
}

LPDIRECTDRAWSURFACE CDirectDraw::GetBufferSurface()
{
 return m_pDDSBack;
}


LPDIRECTDRAWSURFACE CDirectDraw::GetPrimarySurface()
{
 return m_pDDSPrimary;
}


void CDirectDraw::ChangeClientToSreen(RECT &rc)
{
 GetClientRect(m_hAttach,&rc);
 ClientToScreen(m_hAttach,(LPPOINT)&rc);
 ClientToScreen(m_hAttach,(LPPOINT)&rc + 1);
}


HRESULT CDirectDraw::RestoreResource()
{
 HRESULT hRet;

    hRet = m_pDDSPrimary->Restore();
    if (hRet == DD_OK)
    {
        hRet = m_pDDSBack->Restore();
    }

    return hRet;
}

void CDirectDraw::ReleaseResource()
{
 //释放离屏页
 ReleaseRes(m_pDDSBack);

 //解除裁剪器和主页的关联
 if (m_pDDSPrimary != NULL)
 {
  m_pDDSPrimary ->SetClipper(NULL);
 }
   
 //是否裁剪器
 ReleaseRes(m_lpddClipper);

 //释放主屏页
 ReleaseRes(m_pDDSPrimary);

 //释放DirectDraw
 ReleaseRes(m_pDD);
}


HFONT CDirectDraw::CreateFont(LPCTSTR pszFaceName, UINT8 nSize, BOOL bBold, BOOL bAntiAliasing)
{
 LOGFONT LogFont;

 LogFont.lfHeight = nSize;
 LogFont.lfWidth = 0;
 LogFont.lfEscapement = 0;
 LogFont.lfOrientation = 0;
 if( bBold ) LogFont.lfWeight = FW_BOLD;
 else        LogFont.lfWeight = FW_NORMAL;
 LogFont.lfItalic = 0;
 LogFont.lfUnderline = 0;
 LogFont.lfStrikeOut = 0;
 LogFont.lfCharSet = DEFAULT_CHARSET;
 LogFont.lfOutPrecision = 0;
 LogFont.lfClipPrecision = 0;
 if( bAntiAliasing ) LogFont.lfQuality = ANTIALIASED_QUALITY;
 else                LogFont.lfQuality = 0;
 LogFont.lfPitchAndFamily = 0;
 wcscpy(LogFont.lfFaceName, pszFaceName);

 return CreateFontIndirect(&LogFont);
}


BOOL CDirectDraw::CreateOffScreenSuface(LPDIRECTDRAWSURFACE *pDDS, int iWidth, int iHeight)
{
 HRESULT hRet;
 DDSURFACEDESC ddsd;
 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
 ddsd.dwHeight = iHeight;
 ddsd.dwWidth  = iWidth;

 //创建位图离屏页
  hRet = m_pDD->CreateSurface(&ddsd,pDDS, NULL);
    if (hRet != DD_OK)
 {
  return FALSE;
 }

 return TRUE;
}


BOOL CDirectDraw::DrawImageToSurface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszFileName,LPRECT prcSrc,LPCOLORREF pcol)
{
 if(pDDS == NULL)
  return FALSE;

 HRESULT hRet;
 HBITMAP hbm;
 BITMAP bmInfo;
 DDSURFACEDESC ddsd;
 LPDIRECTDRAWSURFACE pDDSBitmap;
 DDBLTFX  ddbltfx;

    memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwROP = SRCCOPY;
 ddbltfx.ddckSrcColorkey;

 hbm = SHLoadDIBitmap(pszFileName);
 if (hbm == NULL)
 {
  return FALSE;
 }

 GetObject(hbm,sizeof(bmInfo),&bmInfo);

 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
 ddsd.dwHeight = bmInfo.bmHeight;
 ddsd.dwWidth  = bmInfo.bmWidth;
 
 //创建位图离屏页
  hRet = m_pDD->CreateSurface(&ddsd, &pDDSBitmap, NULL);
    if (hRet != DD_OK)
 {
  return FALSE;
 }

 DDCopyBitmap(pDDSBitmap, hbm, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight);


 if(pcol != NULL)
 {
  DDSetColorKey(pDDSBitmap,*pcol);
  pDDS->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_KEYSRC,NULL);
 }
 else
 {
  pDDS->Blt(prcDes,pDDSBitmap,prcSrc,DDBLT_ROP ,&ddbltfx);
 }

 ReleaseRes(pDDSBitmap);

 return TRUE;
}

BOOL CDirectDraw::DrawTextToSuface(LPDIRECTDRAWSURFACE pDDS,LPRECT prcDes,LPCTSTR pszText,LPCTSTR pfName, int ifSize,UINT uFormat,LPCOLORREF pcol)
{
 if(pDDS == NULL)
  return FALSE;

 HFONT hf = CreateFont(pfName,ifSize,FALSE,TRUE);
 HDC hdc;
 pDDS ->GetDC(&hdc);
 HGDIOBJ hOldf = SelectObject(hdc,hf);
 SetBkMode(hdc,TRANSPARENT);
 pcol == NULL ? SetTextColor(hdc,RGB(0,0,0)) : SetTextColor(hdc,*pcol);
 DrawText(hdc,pszText,-1,prcDes,uFormat);
 SelectObject(hdc,hOldf);
 pDDS->ReleaseDC(hdc);

 DeleteObject(hf);

 return TRUE;
}

BOOL CDirectDraw::BltBackSurface(LPRECT prcDes,LPDIRECTDRAWSURFACE pDDS,LPRECT prcSrc,LPCOLORREF pcol)
{
 if(pDDS == NULL)
  return FALSE;

 DDBLTFX  ddbltfx;
 memset(&ddbltfx, 0, sizeof(ddbltfx));
 ddbltfx.dwSize = sizeof(ddbltfx);
 ddbltfx.dwROP = SRCCOPY;


   if(pcol != NULL)
 {
  DDSetColorKey(pDDS,*pcol);
  m_pDDSBack->Blt(prcDes,pDDS,prcSrc,DDBLT_KEYSRC,NULL);
 }
 else
 {
  m_pDDSBack->Blt(prcDes,pDDS,prcSrc,DDBLT_ROP ,&ddbltfx);
 }

   return TRUE;
}

BOOL CDirectDraw::CopyBackSurface(LPDIRECTDRAWSURFACE pDDS, LPRECT prcDes, LPRECT prcSrc)
{
 if(pDDS == NULL || m_pDDSBack == NULL)
  return FALSE;

 DDBLTFX  ddbltfx;
 memset(&ddbltfx, 0, sizeof(ddbltfx));
 ddbltfx.dwSize = sizeof(ddbltfx);
 ddbltfx.dwROP = SRCCOPY;

 pDDS->Blt(prcDes,m_pDDSBack,prcSrc,DDBLT_ROP ,&ddbltfx);
 return TRUE;

}

测试例子:

#include "stdafx.h"
#include "MyDDraw.h"
#include <windows.h>
#include <commctrl.h>
#include "DirectDraw.h"

// Global Variables:
HINSTANCE   g_hInst;
CDirectDraw g_DDraw;

ATOM   MyRegisterClass(HINSTANCE, LPTSTR);
BOOL   InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
 MSG msg;
 if (!InitInstance(hInstance, nCmdShow))
 {
  return FALSE;
 }

 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
 WNDCLASS wc;

 wc.style         = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc   = WndProc;
 wc.cbClsExtra    = 0;
 wc.cbWndExtra    = 0;
 wc.hInstance     = hInstance;
 wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYDDRAW));
 wc.hCursor       = 0;
 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 wc.lpszMenuName  = 0;
 wc.lpszClassName = szWindowClass;

 return RegisterClass(&wc);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    TCHAR szTitle[255];  // title bar text
    TCHAR szWindowClass[255]; // main window class name

    g_hInst = hInstance; // Store instance handle in our global variable


    if (!MyRegisterClass(hInstance, szWindowClass))
    {
     return FALSE;
    }

    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
        0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }


    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

 //
 g_DDraw.Init(hWnd,DDSCL_NORMAL);
 g_DDraw.DrawImageToBackSurface(NULL,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//BT_Background.bmp",NULL);
 g_DDraw.UpDatePrimarySurface();


    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
   
  case WM_LBUTTONDOWN:
   {
    RECT rc ={90, 153, 90+142, 153+174};
    RECT rc1 ={0,0,142, 174};
    COLORREF cr = RGB(255,255,255);
    g_DDraw.DrawImageToBackSurface(&rc,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//Search_BT_Down.bmp",&rc1);
    g_DDraw.DrawTextToBackSuface(&rc,L"搜索",L"方正兰亭黑简体",30, DT_CENTER |DT_BOTTOM,&cr);

    g_DDraw.UpDatePrimarySurface();
    break;
   }

  case WM_LBUTTONUP:
   {
    RECT rc ={90, 153, 90+142, 153+174};
    RECT rc1 ={0,0,142, 174};
    COLORREF cr = RGB(255,255,255);
    g_DDraw.DrawImageToBackSurface(&rc,L"//NANDDisk//MSD6_951V1.0.1-HASE//APP//UI//Search_BT_Normal.bmp",&rc1);
    g_DDraw.DrawTextToBackSuface(&rc,L"搜索",L"方正兰亭黑简体",30, DT_CENTER |DT_BOTTOM,&cr);
    
    g_DDraw.UpDatePrimarySurface();
    break;
   }
        case WM_CREATE:
  case WM_ERASEBKGND:
   return 0;
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
           
            // TODO: Add any drawing code here...
            EndPaint(hWnd, &ps);
   g_DDraw.UpDatePrimarySurface();
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值