📄 ddraw01.cpp
字号:
BeginPaint( hWnd, &ps );
GetClientRect( hWnd, &rc );
// dc.Attach( ps.hdc );
// theSize = dc.GetTextExtent( szMsgFlip, lstrlen( szMsgFlip ) );
// dc.SetBkColor( RGB( 0, 0, 255 ) );
// dc.SetTextColor( RGB( 255, 255, 0 ) );
// dc.TextOut( ( rc.right - theSize.cx ) / 2, ( rc.bottom - theSize.cy ) / 2, szMsgFlip, lstrlen( szMsgFlip ) );
// dc.Detach();
GetTextExtentPoint( ps.hdc, szMsgFlip, lstrlen( szMsgFlip ), &size );
SetBkColor( ps.hdc, RGB( 0, 0, 255 ) );
SetTextColor( ps.hdc, RGB( 255, 255, 0 ) );
TextOut( ps.hdc, ( rc.right - size.cx ) / 2, ( rc.bottom - size.cy ) / 2, szMsgFlip, lstrlen( szMsgFlip ) );
EndPaint( hWnd, &ps );
// RECT rt;
// GetClientRect(hWnd, &rt);
// DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
// EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DestroyDirectDrawObjects();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
// Inserted code begin
/*
* DestroyDirectDrawObjects
*
* finished with all objects we use; release them
*/
static void DestroyDirectDrawObjects( void )
{
if( lpDD != NULL )
{
if( lpDDSPrimary != NULL )
{
lpDDSPrimary->Release();
lpDDSPrimary = NULL;
}
lpDD->Release();
lpDD = NULL;
}
} /* DestroyDirectDrawObjects */
IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy)
{
HBITMAP hbm;
BITMAP bm;
DDSURFACEDESC ddsd;
IDirectDrawSurface *pdds;
//
// try to load the bitmap as a resource, if that fails, try it as a file
//
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL)
return NULL;
//
// get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
//
// 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 = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
return NULL;
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
DeleteObject(hbm);
return pdds;
}
/*
* DDReLoadBitmap
*
* load a bitmap from a file or resource into a directdraw surface.
* normaly used to re-load a surface after a restore.
*
*/
HRESULT DDAttachBitmap(IDirectDrawSurface *pdds, LPCSTR szBitmap)
{
HBITMAP hbm;
HRESULT hr;
//
// try to load the bitmap as a resource, if that fails, try it as a file
//
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL)
{
OutputDebugString("handle is null\n");
return E_FAIL;
}
hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
if (hr != DD_OK)
{
OutputDebugString("ddcopybitmap failed\n");
}
DeleteObject(hbm);
return hr;
}
/*
* DDCopyBitmap
*
* draw a bitmap into a DirectDrawSurface
*
*/
HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
BITMAP bm;
DDSURFACEDESC ddsd;
HRESULT hr;
if (hbm == NULL || pdds == NULL)
return E_FAIL;
//
// make sure this surface is restored.
//
pdds->Restore();
//
// select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
if (!hdcImage)
OutputDebugString("createcompatible dc failed\n");
SelectObject(hdcImage, hbm);
//
// get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
dx = dx == 0 ? bm.bmWidth : dx; // use the passed size, unless zero
dy = dy == 0 ? bm.bmHeight : dy;
//
// get size of surface.
//
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd);
if ((hr = pdds->GetDC(&hdc)) == DD_OK)
{
StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
return hr;
}
// Inserted code end
// Inserted code begin
/****************************************************************************
*
* GetDirectXVersion
*
* This function returns two arguments:
* dwDXVersion:
* 0 No DirectX installed
* 0x100 DirectX version 1 installed
* 0x200 DirectX 2 installed
* 0x300 DirectX 3 installed
* 0x500 At least DirectX 5 installed.
* 0x501 At least DirectX 5a installed.
* dwDXPlatform:
* 0 Unknown (This is a failure case. Should never happen)
* VER_PLATFORM_WIN32_WINDOWS Windows 9X platform
* VER_PLATFORM_WIN32_NT Windows NT platform
*
* Please note that this code is intended as a general guideline. Your app will
* probably be able to simply query for functionality (via COM's QueryInterface)
* for one or two components.
* Please also note:
* "if (dxVer != 0x500) return FALSE;" is BAD.
* "if (dxVer < 0x500) return FALSE;" is MUCH BETTER.
* to ensure your app will run on future releases of DirectX.
*
****************************************************************************/
void GetDirectXVersion(LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform)
{
HRESULT hr;
HINSTANCE DDHinst = 0;
HINSTANCE DIHinst = 0;
LPDIRECTDRAW pDDraw = 0;
LPDIRECTDRAW2 pDDraw2 = 0;
DIRECTDRAWCREATE DirectDrawCreate = 0;
DIRECTINPUTCREATE DirectInputCreate = 0;
OSVERSIONINFO osVer;
LPDIRECTDRAWSURFACE pSurf = 0;
LPDIRECTDRAWSURFACE3 pSurf3 = 0;
// First get the windows platform
osVer.dwOSVersionInfoSize = sizeof(osVer);
if (!GetVersionEx(&osVer))
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
return;
}
if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
*pdwDXPlatform = VER_PLATFORM_WIN32_NT;
// NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5 and no DX on earlier versions.
if (osVer.dwMajorVersion < 4)
{
*pdwDXPlatform = 0; //No DX on NT3.51 or earlier
return;
}
if (osVer.dwMajorVersion == 4)
{
// NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2
*pdwDXVersion = 0x200;
// We're not supposed to be able to tell which SP we're on, so check for dinput
DIHinst = LoadLibrary("DINPUT.DLL");
if (DIHinst == 0)
{
// No DInput... must be DX2 on NT 4 pre-SP3
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
return;
}
DirectInputCreate = (DIRECTINPUTCREATE)
GetProcAddress(DIHinst, "DirectInputCreateA");
FreeLibrary(DIHinst);
if (DirectInputCreate == 0)
{
// No DInput... must be pre-SP3 DX2
OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
return;
}
// It must be NT4, DX2
*pdwDXVersion = 0x300; //DX3 on NT4 SP3 or higher
return;
}
// Else it's NT5 or higher, and it's DX5a or higher:
*pdwDXVersion = 0x501; //DX5a on NT5
return;
}
// Not NT... must be Win9x
*pdwDXPlatform = VER_PLATFORM_WIN32_WINDOWS;
// If we are on Memphis or higher, then we are at least DX5a
if ( (osVer.dwBuildNumber & 0xffff) > 1353) //Check for higher than developer release
{
*pdwDXVersion = 0x501; //DX5a on Memphis or higher
return;
}
// Now we know we are in Windows 9x (or maybe 3.1), so anything's possible.
// First see if DDRAW.DLL even exists.
DDHinst = LoadLibrary("DDRAW.DLL");
if (DDHinst == 0)
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
return;
}
// See if we can create the DirectDraw object.
DirectDrawCreate = (DIRECTDRAWCREATE)
GetProcAddress(DDHinst, "DirectDrawCreate");
if (DirectDrawCreate == 0)
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
OutputDebugString("Couldn't LoadLibrary DDraw\r\n");
return;
}
hr = DirectDrawCreate(NULL, &pDDraw, NULL);
if (FAILED(hr))
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
OutputDebugString("Couldn't create DDraw\r\n");
return;
}
// So DirectDraw exists. We are at least DX1.
*pdwDXVersion = 0x100;
// Let's see if IID_IDirectDraw2 exists.
hr = pDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDDraw2);
if (FAILED(hr))
{
// No IDirectDraw2 exists... must be DX1
pDDraw->Release();
FreeLibrary(DDHinst);
OutputDebugString("Couldn't QI DDraw2\r\n");
return;
}
// IDirectDraw2 exists. We must be at least DX2
pDDraw2->Release();
*pdwDXVersion = 0x200;
// See if we can create the DirectInput object.
DIHinst = LoadLibrary("DINPUT.DLL");
if (DIHinst == 0)
{
// No DInput... must be DX2
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
pDDraw->Release();
FreeLibrary(DDHinst);
return;
}
DirectInputCreate = (DIRECTINPUTCREATE)
GetProcAddress(DIHinst, "DirectInputCreateA");
FreeLibrary(DIHinst);
if (DirectInputCreate == 0)
{
// No DInput... must be DX2
FreeLibrary(DDHinst);
pDDraw->Release();
OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
return;
}
// DirectInputCreate exists. That's enough to tell us that we are at least DX3
*pdwDXVersion = 0x300;
// Checks for 3a vs 3b?
// We can tell if DX5 is present by checking for the existence of IDirectDrawSurface3.
// First we need a surface to QI off of.
DDSURFACEDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = pDDraw->SetCooperativeLevel(NULL,DDSCL_NORMAL);
if (FAILED(hr))
{
// Failure. This means DDraw isn't properly installed.
pDDraw->Release();
FreeLibrary(DDHinst);
*pdwDXVersion = 0;
OutputDebugString("Couldn't Set coop level\r\n");
return;
}
hr = pDDraw->CreateSurface(&desc, &pSurf, NULL);
if (FAILED(hr))
{
// Failure. This means DDraw isn't properly installed.
pDDraw->Release();
FreeLibrary(DDHinst);
*pdwDXVersion = 0;
OutputDebugString("Couldn't CreateSurface\r\n");
return;
}
// Try for the IDirectDrawSurface3 interface. If it works, we're on DX5 at least
if ( FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface3,(LPVOID*)&pSurf3)) )
{
pDDraw->Release();
FreeLibrary(DDHinst);
return;
}
// QI for IDirectDrawSurface3 succeeded. We must be at least DX5
*pdwDXVersion = 0x500;
pSurf->Release();
pDDraw->Release();
FreeLibrary(DDHinst);
return;
}
//Inserted code end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -