DDEX3.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       ddex3.cpp
  6.  *  Content:    Direct Draw example program 3.  Adds functionality to 
  7.  *              example program 2.  Creates two offscreen surfaces in 
  8.  *              addition to the primary surface and back buffer.  Loads
  9.  *              a bitmap file into each offscreen surface.  Uses BltFast
  10.  *              to copy the contents of an offscreen surface to the back
  11.  *              buffer and then flips the buffers and copies the next 
  12.  *              offscreen surface to the back buffer.  Press F12 to exit
  13.  *              the program.  This program requires at least 1.2 Megs of 
  14.  *              video ram.
  15.  *
  16.  ***************************************************************************/
  17. #define NAME "DDExample3"
  18. #define TITLE "Direct Draw Example 3"
  19. #define WIN32_LEAN_AND_MEAN
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <ddraw.h>
  23. #include <stdlib.h>
  24. #include <stdarg.h>
  25. #include "resource.h"
  26. #include "ddutil.h"         // DDLoadPalette, DDCopyBitmap
  27. // Name of our bitmap resource.
  28. char szBitmap[] = "DDEX3";
  29. BOOL InitSurfaces( void );
  30. #define TIMER_ID        1
  31. #define TIMER_RATE      500
  32. LPDIRECTDRAW            lpDD;           // DirectDraw object
  33. LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
  34. LPDIRECTDRAWSURFACE     lpDDSBack;      // DirectDraw back surface
  35. LPDIRECTDRAWSURFACE     lpDDSOne;       // Offscreen surface 1
  36. LPDIRECTDRAWSURFACE     lpDDSTwo;       // Offscreen surface 2
  37. LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette
  38. BOOL                    bActive;        // is application active?
  39. /*
  40.  * finiObjects
  41.  *
  42.  * finished with all objects we use; release them
  43.  */
  44. static void finiObjects( void )
  45. {
  46.     if( lpDD != NULL )
  47.     {
  48. if( lpDDSPrimary != NULL )
  49. {
  50.     lpDDSPrimary->Release();
  51.     lpDDSPrimary = NULL;
  52. }
  53. if( lpDDSOne != NULL )
  54. {
  55.     lpDDSOne->Release();
  56.     lpDDSOne = NULL;
  57. }
  58. if( lpDDSTwo != NULL )
  59. {
  60.     lpDDSTwo->Release();
  61.     lpDDSTwo = NULL;
  62. }
  63. if( lpDDPal != NULL )
  64. {
  65.     lpDDPal->Release();
  66.     lpDDPal = NULL;
  67. }
  68. lpDD->Release();
  69. lpDD = NULL;
  70.     }
  71. } /* finiObjects */
  72. /*
  73.  * restoreAll
  74.  *
  75.  * restore all lost objects
  76.  */
  77. HRESULT restoreAll( void )
  78. {
  79.     HRESULT     ddrval;
  80.     ddrval = lpDDSPrimary->Restore();
  81.     if( ddrval == DD_OK )
  82.     {
  83. ddrval = lpDDSOne->Restore();
  84. if( ddrval == DD_OK )
  85. {
  86.     ddrval = lpDDSTwo->Restore();
  87.     if( ddrval == DD_OK )
  88.     {
  89. InitSurfaces();
  90.     }
  91. }
  92.     }
  93.     return ddrval;
  94. } /* restoreAll */
  95. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  96.     WPARAM wParam, LPARAM lParam )
  97. {
  98.     static  int phase = 0;
  99.     RECT        rcRect;
  100.     switch( message )
  101.     {
  102.     case WM_ACTIVATEAPP:
  103. bActive = wParam;
  104. break;
  105.     case WM_CREATE:
  106. break;
  107.     case WM_SETCURSOR:
  108. SetCursor(NULL);
  109. return TRUE;
  110.     case WM_TIMER:
  111. if( bActive )
  112. {
  113.     HRESULT             ddrval;
  114.     LPDIRECTDRAWSURFACE pdds;
  115.     rcRect.left = 0;
  116.     rcRect.top = 0;
  117.     rcRect.right = 640;
  118.     rcRect.bottom = 480;
  119.     if(phase)
  120.     {
  121. pdds = lpDDSTwo;
  122. phase = 0;
  123.     }
  124.     else
  125.     {
  126. pdds = lpDDSOne;
  127. phase = 1;
  128.     }
  129.     while( 1 )
  130.     {
  131. ddrval = lpDDSBack->BltFast( 0, 0, pdds, &rcRect, FALSE );
  132. if( ddrval == DD_OK )
  133. {
  134.     break;
  135. }
  136. if( ddrval == DDERR_SURFACELOST )
  137. {
  138.     ddrval = restoreAll();
  139.     if( ddrval != DD_OK )
  140.     {
  141. break;
  142.     }
  143. }
  144. if( ddrval != DDERR_WASSTILLDRAWING )
  145. {
  146.     break;
  147. }
  148.     }
  149.     
  150.     // Flip surfaces
  151.     while( 1 )
  152.     {
  153. ddrval = lpDDSPrimary->Flip( NULL, 0 );
  154. if( ddrval == DD_OK )
  155. {
  156.     break;
  157. }
  158. if( ddrval == DDERR_SURFACELOST )
  159. {
  160.     ddrval = restoreAll();
  161.     if( ddrval != DD_OK )
  162.     {
  163. break;
  164.     }
  165. }
  166. if( ddrval != DDERR_WASSTILLDRAWING )
  167. {
  168.     break;
  169. }
  170.     }
  171. }
  172. break;
  173.  
  174.     case WM_KEYDOWN:
  175. switch( wParam )
  176. {
  177. case VK_ESCAPE:
  178. case VK_F12:
  179.     PostMessage(hWnd, WM_CLOSE, 0, 0);
  180.     break;
  181. }
  182. break;
  183.     case WM_DESTROY:
  184. finiObjects();
  185. PostQuitMessage( 0 );
  186. break;
  187.     }
  188.     return DefWindowProc(hWnd, message, wParam, lParam);
  189. } /* WindowProc */
  190. /*
  191.  * This function is called if the initialization function fails
  192.  */
  193. BOOL initFail( HWND hwnd )
  194. {
  195.     finiObjects();
  196.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  197.     DestroyWindow( hwnd );
  198.     return FALSE;
  199. } /* initFail */
  200. /*
  201.  * doInit - do work required for every instance of the application:
  202.  *                create the window, initialize data
  203.  */
  204. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  205. {
  206.     HWND                hwnd;
  207.     WNDCLASS            wc;
  208.     DDSURFACEDESC       ddsd;
  209.     DDSCAPS             ddscaps;
  210.     HRESULT             ddrval;
  211.     /*
  212.      * set up and register window class
  213.      */
  214.     wc.style = CS_HREDRAW | CS_VREDRAW;
  215.     wc.lpfnWndProc = WindowProc;
  216.     wc.cbClsExtra = 0;
  217.     wc.cbWndExtra = 0;
  218.     wc.hInstance = hInstance;
  219.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  220.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  221.     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  222.     wc.lpszMenuName = NAME;
  223.     wc.lpszClassName = NAME;
  224.     RegisterClass( &wc );
  225.     
  226.     /*
  227.      * create a window
  228.      */
  229.     hwnd = CreateWindowEx(
  230. 0,
  231. NAME,
  232. TITLE,
  233. WS_POPUP,
  234. 0,
  235. 0,
  236. GetSystemMetrics(SM_CXSCREEN),
  237. GetSystemMetrics(SM_CYSCREEN),
  238. NULL,
  239. NULL,
  240. hInstance,
  241. NULL );
  242.     if( !hwnd )
  243.     {
  244. return FALSE;
  245.     }
  246.     ShowWindow( hwnd, nCmdShow );
  247.     UpdateWindow( hwnd );
  248.     /*
  249.      * create the main DirectDraw object
  250.      */
  251.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  252.     if( ddrval != DD_OK )
  253.     {
  254. return initFail(hwnd);
  255.     }
  256.     // Get exclusive mode
  257.     ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  258.     if( ddrval != DD_OK )
  259.     {
  260. return initFail(hwnd);
  261.     }
  262.     // Set the video mode to 640x480x8
  263.     ddrval = lpDD->SetDisplayMode( 640, 480, 8);
  264.     if( ddrval != DD_OK )
  265.     {
  266. return initFail(hwnd);
  267.     }
  268.     // Create the primary surface with 1 back buffer
  269.     ddsd.dwSize = sizeof( ddsd );
  270.     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  271.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  272.   DDSCAPS_FLIP |
  273.   DDSCAPS_COMPLEX;
  274.     ddsd.dwBackBufferCount = 1;
  275.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  276.     if( ddrval != DD_OK )
  277.     {
  278. return initFail(hwnd);
  279.     }
  280.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  281.     ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
  282.     if( ddrval != DD_OK )
  283.     {
  284. return initFail(hwnd);
  285.     }
  286.     // Create a offscreen bitmap.
  287.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  288.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  289.     ddsd.dwHeight = 480;
  290.     ddsd.dwWidth = 640;
  291.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSOne, NULL );
  292.     if( ddrval != DD_OK )
  293.     {
  294. return initFail(hwnd);
  295.     }
  296.     // Create another offscreen bitmap.
  297.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSTwo, NULL );
  298.     if( ddrval != DD_OK )
  299.     {
  300. return initFail(hwnd);
  301.     }
  302.     // Create a Direct Draw Palette and associate it with the front buffer
  303.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  304.     if (lpDDPal)
  305. lpDDSPrimary->SetPalette( lpDDPal );
  306.     if( !InitSurfaces() )
  307.     {
  308. return initFail(hwnd);
  309.     }
  310.     // Create a timer to flip the pages
  311.     if( !SetTimer( hwnd, TIMER_ID, TIMER_RATE, NULL ) )
  312.     {
  313. return initFail(hwnd);
  314.     }
  315.     return TRUE;
  316. } /* doInit */
  317. /*
  318.  * WinMain - initialization, message loop
  319.  */
  320. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  321. LPSTR lpCmdLine, int nCmdShow)
  322. {
  323.     MSG         msg;
  324.     lpCmdLine = lpCmdLine;
  325.     hPrevInstance = hPrevInstance;
  326.     if( !doInit( hInstance, nCmdShow ) )
  327.     {
  328. return FALSE;
  329.     }
  330.     while( GetMessage( &msg, NULL, 0, 0 ) )
  331.     {
  332. TranslateMessage(&msg);
  333. DispatchMessage(&msg);
  334.     }
  335.     return msg.wParam;
  336. } /* WinMain */
  337. /*
  338.  * InitSurfaces - This function reads the bitmap file FRNTBACK.BMP
  339.  * and stores half of it in offscreen surface 1 and the other half in 
  340.  * offscreen surface 2.
  341.  */
  342. BOOL InitSurfaces( void )
  343. {
  344.     HBITMAP hbm;
  345.     // Load our bitmap resource.
  346.     hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  347.     if (hbm == NULL)
  348. return FALSE;
  349.     DDCopyBitmap(lpDDSOne, hbm, 0, 0,   640, 480);
  350.     DDCopyBitmap(lpDDSTwo, hbm, 0, 480, 640, 480);
  351.     DeleteObject(hbm);
  352.     return TRUE;
  353. } /* readBMPIntoSurfaces */