📄 ddutil.cpp
字号:
//-----------------------------------------------------------------------------
// File: ddutil.cpp
//
// Desc: DirectDraw framewark classes. Feel free to use this class as a
// starting point for adding extra functionality.
//
//
// Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include "ddutil.h"
//-----------------------------------------------------------------------------
// Name: CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::CDisplay()
{
m_pDD = NULL; //设置初值
m_pddsFrontBuffer = NULL;
m_pddsBackBuffer = NULL;
}
//-----------------------------------------------------------------------------
// Name: ~CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::~CDisplay()
{
DestroyObjects();
}
//-----------------------------------------------------------------------------
// Name: DestroyObjects()
// Desc: 释放已建立的对象
//-----------------------------------------------------------------------------
HRESULT CDisplay::DestroyObjects()
{
SAFE_RELEASE( m_pddsBackBuffer );
SAFE_RELEASE( m_pddsFrontBuffer );
if( m_pDD )
m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL );//取消与窗口的关联
SAFE_RELEASE( m_pDD );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateFullScreenDisplay()
// Desc: 创建DirectX对象
// 参数:窗口句柄,屏幕宽度,高度,深度
//-----------------------------------------------------------------------------
HRESULT CDisplay::Create( HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP )
{
HRESULT hr;
// 释放已建立的对象
DestroyObjects();
// 创建DirectX对象(NULL,DirectX对象指针,DirectX对象类型,NULL)
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// 设置关联的窗口(窗口句柄,方式
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
if( FAILED(hr) )
return E_FAIL;
// 设置显示的模式(设置颜色时应与深度位数相对应)
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
return E_FAIL;
// 创建前平面结构
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 | DDSCAPS_3DDEVICE;
ddsd.dwBackBufferCount = 1; //后平面个数
//创建前平面(平面结构指针,前平面指针,NULL)
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer,
NULL ) ) )
return E_FAIL;
// 设置平面信息结构
DDSCAPS2 ddscaps;
ZeroMemory( &ddscaps, sizeof( ddscaps ) );
ddscaps.dwCaps = DDSCAPS_BACKBUFFER; //设置为后平面
//创建后平面对象
if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
&m_pddsBackBuffer ) ) )
return E_FAIL;
m_pddsBackBuffer->AddRef(); //向系统申请加1
m_hWnd = hWnd; //保存场口句柄
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::CreateSurfaceFromBitmap()
// Desc: Create a DirectDrawSurface from a bitmap resource or bitmap file.
// Use MAKEINTRESOURCE() to pass a constant into strBMP.
// Desc: 通过位图创建一个位图平面
// 参数:平面类指针,位图字符串,希望使用的宽度,希望使用的高度
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurfaceFromBitmap( CSurface** ppSurface,
TCHAR* strBMP,
DWORD dwDesiredWidth,
DWORD dwDesiredHeight )
{
HRESULT hr;
HBITMAP hBMP = NULL;
BITMAP bmp;
DDSURFACEDESC2 ddsd;
if( m_pDD == NULL || strBMP == NULL || ppSurface == NULL ) //判断创建条件
return E_INVALIDARG;
*ppSurface = NULL; //清除前面的内容
// 从资源中调用位图
hBMP = (HBITMAP) LoadImage( GetModuleHandle(NULL), strBMP,
IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
LR_CREATEDIBSECTION );
if( hBMP == NULL )
{
//从文件中调用位图
hBMP = (HBITMAP) LoadImage( NULL, strBMP,
IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
LR_LOADFROMFILE | LR_CREATEDIBSECTION );
if( hBMP == NULL )
return E_FAIL;
}
//得到位图句柄
GetObject( hBMP, sizeof(bmp), &bmp );
// 从位图创建平面结构
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd); //设置结构尺寸
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; //有效信息
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = bmp.bmWidth; //平面的宽度和高度(不能更改)
ddsd.dwHeight = bmp.bmHeight;
(*ppSurface) = new CSurface(); //创建新平面
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) ) //通过结构创建平面
{
delete (*ppSurface);
return hr;
}
// 将位图画入平面
if( FAILED( hr = (*ppSurface)->DrawBitmap( hBMP ) ) )
{
DeleteObject( hBMP );
return hr;
}
DeleteObject( hBMP ); //删除位图指针
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::CreateSurfaceFromText()
// Desc: Creates a DirectDrawSurface from a text string using hFont or the default
// GDI font if hFont is NULL.
// Desc: 通过文字创建一个文字平面
// 参数:平面类指针,字体,文字内容,背景颜色,前景颜色
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurfaceFromText( CSurface** ppSurface,
HFONT hFont, TCHAR* strText,
COLORREF crBackground, COLORREF crForeground )
{
HDC hDC = NULL;
LPDIRECTDRAWSURFACE7 pDDS = NULL;
HRESULT hr;
DDSURFACEDESC2 ddsd;
SIZE sizeText;
if( m_pDD == NULL || strText == NULL || ppSurface == NULL )//判断条件
return E_INVALIDARG;
*ppSurface = NULL;//清除前面的内容
hDC = GetDC( NULL ); //创建设备DC
if( hFont )
SelectObject( hDC, hFont ); //如果没有设置字体,则使用默认字体
GetTextExtentPoint32( hDC, strText, _tcslen(strText), &sizeText ); //得到显示文字的尺寸
ReleaseDC( NULL, hDC );
// Create a DirectDrawSurface for this bitmap
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd); //设置结构尺寸
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;//有效信息
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = sizeText.cx;//平面的宽度和高度(不能更改)
ddsd.dwHeight = sizeText.cy;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) ) //通过结构创建平面
{
delete (*ppSurface);
return hr;
}
// 将文字写入平面
if( FAILED( hr = (*ppSurface)->DrawText( hFont, strText, crBackground, crForeground ) ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: 交换前后平面
// 参数:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Present()
{
HRESULT hr;
if( NULL == m_pddsFrontBuffer && NULL == m_pddsBackBuffer ) //判断条件
return E_POINTER;
while( 1 )
{
hr = m_pddsFrontBuffer->Flip( NULL, 0 ); //将前后平面交换,来显示刚刚画好的屏幕
if( hr == DDERR_SURFACELOST ) //平面丢失了
{
m_pddsFrontBuffer->Restore(); //恢复平面
m_pddsBackBuffer->Restore();
}
if( hr != DDERR_WASSTILLDRAWING )
return hr;
}
}
//-----------------------------------------------------------------------------
// Name: 将平面位图画到后平面上
// 参数: 后平面上的x坐标,后平面上的y坐标,平面对象,位图(文字)平面上的一个矩形区域,方式
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -