⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddraw01.cpp

📁 Visual C++ 6DirectX篇.rar Visual C++ 6DirectX篇.rar
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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 + -