📄 1394display.cpp
字号:
// 1394Display.cpp: implementation of the C1394Display class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "1394show.h"
#include "1394Display.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
C1394Display::C1394Display()
{
m_pDD = NULL;
m_pddsFrontBuffer = NULL;
m_pddsBackBuffer = NULL;
}
C1394Display::~C1394Display()
{
DestroyObjects();
}
//窗口模式
HRESULT C1394Display::CreateWindowedDisplay(HWND hWnd, DWORD dwWidth, DWORD dwHeight)
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
//创建DirectDraw对象
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
//选定工作模式:窗口模式 或 全屏模式
//要注意的是,只有当DirectDraw对象为独占访问的控制程度时才能改变显示器的显示模式,
//如果DirectDraw对象运行为窗口模式,调用SetDisplayMode()函数会返回一个错误。
/*普通的控制级表明你的DirectDraw应用程序将以窗口的形式运行。在这种控制级下,你将不能
改变显示器分辨率,主页面的调色板,或进行换页操作。除此之外,你也不能够调用那些会使
视频RAM或视频RAM产生激烈反应的函数,例如:IDirectDraw2::Compact等。
当应用程序为全屏并且独占的控制级时,你就可以充分的利用硬件资源了。在这种控制级下,
你可以设置自定义和动态的调色板,改变显示器分辨率,紧凑内存,和实现换页操作等。独占
模式(也可称为全屏模式)不会妨碍其它的应用程序分配页面内存,也不会阻止它们使用DirectDraw
或GDI的函数性。然而,它的确会阻止除了它自己(为活跃状态时)以外的应用程序改变显示模式
或调色板。
*/
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );//窗口模式
if( FAILED(hr) )
return E_FAIL;
//窗口模式下,不可以改变显示模式
/*
RECT rcWork;
RECT rc;
DWORD dwStyle;
// If we are still a WS_POPUP window we should convert to a normal app
// window so we look like a windows app.
dwStyle = GetWindowStyle( hWnd );
dwStyle &= ~WS_POPUP;
dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
// Aet window size
SetRect( &rc, 0, 0, dwWidth, dwHeight );
AdjustWindowRectEx( &rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL,
GetWindowExStyle(hWnd) );
SetWindowPos( hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
// Make sure our window does not hang outside of the work area
SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
GetWindowRect( hWnd, &rc );
if( rc.left < rcWork.left ) rc.left = rcWork.left;
if( rc.top < rcWork.top ) rc.top = rcWork.top;
SetWindowPos( hWnd, NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
*/
//创建表面对象(surface)放置应用程序的图像数据
//在窗口模式下,只能创建可Blt的表面对象;在全屏模式下,能创建可翻转切换的表面对象
// Create the primary surface:主表面对象
/*尽管创建所有其它类型的页面要求填充DDSURFACEDESC结构的dwHeight 和 dwWidth值
以及像素格式,而创建主页面时一定不能自己指定它们,甚至你知道它们与当前屏幕
是同样大小,否则,CreateSurface函数将调用失败,并且返回DDERR_INVALIDPARAMS。
*/
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
return E_FAIL;
// Create the off-screen surface
//离屏页面(off-screen surface),通常被用来存储位图,用于后来的将位图图象Blit到主页面。
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
return E_FAIL;
//管理剪切列表
LPDIRECTDRAWCLIPPER pcClipper;
if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
return E_FAIL;
if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
{
pcClipper->Release();
return E_FAIL;
}
if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
return E_FAIL;
}
// Done with clipper
pcClipper->Release();
m_hWnd = hWnd;
m_bWindowed = TRUE;
UpdateBounds();
return S_OK;
}
HRESULT C1394Display::CreateFullScreenDisplay( HWND hWnd, DWORD dwWidth,
DWORD dwHeight, DWORD dwBPP )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
if( FAILED(hr) )
return E_FAIL;
// Set the display mode
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
return E_FAIL;
// Create primary surface (with backbuffer attached)
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;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer,
NULL ) ) )
return E_FAIL;
// Get a pointer to the back buffer
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();
m_hWnd = hWnd;
m_bWindowed = FALSE;
UpdateBounds();
return S_OK;
}
HRESULT C1394Display::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;
}
HRESULT C1394Display::CreatePaletteFromBitmap(LPDIRECTDRAWPALETTE *ppPalette, const TCHAR *strBMP)
{
HRSRC hResource = NULL;
RGBQUAD* pRGB = NULL;
BITMAPINFOHEADER* pbi = NULL;
PALETTEENTRY aPalette[256];
HANDLE hFile = NULL;
DWORD iColor;
DWORD dwColors;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
DWORD dwBytesRead;
if( m_pDD == NULL || strBMP == NULL || ppPalette == NULL )
return E_INVALIDARG;
*ppPalette = NULL;
// Try to load the bitmap as a resource, if that fails, try it as a file
hResource = FindResource( NULL, strBMP, RT_BITMAP );
if( hResource )
{
pbi = (LPBITMAPINFOHEADER) LockResource( LoadResource( NULL, hResource ) );
if( NULL == pbi )
return E_FAIL;
pRGB = (RGBQUAD*) ( (BYTE*) pbi + pbi->biSize );
// Figure out how many colors there are
if( pbi == NULL || pbi->biSize < sizeof(BITMAPINFOHEADER) )
dwColors = 0;
else if( pbi->biBitCount > 8 )
dwColors = 0;
else if( pbi->biClrUsed == 0 )
dwColors = 1 << pbi->biBitCount;
else
dwColors = pbi->biClrUsed;
// A DIB color table has its colors stored BGR not RGB
// so flip them around.
for( iColor = 0; iColor < dwColors; iColor++ )
{
aPalette[iColor].peRed = pRGB[iColor].rgbRed;
aPalette[iColor].peGreen = pRGB[iColor].rgbGreen;
aPalette[iColor].peBlue = pRGB[iColor].rgbBlue;
aPalette[iColor].peFlags = 0;
}
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
}
// Attempt to load bitmap as a file
hFile = CreateFile( strBMP, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
if( NULL == hFile )
return E_FAIL;
// Read the BITMAPFILEHEADER
ReadFile( hFile, &bf, sizeof(bf), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(bf) )
{
CloseHandle( hFile );
return E_FAIL;
}
// Read the BITMAPINFOHEADER
ReadFile( hFile, &bi, sizeof(bi), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(bi) )
{
CloseHandle( hFile );
return E_FAIL;
}
// Read the PALETTEENTRY
ReadFile( hFile, aPalette, sizeof(aPalette), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(aPalette) )
{
CloseHandle( hFile );
return E_FAIL;
}
CloseHandle( hFile );
// Figure out how many colors there are
if( bi.biSize != sizeof(BITMAPINFOHEADER) )
dwColors = 0;
else if (bi.biBitCount > 8)
dwColors = 0;
else if (bi.biClrUsed == 0)
dwColors = 1 << bi.biBitCount;
else
dwColors = bi.biClrUsed;
// A DIB color table has its colors stored BGR not RGB
// so flip them around since DirectDraw uses RGB
for( iColor = 0; iColor < dwColors; iColor++ )
{
BYTE r = aPalette[iColor].peRed;
aPalette[iColor].peRed = aPalette[iColor].peBlue;
aPalette[iColor].peBlue = r;
}
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT C1394Display::CreateSurface( C1394Surface** ppSurface,
DWORD dwWidth, DWORD dwHeight )
{
if( NULL == m_pDD )
return E_POINTER;
if( NULL == ppSurface )
return E_INVALIDARG;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
(*ppSurface) = new C1394Surface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: C1394Display::CreateSurfaceFromBitmap()
// Desc: Create a DirectDrawSurface from a bitmap resource or bitmap file.
// Use MAKEINTRESOURCE() to pass a constant into strBMP.
//-----------------------------------------------------------------------------
HRESULT C1394Display::CreateSurfaceFromBitmap( C1394Surface** 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;
// Try to load the bitmap as a resource, if that fails, try it as a file
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;
}
// Get size of the bitmap
GetObject( hBMP, sizeof(bmp), &bmp );//retrieves information for the specified graphics object
// 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 = bmp.bmWidth;
ddsd.dwHeight = bmp.bmHeight;
(*ppSurface) = new C1394Surface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -