home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / boids / winmain.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  14.9 KB  |  566 lines

  1. /*
  2. **-----------------------------------------------------------------------------
  3. **  File:       WinMain.cpp
  4. **  Purpose:    D3D sample showing DrawPrimitive functionality 
  5. **  Notes:
  6. **
  7. **    There are 3 main C++ classes that make this sample work.
  8. **
  9. **        DDDrvMgr:    Enumerates all drivers, modes, devices, etc.
  10. **        D3DWindow:    D3D Frameworks
  11. **        D3DScene:    Sample Scene Renderer
  12. **
  13. **  Copyright (c) 1995 - 1997 by Microsoft, all rights reserved
  14. **-----------------------------------------------------------------------------
  15. */
  16.  
  17. /*
  18. **-----------------------------------------------------------------------------
  19. **  Include files
  20. **-----------------------------------------------------------------------------
  21. */
  22.  
  23. // Note:  Define INITGUID in one and only one file!!!
  24. #define  INITGUID    
  25. #include "Common.h"
  26. #include "Debug.h"
  27. #include "WinMain.h"
  28. #include "WinProc.h"
  29. #include "DrvMgr.h"
  30. #include "D3DWin.h"
  31. #include "D3DScene.h"
  32. #include "boids.h"
  33.  
  34.  
  35. /*
  36. **-----------------------------------------------------------------------------
  37. **  Global Variables
  38. **-----------------------------------------------------------------------------
  39. */
  40.  
  41. // Application variables
  42. HINSTANCE    g_hMainInstance        = NULL;
  43. HWND        g_hMainWindow       = NULL;
  44. HACCEL      g_hMainAccel        = NULL;
  45. HCURSOR        g_hMainCursor        = NULL;
  46.  
  47. LPCTSTR     g_szMainName        = TEXT ("Boids2");
  48. LPCTSTR     g_szMainClass        = TEXT ("BoidsClass");
  49. LPCTSTR     g_szMainTitle        = TEXT ("Boids2 Sample");
  50. LPCTSTR     g_szPaused          = TEXT ("Paused");
  51.  
  52. INT         g_nExitCode         = 0L;
  53.  
  54.  
  55. //
  56. // D3D Variables
  57. //
  58.  
  59. // Driver Management (DD Drivers, modes, D3D devices)
  60. DDDrvMgr    g_DrvMgr;
  61.  
  62. //    D3D framework (DD/D3D interfaces, surfaces, etc.)
  63. LPD3DWindow        g_lpd3dWin;
  64.  
  65. //  The Sample Framework (Materials, lights, textures, rendering, etc.)
  66. LPD3DScene        g_lpd3dScene;
  67.  
  68.  
  69.  
  70. /*
  71. **-----------------------------------------------------------------------------
  72. **  Function Prototypes
  73. **-----------------------------------------------------------------------------
  74. */
  75.  
  76. HRESULT CreateD3DWindow (
  77.     DWORD        dwStyleEx,            /* In:  Standard CreateWindowEx parameters */
  78.     LPCTSTR        lpszClass, 
  79.     LPCTSTR        lpszName, 
  80.     DWORD        dwStyle,
  81.     int            x, 
  82.     int            y, 
  83.     int            nWidth, 
  84.     int            nHeight,
  85.     HWND        hParent, 
  86.     HMENU        hMenu,
  87.     HINSTANCE    hInstance, 
  88.     LPVOID        lpParam, 
  89.  
  90.     BOOL        fUseZBuffer,        /* In:  Use Z-buffer */
  91.     HWND *        lphWnd,                /* Out:    Window handle */
  92.     LPD3DWindow * lpd3dWnd);        /* Out: Created D3DWindow pointer */
  93.  
  94. HRESULT DestroyD3DWindow (void);
  95.  
  96. extern void GetDXVersion (LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform);
  97.  
  98.  
  99.  
  100. /*
  101. **-----------------------------------------------------------------------------
  102. **  Function Definitions
  103. **-----------------------------------------------------------------------------
  104. */
  105.  
  106. /*
  107. **-----------------------------------------------------------------------------
  108. **  Name:       InitMain
  109. **  Purpose:    Initialize Application
  110. **-----------------------------------------------------------------------------
  111. */
  112.  
  113. BOOL InitMain (void)
  114. {
  115.     DWORD dwDxVersion;
  116.     DWORD dwDxPlatform;
  117.  
  118.     DPF (DEBUG_DETAILS, TEXT("InitApp"));
  119.  
  120.     // Get hInstance handle
  121.     g_hMainInstance = (HINSTANCE) GetModuleHandle (NULL);
  122.     if (NULL == g_hMainInstance)
  123.     {
  124.         // Error - GetModule Handle 
  125.  
  126.         DPF (DEBUG_CRITICAL, TEXT("InitApp - GetModuleHandle() failed."));
  127.         return FALSE;
  128.     }
  129.  
  130.     // Check for DX5.0 or greater
  131.     GetDXVersion (&dwDxVersion, &dwDxPlatform);
  132.     if (dwDxVersion < 0x500)
  133.     {
  134.         MessageBox (NULL, TEXT("This App requires DX 5.0 or greater\r\nin order to run."), TEXT("Error"), MB_OK);
  135.         return FALSE;
  136.     }
  137.  
  138.     // Check for Previous instance
  139.     if (! CheckPreviousApp ())
  140.     {
  141.         return FALSE;
  142.     }
  143.  
  144.     // Init main window
  145.     if (! InitMainWindow ())
  146.     {
  147.         return FALSE;
  148.     }
  149.  
  150.     DPF (DEBUG_DETAILS, TEXT("InitApp - Success"));
  151.  
  152.     // Success
  153.     return TRUE;
  154. } // End InitMain
  155.  
  156.  
  157.  
  158. /*
  159. **-----------------------------------------------------------------------------
  160. **  Name:       FiniMain
  161. **  Purpose:    Cleanup Application
  162. **-----------------------------------------------------------------------------
  163. */
  164.  
  165. void FiniMain (void)
  166. {
  167.     DestroyD3DWindow ();
  168.  
  169.     UnregisterClass (g_szMainClass, g_hMainInstance);
  170. } // End FiniMain
  171.   
  172.  
  173.   
  174. /*
  175. **-----------------------------------------------------------------------------
  176. **  Name:       CheckPreviousApp
  177. **  Purpose:    Check for previous instance of this application
  178. **-----------------------------------------------------------------------------
  179. */
  180.  
  181. BOOL CheckPreviousApp (void)
  182. {
  183.     HWND hwndFind;
  184.     HWND hwndLast;
  185.     HWND hwndForeGround;
  186.     DWORD dwFindID;
  187.     DWORD dwForeGroundID;
  188.  
  189.     // Check if application is already running
  190.     hwndFind = FindWindow (g_szMainClass, g_szMainTitle);
  191.     if (hwndFind)
  192.     {
  193.         // Bring previously running application's main
  194.         // window to the user's attention
  195.         hwndForeGround = GetForegroundWindow ();
  196.         dwForeGroundID = GetWindowThreadProcessId (hwndForeGround, NULL);
  197.         dwFindID = GetWindowThreadProcessId (hwndFind, NULL);
  198.  
  199.         // Don't do anything if window is already in foreground
  200.         // Unless it is iconized.
  201.         if ((dwFindID != dwForeGroundID) || (IsIconic (hwndFind)))
  202.         {
  203.             hwndLast = GetLastActivePopup (hwndFind);
  204.             if (IsIconic (hwndLast))
  205.             {
  206.                 ShowWindow (hwndLast, SW_RESTORE);
  207.             }
  208.  
  209.             BringWindowToTop (hwndLast);
  210.             SetForegroundWindow (hwndLast);
  211.         }
  212.  
  213.         // Prevent additional instance's of this application
  214.         // from running
  215.  
  216.         DPF (DEBUG_WARN, TEXT("CheckPrevious App - Another instance of this app is already running."));
  217.         return FALSE;
  218.     }
  219.  
  220.     return TRUE;
  221. } // End CheckPreviousApp
  222.   
  223.   
  224.  
  225. /*
  226. **-----------------------------------------------------------------------------
  227. **  Name:       RunMain
  228. **  Purpose:    Main Message Pump
  229. **-----------------------------------------------------------------------------
  230. */
  231.  
  232. void RunMain (void)
  233. {
  234.     MSG msg;
  235.  
  236.     DPF (DEBUG_DETAILS, TEXT("RunMain - Enter"));
  237.  
  238.     if ((! g_hMainInstance) || (! g_hMainWindow))
  239.     {
  240.         return;
  241.     }
  242.  
  243.     g_hMainAccel = LoadAccelerators (g_hMainInstance, MAKEINTRESOURCE (IDR_MAIN_ACCEL));
  244.   
  245.     //
  246.     //  The Main Message loop
  247.     //
  248.     //  Note:  In order to catch Idle behavior we use PeekMessage instead of GetMessage
  249.     //
  250.     while (TRUE)
  251.     {
  252.         while (TRUE)
  253.         {
  254.  
  255.             if (! PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  256.             {
  257.                 // App is Idle
  258.                 break;
  259.             }
  260.  
  261.             // Exit App ?!?
  262.             if (msg.message == WM_QUIT)
  263.             {
  264.                 DPF (DEBUG_DETAILS, TEXT("RunMain - Exit"));
  265.                 g_nExitCode = msg.wParam;
  266.                 return;
  267.             }
  268.  
  269.             if (g_hMainAccel)
  270.             {
  271.                 if (! TranslateAccelerator (g_hMainWindow, g_hMainAccel, &msg))
  272.                 {
  273.                     TranslateMessage (&msg);
  274.                     DispatchMessage (&msg);
  275.                 }
  276.             }
  277.             else
  278.             {
  279.                 TranslateMessage (&msg);
  280.                 DispatchMessage (&msg);
  281.             }
  282.         }
  283.       
  284.         // Do some Idle processing
  285.         OnIdle (g_hMainWindow);
  286.     } // End While
  287.  
  288. } // End RunMain
  289.  
  290.  
  291.   
  292. /*
  293. **-----------------------------------------------------------------------------
  294. **  Name:       WinMain
  295. **  Purpose:    Application EntryPoint
  296. **-----------------------------------------------------------------------------
  297. */
  298.  
  299. INT WINAPI WinMain(
  300.     HINSTANCE   hInstance,        // handle to current instance
  301.     HINSTANCE   hPrevInstance,    // handle to previous instance
  302.     LPSTR       lpCmdLine,        // pointer to command line
  303.     INT         nShowCmd)         // show state of window
  304. {
  305.     g_nExitCode = 0;
  306.     
  307.     DPF (DEBUG_DETAILS, TEXT("WinMain - Enter"));
  308.  
  309.     //  Initialize App
  310.     if (! InitMain ())
  311.         return g_nExitCode;
  312.  
  313.     //  Main Message Loop
  314.     RunMain ();
  315.  
  316.     //  Cleanup App
  317.     FiniMain ();
  318.  
  319.     //  Success
  320.     DPF (DEBUG_DETAILS, TEXT("WinMain - Exit, status = %08lX"), (DWORD)g_nExitCode);
  321.     return g_nExitCode;
  322. } // End WinMain
  323.  
  324.  
  325.  
  326.  /*
  327. **-----------------------------------------------------------------------------
  328. **  Name:       InitMainWindow
  329. **  Purpose:    
  330. **-----------------------------------------------------------------------------
  331. */
  332.  
  333. BOOL InitMainWindow (void)
  334. {
  335.     HRESULT        hResult;
  336.     WNDCLASS    wc;
  337.     HWND        hWnd;
  338.     DWORD        dwStyle, dwStyleEx;
  339.  
  340.     DPF (DEBUG_DETAILS, TEXT("InitMainWindow - Enter"));
  341.  
  342.     g_hMainCursor = LoadCursor ((HINSTANCE)NULL, IDC_ARROW);
  343.  
  344.     // Register Main Window Class
  345.     wc.style            = CS_DBLCLKS; 
  346.     wc.lpfnWndProc      = (WNDPROC)D3DWindowProc; 
  347.     wc.cbClsExtra       = 0; 
  348.     wc.cbWndExtra       = 4;  // Reserve space for lpd3dWindow pointer
  349.     wc.hInstance        = g_hMainInstance; 
  350.     wc.hIcon            = LoadIcon (g_hMainInstance, MAKEINTRESOURCE (IDI_MAIN_ICON));
  351.     wc.hCursor          = g_hMainCursor;
  352.     wc.hbrBackground    = (HBRUSH)GetStockObject (WHITE_BRUSH);
  353.     wc.lpszMenuName     = MAKEINTRESOURCE (IDR_MAIN_MENU); 
  354.     wc.lpszClassName    = g_szMainClass; 
  355.  
  356.     if (! RegisterClass (&wc))
  357.     {
  358.         // Error - Register class failed
  359.         DPF (DEBUG_CRITICAL, TEXT("InitMainWindow - RegisterClass failed."));
  360.         return FALSE;
  361.     }
  362.  
  363.  
  364.     // We want a popup window
  365.     dwStyleEx = WS_EX_APPWINDOW;
  366.     dwStyle   = WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX;
  367.  
  368.     //
  369.     // Create Main Window
  370.     //
  371.     hResult = CreateD3DWindow (dwStyleEx, 
  372.                                g_szMainClass,
  373.                                g_szMainTitle,
  374.                                dwStyle,
  375.                                0, 0, 640, 480,
  376.                                NULL,
  377.                                NULL,
  378.                                g_hMainInstance,
  379.                                NULL,
  380.                                TRUE,    // Use Z-Buffer
  381.                                &hWnd,
  382.                                &g_lpd3dWin);
  383.     if (FAILED (hResult))
  384.     {
  385.         // Error - CreateWindow failed
  386.         DPF (DEBUG_CRITICAL, TEXT("InitMainWindow - CreateWindow failed."));
  387.         return FALSE;
  388.     }
  389.  
  390.     //
  391.     // Create our D3D scene
  392.     //
  393.  
  394.     g_lpd3dScene = new D3DScene;
  395.     if (! g_lpd3dScene)
  396.     {
  397.         // Error - Construct D3D Scene failed
  398.         DPF (DEBUG_CRITICAL, TEXT("InitMainWindow - Not enough memory for D3D scene."));
  399.         return FALSE;
  400.     }
  401.  
  402.     // Attach our D3DScene to the Window
  403.     hResult = g_lpd3dWin->AttachScene (g_lpd3dScene);
  404.     if (FAILED (hResult))
  405.     {
  406.         // Error - Attaching our D3D Scene to our D3D Window failed
  407.         DPF (DEBUG_CRITICAL, TEXT("InitMainWindow - AttachScene failed."));
  408.         return FALSE;
  409.     }
  410.  
  411.     g_hMainWindow = hWnd;
  412.  
  413.     // Success
  414.     DPF (DEBUG_DETAILS, TEXT("InitMainWindow - Success"));
  415.     return TRUE;
  416. } // End InitMainWindow
  417.  
  418.   
  419. /*
  420. **-----------------------------------------------------------------------------
  421. ** Name:    CreateD3DWindow
  422. ** Purpose: Creates a simple D3D window 
  423. ** Notes:   
  424. **-----------------------------------------------------------------------------
  425. */
  426.  
  427. HRESULT CreateD3DWindow (
  428.     DWORD        dwStyleEx,            /* In:  CreateWindowEx parameters */
  429.     LPCTSTR        lpszClass, 
  430.     LPCTSTR        lpszName, 
  431.     DWORD        dwStyle,
  432.     int            x, 
  433.     int            y, 
  434.     int            nWidth, 
  435.     int            nHeight,
  436.     HWND        hParent, 
  437.     HMENU        hMenu,
  438.     HINSTANCE    hInstance, 
  439.     LPVOID        lpParam, 
  440.  
  441.     BOOL        fUseZBuffer,        /* In:  Use Z-buffer */
  442.     HWND *        lphWnd,                /* Out:    Window handle */
  443.     LPD3DWindow * lpd3dWnd)            /* Out: Created D3DWindow pointer */
  444. {
  445.     HRESULT             hResult;
  446.     HWND                hWnd;
  447.     LPD3DWindow         lpWnd;
  448.  
  449.     // Check Parameters
  450.     if (! lpszClass)
  451.     {
  452.         REPORTERR (DDERR_INVALIDPARAMS);
  453.         return DDERR_INVALIDPARAMS;
  454.     }
  455.  
  456.     // Fill in defaults, if missing
  457.     if (! hInstance)
  458.         hInstance = GetModuleHandle (NULL);
  459.  
  460.     if (! hParent)
  461.         hParent = GetDesktopWindow ();
  462.  
  463.     // Create D3D Window 
  464.     lpWnd = new D3DWindow ();
  465.     if (! lpWnd)
  466.     {
  467.         // Error, not enough memory
  468.         REPORTERR (DDERR_OUTOFMEMORY);
  469.         return DDERR_OUTOFMEMORY;
  470.     }
  471.  
  472.     // Create Extended Window
  473.     hWnd = CreateWindowEx (
  474.                 dwStyleEx,                // extended window style
  475.                 lpszClass,                // window class
  476.                 lpszName,                // window name (title)
  477.                 dwStyle,                // window style
  478.                 x,                        // horizontal position of window
  479.                 y,                        // vertical position of window
  480.                 nWidth,                    // window width
  481.                 nHeight,                // window height
  482.                 hParent,                // handle to parent window
  483.                 hMenu,                  // handle to menu
  484.                 hInstance,              // handle to app instance
  485.                 lpParam);               // Extra Data
  486.     if (! hWnd)
  487.     {
  488.         // Error, unable to create window
  489.         delete lpWnd;
  490.         REPORTERR (DDERR_GENERIC);
  491.         return DDERR_GENERIC;
  492.     }
  493.  
  494.     //
  495.     //  Gotcha:  You must Show the window before you change to Fullscreen
  496.     //           Otherwise the following can happen.
  497.     //           1. SetCooperativeLevel (DDSCL_EXCLUSIVE) works
  498.     //             2. SetDisplayMode (w,h,bpp) loses the exclusive mode state
  499.     //                because the window is not fully initialized.
  500.     //                (DDraw gets confused by the responses it gets from the window)
  501.     //             3. CreateSurface (PRIMARY | FLIP) fails with DDERR_NOEXCLUSIVEMODE.
  502.     //                As the exlusive mode state has been lost
  503.     //
  504.  
  505.     // Show the Window and Paint it's contents
  506.     ShowWindow (hWnd, SW_SHOWDEFAULT);
  507.     UpdateWindow (hWnd);
  508.  
  509.     // Create D3DWindow from hWnd
  510.     hResult = lpWnd->Create (hWnd);
  511.     if (FAILED (hResult))
  512.     {
  513.         // Error, unable to create window
  514.         delete lpWnd;
  515.         DestroyWindow (hWnd);
  516.         return hResult;
  517.     }
  518.  
  519.     // Return results
  520.     if (lphWnd)
  521.         *lphWnd = hWnd;
  522.     if (lpd3dWnd)
  523.         *lpd3dWnd = lpWnd;
  524.  
  525.     // Success
  526.     return DD_OK;
  527. } // End CreateD3DWindow
  528.  
  529.  
  530.  
  531. /*
  532. **-----------------------------------------------------------------------------
  533. ** Name:    DestroyD3DWindow
  534. ** Purpose: Destroys a D3DWindow (window and D3DWindow object)
  535. **-----------------------------------------------------------------------------
  536. */
  537.  
  538. HRESULT DestroyD3DWindow (void)
  539. {
  540.     // Check Parameters
  541.     if ((g_hMainWindow) && (IsWindow (g_hMainWindow)))
  542.     {
  543.         DestroyWindow (g_hMainWindow);
  544.         g_hMainWindow = NULL;
  545.     }
  546.  
  547.     // Free memory associated with D3DWindow Object
  548.     if (g_lpd3dWin)
  549.     {
  550.         delete g_lpd3dWin;
  551.         g_lpd3dWin = NULL;
  552.     }
  553.  
  554.     // Sucess
  555.     return DD_OK;
  556. } // End DestroyD3DWindow
  557.  
  558.   
  559. /*
  560. **-----------------------------------------------------------------------------
  561. **  End of File
  562. **-----------------------------------------------------------------------------
  563. */
  564.  
  565.  
  566.