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

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  3.  *
  4.  *  File:       pick3.cpp
  5.  *
  6.  *  This sample takes a empty direct draw primary surface which is created 
  7.  *  in this file and passed to the DAView object for rendering.
  8.  *
  9.  ***************************************************************************/
  10. #define NAME "PICK3"
  11. #define TITLE "PICK3"
  12. #define WIN32_LEAN_AND_MEAN
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include <ddrawex.h>
  16. #include "dxa.h"
  17. BOOL            gExclusive = FALSE;
  18. BOOL            bPaused = FALSE;
  19. HWND            hWndMain;
  20. DXA Danim;
  21. IDirectDrawFactory      *lpDDF;
  22. LPDIRECTDRAW            lpDD;           // DirectDraw object
  23. LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
  24. LPDIRECTDRAWSURFACE     lpDDSDA;        // Offscreen surface for DA
  25. LPDIRECTDRAWCLIPPER     lpClipper;      // Clipper for the primary surface
  26. BOOL                    bActive;        // is application active?
  27. RECT                    windowRect;     // windows' client rectangle
  28. /*
  29.  * releaseSurfaces
  30.  *
  31.  * Release the global surfaces and clipper.
  32.  */
  33. void releaseSurfaces( void )
  34. {
  35.     if( lpDDSPrimary != NULL )
  36.     {
  37.         lpDDSPrimary->Release();
  38.         lpDDSPrimary = NULL;
  39.     }
  40.     if( lpDDSDA != NULL )
  41.     {
  42.         lpDDSDA->Release();
  43.         lpDDSDA = NULL;
  44.     }
  45.     if( lpClipper != NULL )
  46.     {
  47.         lpClipper->Release();
  48.         lpClipper = NULL;
  49.     }
  50. /*
  51.  * finiObjects
  52.  *
  53.  * Finish with all objects we use; release them
  54.  */
  55. static void finiObjects( void )
  56. {
  57.     if( lpDD != NULL )
  58.     {
  59.         releaseSurfaces();
  60.         lpDD->Release();
  61.         lpDD = NULL;
  62.     }
  63.     // Clean up the screen on exit
  64.     RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
  65.                      RDW_ALLCHILDREN );
  66. } /* finiObjects */
  67. /*
  68.  * initFail
  69.  *
  70.  * This function is called if the initialization function fails
  71.  */
  72. BOOL initFail( HWND hWnd, LPCTSTR msg )
  73. {
  74.     finiObjects();
  75.     MessageBox( hWnd, msg, TITLE, MB_OK );
  76.     DestroyWindow( hWnd );
  77.     return FALSE;
  78. } /* initFail */
  79. /*
  80.  * createSurfaces
  81.  *
  82.  * Create the front and back buffers.
  83.  */
  84. BOOL createSurfaces( void )
  85. {
  86.     HRESULT             ddrval;
  87.     DDSURFACEDESC       ddsd;
  88.     
  89.     // Create the primary surface
  90.     ddsd.dwSize = sizeof( ddsd );
  91.     ddsd.dwFlags = DDSD_CAPS;
  92.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  93.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  94.     if( ddrval != DD_OK )
  95.         return false;
  96.     if(!gExclusive)
  97.     {
  98.         //
  99.         // now create a DirectDrawClipper object.
  100.         //
  101.         ddrval = lpDD->CreateClipper(0, &lpClipper, NULL);
  102.         if( ddrval == DD_OK )
  103.         {
  104.             ddrval = lpClipper->SetHWnd(0, hWndMain);
  105.             if( ddrval == DD_OK )
  106.             {
  107.                 ddrval = lpDDSPrimary->SetClipper(lpClipper);
  108.             }
  109.         }
  110.         if( ddrval != DD_OK )
  111.             return false;
  112.     }
  113.     //
  114.     // Create a DirectDrawSurface to hand to Direct Animation.
  115.     //
  116.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  117.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  118.     ddsd.dwWidth = WINDOW_WIDTH;
  119.     ddsd.dwHeight = WINDOW_HEIGHT;
  120.     ddrval = lpDD->CreateSurface(&ddsd, &lpDDSDA, NULL);
  121.     if (ddrval != DD_OK)
  122.         return false;
  123.     return true;
  124. } /* createSurfaces */
  125. /*
  126.  * recreateSurfaces
  127.  *
  128.  * The screen resolution or bitdepth has changed, re-create
  129.  * all surfaces.
  130.  */
  131. BOOL recreateSurfaces( void )
  132. {
  133.     releaseSurfaces();
  134.     if (createSurfaces())
  135.     {
  136.         return Danim.resetDXASurfaces(lpDDSDA);
  137.     }
  138.     return false;
  139. } /* recreateSurfaces */
  140. /*
  141.  * restoreAll
  142.  *
  143.  * Restore all lost objects
  144.  */
  145. BOOL restoreAll( void )
  146. {
  147.     HRESULT     ddrval;
  148.     ddrval = lpDDSPrimary->Restore();
  149.     if (ddrval == DDERR_WRONGMODE)
  150.     {
  151.         if (recreateSurfaces())
  152.             return true;
  153.     }
  154.     else if (ddrval == DD_OK)
  155.     {
  156.         ddrval = lpDDSDA->Restore();
  157.     }
  158.     return initFail(hWndMain, "DirectDraw: Can't Recreate Surfaces");
  159. } /* restoreAll */
  160. /*
  161.  * updateFrame
  162.  * 
  163.  * Decide what needs to be blitted next, wait for flip to complete,
  164.  * then flip the buffers.
  165.  */
  166. void updateFrame( void )
  167. {
  168.     static DWORD        lastTickCount = 0;
  169.     static int          currentFrame = 0;
  170.     static BOOL         haveBackground = FALSE;
  171.     DWORD               thisTickCount;
  172.     DWORD               delay = 17;
  173.     HRESULT             ddrval;
  174.     thisTickCount = GetTickCount();
  175.     if((thisTickCount - lastTickCount) <= delay)
  176.     {
  177.         return;
  178.     }
  179.     thisTickCount = GetTickCount();
  180.     if((thisTickCount - lastTickCount) > delay)
  181.     {
  182.         // Move to next frame;
  183.         lastTickCount = thisTickCount;
  184.         currentFrame++;
  185.         if(currentFrame > 59)
  186.         {
  187.             currentFrame = 0;
  188.         }
  189.     }
  190.     // DA doesn't like lost surface.  We should restore lost surface
  191.     // before asking DA to render.
  192.     if (lpDDSDA && lpDDSDA->IsLost() == DDERR_SURFACELOST)
  193.     {
  194.         // This function will destroy the window if failed.        
  195.         if (!restoreAll())
  196.             return;
  197.     }
  198.     // Ask DA to render to the DA surface the next image/sound for _view.
  199.     Danim.tick();
  200.     // Blit from the DA surface to the screen.
  201.     RECT daRect;
  202.     daRect.left = 0;
  203.     daRect.top = 0;
  204.     daRect.right = WINDOW_WIDTH;
  205.     daRect.bottom = WINDOW_HEIGHT;
  206.     RECT screenRect;
  207.     screenRect.left = windowRect.left;
  208.     screenRect.top = windowRect.top;
  209.     screenRect.right = windowRect.left + WINDOW_WIDTH;
  210.     screenRect.bottom = windowRect.top + WINDOW_HEIGHT;
  211.         
  212.     while( 1 )
  213.     {
  214.         ddrval = lpDDSPrimary->Blt(&screenRect, lpDDSDA,
  215.                                    &daRect, DDBLT_WAIT, NULL);
  216.         if( ddrval == DD_OK )
  217.         {
  218.             break;
  219.         }
  220.         if( ddrval == DDERR_SURFACELOST )
  221.         {
  222.             ddrval = restoreAll();
  223.             if( ddrval != DD_OK )
  224.             {
  225.                 return;
  226.             }
  227.         }
  228.         if( ddrval != DDERR_WASSTILLDRAWING )
  229.         {
  230.             return;
  231.         }
  232.     }
  233. } /* updateFrame */
  234. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  235.                             WPARAM wParam, LPARAM lParam )
  236. {
  237.     switch( message )
  238.     {
  239.     case WM_SIZE:
  240.     case WM_MOVE:
  241.         if (IsIconic(hWnd))
  242.         {
  243.             bPaused = true;
  244.         }
  245.         if (!gExclusive) 
  246.         {
  247.             GetClientRect(hWnd, &windowRect);
  248.             ClientToScreen(hWnd, (LPPOINT)&windowRect);
  249.             ClientToScreen(hWnd, (LPPOINT)&windowRect+1);
  250.         } else {
  251.             SetRect(&windowRect, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  252.         }
  253.         break;
  254.     case WM_ACTIVATEAPP:
  255.         bActive = wParam && GetForegroundWindow() == hWnd;
  256.         // Unpause when we're no longer iconic.
  257.         if (bPaused && bActive)
  258.         {
  259.             bPaused = false;
  260.         }
  261.         break;
  262.     case WM_SETCURSOR:
  263.         if (gExclusive && bActive)
  264.         {
  265.             SetCursor(NULL);
  266.             return TRUE;
  267.         }
  268.         break;
  269.         
  270.     case WM_CREATE:
  271.         break;
  272.     case WM_KEYDOWN:
  273.         switch( wParam )
  274.         {
  275.         case VK_ESCAPE:
  276.         case VK_F12:
  277.             PostMessage(hWnd,WM_CLOSE,0,0);
  278.             break;
  279.         }
  280.         break;
  281.     case WM_DESTROY:
  282.         finiObjects();
  283.         PostQuitMessage( 0 );
  284.         break;
  285.     }
  286.     return DefWindowProc(hWnd, message, wParam, lParam);
  287. } /* WindowProc */
  288. /*
  289.  * doInit - do work required for every instance of the application:
  290.  *                create the window, initialize data
  291.  */
  292. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  293. {
  294.     WNDCLASS            wc;
  295.     HRESULT             ddrval;
  296.     /*
  297.      * set up and register window class
  298.      */
  299.     wc.style = CS_HREDRAW | CS_VREDRAW;
  300.     wc.lpfnWndProc = WindowProc;
  301.     wc.cbClsExtra = 0;
  302.     wc.cbWndExtra = 0;
  303.     wc.hInstance = hInstance;
  304.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  305.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  306.     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  307.     wc.lpszMenuName = NAME;
  308.     wc.lpszClassName = NAME;
  309.     RegisterClass( &wc );
  310.     
  311.     /*
  312.      * create a window
  313.      */
  314.     DWORD wndStyle = WS_OVERLAPPEDWINDOW;
  315.     if( gExclusive)
  316.         wndStyle = WS_POPUP;
  317.     hWndMain = CreateWindowEx(
  318.         WS_EX_APPWINDOW,
  319.         NAME,
  320.         TITLE,
  321.         wndStyle,
  322.         0,
  323.         0,
  324.         WINDOW_WIDTH,
  325.         WINDOW_HEIGHT,
  326.         NULL,
  327.         NULL,
  328.         hInstance,
  329.         NULL );
  330.     if( !hWndMain )
  331.     {
  332.         return FALSE;
  333.     }
  334.     ShowWindow( hWndMain, nCmdShow );
  335.     UpdateWindow( hWndMain );
  336.     /*
  337.      * create the main DirectDraw object
  338.      */
  339.     
  340.     ddrval = CoCreateInstance(CLSID_DirectDrawFactory,
  341.                               NULL, CLSCTX_INPROC_SERVER,
  342.                               IID_IDirectDrawFactory,
  343.                               (void **) & lpDDF);
  344.     char strDDFailed[] = "DirectDraw Init Failed";
  345.     if( ddrval != DD_OK )
  346.     {
  347.         return initFail(hWndMain, strDDFailed);
  348.     }
  349.     ddrval = lpDDF->CreateDirectDraw(NULL, hWndMain, DDSCL_NORMAL, 0, NULL, &lpDD);
  350.     if( ddrval != DD_OK )
  351.     {
  352.         return initFail(hWndMain, strDDFailed);
  353.     }
  354.     // Get exclusive mode if requested
  355.     if(gExclusive)
  356.     {
  357.         ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  358.     }
  359.     else
  360.     {
  361.         ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_NORMAL );
  362.     }
  363.     if( ddrval != DD_OK )
  364.     {
  365.         return initFail(hWndMain, strDDFailed);
  366.     }
  367.     if (!createSurfaces())
  368.     {
  369.         return initFail(hWndMain, strDDFailed);
  370.     }
  371.     // Create a DAView object and construct the model.
  372.     if (!Danim.initDXAViewObj(lpDDSDA))
  373.     {
  374.         return initFail(hWndMain, "DirectX Animation Init FAILED");
  375.     }
  376.     return TRUE;
  377. } /* doInit */
  378. /*
  379.  * WinMain - initialization, message loop
  380.  */
  381. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  382.                         LPSTR lpCmdLine, int nCmdShow)
  383. {
  384.     MSG         msg;
  385.     LPSTR       c;
  386.     for(c=lpCmdLine; *c != ''; c++)
  387.     {
  388.         switch( *c )
  389.         {
  390.             case 'X': gExclusive = TRUE; break;
  391.         }
  392.     }
  393.     
  394.     if( !doInit( hInstance, nCmdShow ) )
  395.     {
  396.         return FALSE;
  397.     }
  398.     while( 1 )
  399.     {
  400.         if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  401.         {
  402.             if( !GetMessage( &msg, NULL, 0, 0 ) )
  403.                 return msg.wParam;
  404.             TranslateMessage(&msg); 
  405.             DispatchMessage(&msg);
  406.         }
  407.         else if (!bPaused && (bActive || !gExclusive))
  408.         {
  409.             updateFrame();
  410.         }
  411.         else
  412.         {
  413.             WaitMessage();
  414.         }
  415.     }
  416. } /* WinMain */