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 / pplane / winproc.cpp < prev    next >
C/C++ Source or Header  |  1997-07-14  |  39KB  |  1,571 lines

  1. /*
  2. **-----------------------------------------------------------------------------
  3. **  File:       WinProc.cpp
  4. **  Purpose:    A sample windows proc for supporting D3D.
  5. **  Notes:
  6. **
  7. **
  8. **  Copyright (c) 1995 - 1997 by Microsoft, all rights reserved
  9. **-----------------------------------------------------------------------------
  10. */
  11.  
  12. /*
  13. **-----------------------------------------------------------------------------
  14. **    Include Files
  15. **-----------------------------------------------------------------------------
  16. */
  17.  
  18. #include "WinProc.h"
  19. #include "WinMain.h"
  20. #include "Debug.h"
  21.  
  22.  
  23.  
  24. /*
  25. **-----------------------------------------------------------------------------
  26. **    Local Typedefs
  27. **-----------------------------------------------------------------------------
  28. */
  29.  
  30. typedef struct tagChangeDDInfo {
  31.     DDDrvInfo  * lpDrvOrig;            // Original Driver
  32.     DDDrvInfo  * lpDrvNew;            // New Driver (user choice)
  33.     
  34.     D3DDevInfo * lpDevOrig;            // Original D3D device
  35.     D3DDevInfo * lpDevNew;            // New D3D device (user choice)
  36.  
  37.     DDModeInfo * lpModeOrig;        // Orignal Mode
  38.     DDModeInfo * lpModeNew;            // New Mode (user choice)
  39. } ChangeDDInfo;
  40. typedef ChangeDDInfo * LPChangeDDInfo;
  41.  
  42.  
  43.  
  44. /*
  45. **-----------------------------------------------------------------------------
  46. **    Local Variables
  47. **-----------------------------------------------------------------------------
  48. */
  49.  
  50. // Used for 3Dfx Voodoo driver detection below
  51. const GUID guid3DfxVoodoo = {
  52.     0x3A0CFD01,
  53.     0x9320,
  54.     0x11CF,
  55.     0xAC,0xA1,0x00,0xA0,0x24,0x13,0xC2,0xE2
  56. };
  57.  
  58.  
  59.  
  60. /*
  61. **-----------------------------------------------------------------------------
  62. **    Local function prototypes
  63. **-----------------------------------------------------------------------------
  64. */
  65.  
  66. // About message proc
  67. BOOL FAR PASCAL AboutBoxProc (HWND hWnd, UINT uiMsg,
  68.                               WPARAM wParam, LPARAM lParam);
  69.  
  70.  
  71. /*
  72. **-----------------------------------------------------------------------------
  73. **    Local function prototypes
  74. **-----------------------------------------------------------------------------
  75. */
  76.  
  77. // Change Dialog
  78. BOOL DlgDriversInit (HWND hDlg);
  79. BOOL DlgDevicesInit (HWND hDlg);
  80. BOOL DlgModesInit (HWND hDlg);
  81.  
  82. int _cdecl CompareModes (const void* element1, const void* element2);
  83.  
  84. LPDDDrvInfo  DlgGetDriver (HWND hDlg);
  85. LPD3DDevInfo DlgGetDevice (HWND hDlg);
  86. LPDDModeInfo DlgGetMode (HWND hDlg);
  87.  
  88. BOOL FAR PASCAL ChangeDriverProc (HWND hWnd, UINT uiMsg,
  89.                                   WPARAM wParam, LPARAM lParam);
  90. void OnChangeDriver (HWND hWindow, int idDialog);
  91.  
  92.  
  93.  
  94. /*
  95. **-----------------------------------------------------------------------------
  96. **    Functions
  97. **-----------------------------------------------------------------------------
  98. */
  99.  
  100. /*
  101. **-----------------------------------------------------------------------------
  102. **  Name:       D3DWindowProc
  103. **  Purpose:    handles windows messages for D3DWindow's
  104. **-----------------------------------------------------------------------------
  105. */
  106.  
  107. LRESULT CALLBACK D3DWindowProc (
  108.     HWND    hWindow,
  109.     UINT    uiMsg,
  110.     WPARAM  wParam,
  111.     LPARAM  lParam)
  112. {
  113.     LONG lResult;
  114.  
  115.     //
  116.     // Windows messages
  117.     //
  118.     switch (uiMsg)
  119.     {
  120.     case WM_ACTIVATE:
  121.         // Note:  Do we need to handle this ?!?
  122.         break;
  123.  
  124.     case WM_ACTIVATEAPP:
  125.         return OnActivateApp (hWindow, wParam, lParam);
  126.  
  127.     case WM_CLOSE:
  128.         return OnClose (hWindow);
  129.  
  130.     case WM_COMMAND:
  131.         return OnCommand (hWindow, wParam, lParam);
  132.  
  133.     case WM_CREATE:
  134.         return OnCreate (hWindow);
  135.             
  136.     case WM_DESTROY:
  137.         return OnDestroy (hWindow);
  138.  
  139.     case WM_DISPLAYCHANGE:
  140.         return OnDisplayChange (hWindow);
  141.  
  142.     case WM_ERASEBKGND:
  143.         return OnEraseBackground (hWindow, wParam, lParam);
  144.  
  145.     case WM_GETMINMAXINFO:
  146.         return OnGetMinMaxInfo (hWindow, (LPMINMAXINFO) lParam);
  147.  
  148.     case WM_MOVE:
  149.         return OnMove (hWindow, (INT)LOWORD(lParam), (INT)HIWORD(lParam));
  150.  
  151.     case WM_PAINT:
  152.     {
  153.         HDC         hdc;
  154.         PAINTSTRUCT ps;
  155.  
  156.         hdc = BeginPaint (hWindow, &ps);            
  157.         lResult = OnPaint (hWindow, hdc, &ps);
  158.         EndPaint (hWindow, &ps);
  159.     }
  160.         return lResult;
  161.  
  162.  
  163.     case WM_PALETTECHANGED:
  164.         // Note:  We need to support this
  165.         break;
  166.  
  167.     case WM_QUERYNEWPALETTE:
  168.         // Note:  We need to support this
  169.         break;
  170.  
  171.     case WM_SIZE:
  172.         return OnSize (hWindow, (INT)LOWORD(lParam), (INT)HIWORD(lParam));
  173.      
  174.      //
  175.      // D3D Window messages
  176.      //  
  177.     case D3DWIN_GET_VALID:       // Get valid size
  178.         {
  179.         LPD3DWindow lpd3dWindow;
  180.     
  181.         //    Get D3DWindow pointer
  182.         lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  183.         if (! lpd3dWindow)
  184.             return FALSE;
  185.         return lpd3dWindow->isValid();
  186.         }
  187.  
  188.     case D3DWIN_GET_POINTER:
  189.         //    Get D3DWindow pointer
  190.         return (LRESULT)GetWindowLong (hWindow, GWL_USERDATA);
  191.  
  192.     case D3DWIN_GET_SURFACE:
  193.         {
  194.         LPD3DWindow lpd3dWindow;
  195.     
  196.         //    Get D3DWindow pointer
  197.         lpd3dWindow =  (LPD3DWindow)(void *)GetWindowLong (hWindow, GWL_USERDATA);
  198.         if (! lpd3dWindow)
  199.             return NULL;
  200.         return (LPARAM)(lpd3dWindow->GetRender ());
  201.         }
  202.  
  203.     case D3DWIN_INIT:
  204.         return OnD3DInit (hWindow, (LPD3DWindow) lParam);
  205.  
  206.     case D3DWIN_FINI:
  207.         return OnD3DFini (hWindow, (LPD3DWindow) lParam);
  208.  
  209.     case D3DWIN_CHANGED_DRIVER:
  210.         return OnD3DChangeDriver (hWindow);
  211.  
  212.     case D3DWIN_CHANGED_DEVICE:
  213.         return OnD3DChangeDevice (hWindow);
  214.  
  215.     case D3DWIN_CHANGED_MODE:
  216.         return OnD3DChangeMode (hWindow);
  217.     } // End Switch
  218.  
  219.    // Do Default window behavior
  220.    return (DefWindowProc (hWindow, uiMsg, wParam, lParam));
  221. } // End D3DWindowProc
  222.  
  223.  
  224.  
  225. /*
  226. **-----------------------------------------------------------------------------
  227. **  Name:       AboutBoxProc
  228. **  Purpose:    handles messages for About Dialog box
  229. **-----------------------------------------------------------------------------
  230. */
  231. BOOL
  232. FAR PASCAL AboutBoxProc (HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  233. {
  234.     switch (uiMsg)
  235.     {
  236.     case WM_COMMAND:
  237.         if (LOWORD(wParam) == IDOK)
  238.             EndDialog (hWnd, TRUE);
  239.         break;
  240.  
  241.     case WM_INITDIALOG:
  242.         return TRUE;
  243.     }
  244.     return FALSE;
  245. } // End AboutBoxProc 
  246.  
  247.  
  248.   
  249. /*
  250. **-----------------------------------------------------------------------------
  251. **  Name:       OnAbout
  252. **  Purpose:    Display About Dialog
  253. **-----------------------------------------------------------------------------
  254. */
  255.  
  256. LRESULT OnAbout (HWND hWindow)
  257. {
  258.     HINSTANCE hInstance;
  259.  
  260.     if ((! hWindow) || (! IsWindow (hWindow)))
  261.         return 0L;
  262.  
  263.     hInstance = (HINSTANCE) GetWindowLong (hWindow, GWL_HINSTANCE);
  264.     if (! hInstance)
  265.         return 0L;
  266.  
  267.     // Pause App
  268.     OnPause (hWindow, TRUE);
  269.  
  270.     // Do About Dialog here
  271.     DialogBox (hInstance, MAKEINTRESOURCE (IDD_ABOUT), hWindow, (DLGPROC)AboutBoxProc);
  272.  
  273.     // UnPause app
  274.     OnPause (hWindow, FALSE);
  275.  
  276.     return 0L;
  277. } // End OnAbout
  278.  
  279.  
  280.   
  281. /*
  282. **-----------------------------------------------------------------------------
  283. **  Name:       OnActivateApp
  284. **  Purpose:    ActivateApp
  285. **  Note:
  286. **        always let it fall through to Default window proc
  287. **        to set up keyboard focus properly, etc.
  288. **-----------------------------------------------------------------------------
  289. */
  290.  
  291. LRESULT OnActivateApp (HWND hWindow, WPARAM wParam, LPARAM lParam)
  292. {
  293.     BOOL fActive = (BOOL)wParam;
  294.  
  295.     // Get D3D Window pointer
  296.     LPD3DWindow lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  297.  
  298.     if (fActive)
  299.     {
  300.         // Reactivating - Realize current palette
  301.         if (lpd3dWindow)
  302.         {
  303.             lpd3dWindow->turnActiveOn ();
  304.             lpd3dWindow->RealizePalette ();
  305.         }
  306.     }
  307.     else
  308.     {
  309.         //
  310.         //  If we have been deactivated invalidate
  311.         //  to show the paused display.
  312.         //
  313.         if (lpd3dWindow)
  314.         {
  315.             lpd3dWindow->turnActiveOff ();
  316.             InvalidateRect (hWindow, NULL, FALSE);
  317.         }
  318.  
  319.     }
  320.  
  321.     // Do default behavior
  322.     return DefWindowProc (hWindow, WM_ACTIVATEAPP, wParam, lParam);
  323. } // End OnActivateApp
  324.  
  325.  
  326.   
  327. /*
  328. **-----------------------------------------------------------------------------
  329. **  Name:       OnClose
  330. **  Purpose:    Shut down app
  331. **-----------------------------------------------------------------------------
  332. */
  333.  
  334. LRESULT OnClose (HWND hWindow)
  335. {
  336.     // Just Destroy the window for now
  337.     DestroyWindow (hWindow);
  338.     return 0L;
  339. } // End OnClose
  340.  
  341.   
  342.  
  343. /*
  344. **-----------------------------------------------------------------------------
  345. **  Name:       OnCommand
  346. **  Purpose:    Handle User commands
  347. **-----------------------------------------------------------------------------
  348. */
  349.  
  350. LRESULT OnCommand (HWND hWindow, WPARAM wParam, LPARAM lParam)
  351. {   
  352.     HWND  hControl    = (HWND)lParam;
  353.     DWORD dwNotify    = (DWORD)HIWORD(wParam);
  354.     DWORD dwID      = (DWORD)LOWORD(wParam);
  355.  
  356.     if (hControl)
  357.     {
  358.         //
  359.         // Handle messages from controls here
  360.         //
  361.     }
  362.     else 
  363.     {
  364.         // 
  365.         // Handle Menu messages here
  366.         //
  367.         switch (dwID)
  368.         {
  369.         case IDM_EXIT:
  370.             // Close down app
  371.             SendMessage (hWindow, WM_CLOSE, 0, 0);
  372.             return 0;
  373.  
  374.         case IDM_ABOUT:
  375.             // Bring up About Dialog
  376.             OnAbout (hWindow);
  377.             break;
  378.  
  379.         case IDM_CHANGE_DRIVERS:
  380.             // Bring up the "Change Driver" dialog
  381.             OnChangeDriver (hWindow, IDD_CHANGE_DRIVER);
  382.             break;
  383.  
  384.         default:
  385.             // Unknown Menu Command
  386.             break;
  387.         }
  388.     }
  389.  
  390.     // Let Default Window Proc handle it for us.
  391.     return DefWindowProc (hWindow, WM_COMMAND, wParam, lParam);
  392. } // End OnCommand
  393.  
  394.  
  395.  
  396. /*
  397. **-----------------------------------------------------------------------------
  398. **  Name:       OnCreate
  399. **  Purpose:    Initialization of any Window objects
  400. **-----------------------------------------------------------------------------
  401. */
  402.  
  403. LRESULT OnCreate (HWND hWindow)
  404. {
  405.     // Success
  406.     return 0L;
  407. } // End OnCreate
  408.  
  409.  
  410.   
  411. /*
  412. **-----------------------------------------------------------------------------
  413. **  Name:       OnDestroy
  414. **  Purpose:    Cleanup and shut down app
  415. **-----------------------------------------------------------------------------
  416. */
  417.  
  418. LRESULT OnDestroy (HWND hWindow)
  419. {
  420.     LPD3DWindow lpd3dWindow;
  421.     
  422.     //    Delete associated D3DWindow from this window
  423.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, 0L);
  424.     if (lpd3dWindow)
  425.         lpd3dWindow->Fini ();
  426.     SetWindowLong (hWindow, GWL_USERDATA, 0L);
  427.  
  428.     // Tell windows to QUIT!
  429.     PostQuitMessage (0);
  430.     return 0L;
  431. } // End OnDestroy
  432.  
  433.  
  434.   
  435. /*
  436. **-----------------------------------------------------------------------------
  437. **  Name:       OnDisplayChange
  438. **  Purpose:    Cleanup and shut down app
  439. **-----------------------------------------------------------------------------
  440. */
  441.  
  442. LRESULT OnDisplayChange (HWND hWindow)
  443. {
  444.     HRESULT        hResult;
  445.     LPD3DWindow lpd3dWindow;
  446.  
  447.     // Get D3D window pointer
  448.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  449.     if (! lpd3dWindow)
  450.         return 0L;
  451.     
  452.     // Change Primary surface to new desktop
  453.     hResult = lpd3dWindow->ChangeDesktop ();
  454.     if (FAILED (hResult))
  455.         return 0L;
  456.  
  457.     // Success
  458.     return 0L;
  459. } // End OnDestroy
  460.  
  461.  
  462.   
  463. /*
  464. **-----------------------------------------------------------------------------
  465. **  Name:       OnEraseBackground
  466. **  Purpose:    Erase Window background
  467. **  Notes:
  468. **        1.  The only time we need to do this is when
  469. **            the rendering surface is valid yet smaller than the client area
  470. **            any other situation and we are re-painting the entire client area.
  471. **            so we don't need to erase the background
  472. **-----------------------------------------------------------------------------
  473. */
  474.  
  475. LRESULT OnEraseBackground (HWND hWindow, WPARAM wParam, LPARAM lParam)
  476. {
  477.     LPD3DWindow lpd3dWindow;
  478.     RECT        rTemp, rSurf, rClient;
  479.  
  480.     // Get D3D window pointer
  481.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  482.     if (! lpd3dWindow)
  483.         return 0L;
  484.  
  485.     if ((lpd3dWindow->isValid ()) && (! lpd3dWindow->isPaused ()))
  486.     {
  487.         GetClientRect (hWindow, &rClient);
  488.         lpd3dWindow->GetSurfaceRect (rSurf);
  489.  
  490.         // Does surface rect contain the client rectangle?
  491.         if (IntersectRect (&rTemp, &rClient, &rSurf))
  492.         {
  493.             if (! EqualRect (&rTemp, &rClient))
  494.             {
  495.                 // No, then allow system to erase the background for us
  496.                 return DefWindowProc (hWindow, WM_ERASEBKGND, wParam, lParam);
  497.             }
  498.         }
  499.     }
  500.  
  501.     // Success
  502.     // Tell system we erased background, even though we didn't
  503.     return 1L;
  504. } // End OnEraseBackground
  505.   
  506.  
  507.   
  508. /*
  509. **-----------------------------------------------------------------------------
  510. **  Name:       OnGetMinMaxInfo
  511. **  Purpose:    Set Minimum, Maximum Window sizes
  512. **-----------------------------------------------------------------------------
  513. */
  514.  
  515. LRESULT OnGetMinMaxInfo (HWND hWindow, LPMINMAXINFO lpmmi)
  516. {
  517.     RECT         rMin;
  518.     DWORD         dwStyle, dwStyleEx;
  519.     HMENU         hMenu;
  520.     BOOL         fMenu;
  521.     LPD3DWindow  lpd3dWindow;
  522.  
  523.     // Get D3D window pointer
  524.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  525.     if (! lpd3dWindow)
  526.         return 0L;
  527.  
  528.     // Get Window Style
  529.     dwStyle   = GetWindowLong (hWindow, GWL_STYLE);
  530.     dwStyleEx = GetWindowLong (hWindow, GWL_EXSTYLE);
  531.     hMenu      = GetMenu (hWindow);
  532.     fMenu     = (hMenu ? TRUE : FALSE);
  533.  
  534.     rMin.left    = 0;
  535.     rMin.top    = 0;
  536.     rMin.right  = MIN_WIN_SIZE_X;
  537.     rMin.bottom    = MIN_WIN_SIZE_Y;
  538.  
  539.     AdjustWindowRectEx (&rMin, dwStyle, fMenu, dwStyleEx);
  540.  
  541.      lpmmi->ptMinTrackSize.x = rMin.right - rMin.left;
  542.     lpmmi->ptMinTrackSize.y = rMin.bottom  - rMin.top;
  543.  
  544.     return 0L;
  545. } // End OnGetMinMaxInfo
  546.  
  547.  
  548.  
  549. /*
  550. **-----------------------------------------------------------------------------
  551. **  Name:       OnIdle
  552. **  Purpose:    Animate while system is idle
  553. **-----------------------------------------------------------------------------
  554. */
  555.  
  556. void OnIdle (HWND hWindow)
  557. {
  558.     HRESULT hResult;
  559.     LPD3DWindow  lpd3dWindow;
  560.  
  561.     // Get D3D window pointer
  562.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  563.     if (! lpd3dWindow)
  564.         return;
  565.  
  566.     //
  567.     // Only animate if we are the foreground app, we aren't suspended
  568.     // and we have completed initialization.
  569.     //
  570.     //
  571.     // Only animate if we are the foreground app, we aren't suspended
  572.     // and we have completed initialization.
  573.     //
  574.     if (! lpd3dWindow->isActive () || 
  575.         (lpd3dWindow->isPaused ()) ||
  576.         (! lpd3dWindow->isValid ()))
  577.         return;
  578.  
  579.     hResult = lpd3dWindow->DrawFrame ();
  580.     if (FAILED (hResult))
  581.         return;
  582.  
  583.     return;
  584. } // End OnIdle
  585.  
  586.  
  587.  
  588. /*
  589. **-----------------------------------------------------------------------------
  590. **  Name:       OnMove
  591. **  Purpose:    Move window
  592. **-----------------------------------------------------------------------------
  593. */
  594.  
  595. LRESULT OnMove (HWND hWindow, INT nX, INT nY)
  596. {
  597.     HRESULT hResult;
  598.     LPD3DWindow lpd3dWindow;
  599.  
  600.     // Get D3D Window pointer
  601.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  602.     if (! lpd3dWindow)
  603.         return 0L;
  604.  
  605.     /*
  606.      * No action if the device has not yet been created or if we are
  607.      * suspended.
  608.      */
  609.     if (! lpd3dWindow->isPaused() || ! lpd3dWindow->isValid ())
  610.     {
  611.         // Keep the D3D info in synch with the change
  612.         hResult = lpd3dWindow->Move (nX, nY);
  613.         if (FAILED (hResult))
  614.             return 0L;
  615.  
  616.         // Repaint the client area.
  617.         hResult = lpd3dWindow->DrawFrame ();
  618.         if (FAILED (hResult))
  619.             return 0L;
  620.     }
  621.  
  622.     // Success
  623.     return 0L;
  624. } // End OnMove
  625.  
  626.   
  627.  
  628. /*
  629. **-----------------------------------------------------------------------------
  630. **  Name:       OnPaint
  631. **  Purpose:    Paint the window
  632. **-----------------------------------------------------------------------------
  633. */
  634.  
  635. LRESULT OnPaint (HWND hWindow, HDC hdc, LPPAINTSTRUCT lpps)
  636. {
  637.     HRESULT hResult;
  638.     LPD3DWindow lpd3dWindow;
  639.  
  640.     // Get D3D Window pointer
  641.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  642.     if (! lpd3dWindow)
  643.     {
  644.         PaintPaused (hWindow, hdc);
  645.         return 0L;
  646.     }
  647.  
  648.     if (lpd3dWindow->isActive () && 
  649.         !lpd3dWindow->isPaused () && 
  650.         lpd3dWindow->isValid())
  651.     {
  652.         //
  653.         // NOTE: DrawFrame() re-renders the scene as well as blitting the
  654.         // result to the primary. As all we really want to do here is
  655.         // repaint the client area we don't really need to re-render -
  656.         // just re-blit. For this simple sample this inefficiency
  657.         // doesn't matter but for real applications not re-rendering
  658.         // may be a useful optimization.
  659.         //
  660.         hResult = lpd3dWindow->DrawFrame ();
  661.         if (FAILED (hResult))
  662.             return 0L;
  663.     }
  664.     else
  665.     {
  666.         //
  667.         // Show the suspended image if we are not active, 
  668.         // or paused, or if we have not yet created the device.
  669.         //
  670.         PaintPaused (hWindow, hdc);
  671.     }
  672.  
  673.     return 0L;
  674. } // End OnPaint
  675.  
  676.  
  677.   
  678. /*
  679. **-----------------------------------------------------------------------------
  680. **  Name:        OnPause
  681. **  Purpose:    Pause/Unpause app
  682. **-----------------------------------------------------------------------------
  683. */
  684.  
  685. void OnPause (HWND hWindow, BOOL fPause)
  686. {
  687.     LPD3DWindow lpd3dWindow;
  688.  
  689.     // Get D3D Window pointer
  690.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  691.     if (! lpd3dWindow)
  692.         return;
  693.  
  694.     lpd3dWindow->Pause (fPause);
  695. } // End OnPause
  696.  
  697.  
  698.  
  699. /*
  700. **-----------------------------------------------------------------------------
  701. **  Name:       OnSize
  702. **  Purpose:    Resize main window
  703. **-----------------------------------------------------------------------------
  704. */
  705.  
  706. LRESULT OnSize (HWND hWindow, INT nW, INT nH)
  707. {
  708.     HRESULT       hResult;
  709.     LPD3DWindow  lpd3dWindow;
  710.  
  711.     // Get D3D window pointer
  712.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  713.     if (! lpd3dWindow)
  714.         return 0L;
  715.  
  716.     // Check if we are paused 
  717.     if (! lpd3dWindow->isPaused ())
  718.     {
  719.         // Resize D3D surfaces
  720.         hResult = lpd3dWindow->Resize (nW, nH);
  721.         if (FAILED (hResult))
  722.             return 0L;
  723.  
  724.         //
  725.         // Render at the new size and show the results
  726.         // in the main window's client area.
  727.         //
  728.         hResult = lpd3dWindow->DrawFrame ();
  729.         if (FAILED (hResult))
  730.             return 0L;
  731.     }
  732.  
  733.     // Success
  734.     return 0L;
  735. } // End OnSize
  736.  
  737.  
  738.   
  739. /*
  740. **-----------------------------------------------------------------------------
  741. **  Name:       OnD3DInit
  742. **  Purpose:    Notification that associated D3D Window object
  743. **                has successfully initialized
  744. **-----------------------------------------------------------------------------
  745. */
  746.  
  747. LRESULT OnD3DInit (HWND hWindow, LPD3DWindow lpd3dWindow)
  748. {
  749.     if ((! lpd3dWindow) || (! lpd3dWindow->isValid ()))
  750.     {
  751.         // Error, something went wrong
  752.         return 0L;
  753.     }
  754.  
  755.     // Save the pointer to the D3D Window object
  756.     SetWindowLong (hWindow, GWL_USERDATA, (long)(void *)lpd3dWindow);
  757.  
  758.     // Make sure we are properly marked as active/inactive
  759.     HWND hActive = GetActiveWindow ();
  760.     if (hActive == hWindow)
  761.         lpd3dWindow->turnActiveOn ();
  762.     else
  763.         lpd3dWindow->turnActiveOff ();
  764.  
  765.     // Success
  766.     return 0L;
  767. } // End OnD3DInit
  768.  
  769.  
  770.   
  771. /*
  772. **-----------------------------------------------------------------------------
  773. **  Name:       OnD3DFini
  774. **  Purpose:    Notification that the D3D window object
  775. **                is cleaning up.
  776. **-----------------------------------------------------------------------------
  777. */
  778.  
  779. LRESULT OnD3DFini (HWND hWindow, LPD3DWindow lpd3dWindow)
  780. {
  781.     // Set our window pointer to NULL
  782.     // so we don't attempt to misuse it later.
  783.     SetWindowLong (hWindow, GWL_USERDATA, 0L);
  784.     
  785.     // Success
  786.     return 0L;
  787. } // End OnD3DFini
  788.  
  789.  
  790.  
  791. /*
  792. **-----------------------------------------------------------------------------
  793. **  Name:       OnD3DChangeDriver
  794. **  Purpose:    Notification that our associated D3D Window object
  795. **                has changed it's DD Driver.
  796. **  Notes:        This is a good time to update our Menus
  797. **-----------------------------------------------------------------------------
  798. */
  799.  
  800. LRESULT OnD3DChangeDriver (HWND hWindow)
  801. {
  802.     // Success
  803.     return 0L;
  804. } // End OnD3DChangeDriver
  805.  
  806.   
  807.  
  808.   
  809. /*
  810. **-----------------------------------------------------------------------------
  811. **  Name:       OnD3DChangeMode
  812. **  Purpose:    Notification that our associated D3D Window object
  813. **                has changed it's mode.
  814. **  Notes:        
  815. **        1. This is probably caused by the user changing the Desktop mode
  816. **        2. This is a good time to update our Menus
  817. **-----------------------------------------------------------------------------
  818. */
  819.  
  820. LRESULT OnD3DChangeMode (HWND hWindow)
  821. {
  822.     // Success
  823.     return 0L;
  824. } // End OnD3DChangeMode
  825.  
  826.  
  827.   
  828. /*
  829. **-----------------------------------------------------------------------------
  830. **  Name:       OnD3DChangeDevice
  831. **  Purpose:    Notification that our associated D3D Window object
  832. **                has changed it's D3D device.
  833. **  Notes:        This is a good time to update our Menus
  834. **-----------------------------------------------------------------------------
  835. */
  836.  
  837. LRESULT OnD3DChangeDevice (HWND hWindow)
  838. {
  839.     // Success
  840.     return 0L;
  841. } // End OnD3DChangeDevice
  842.  
  843.  
  844.   
  845. /*
  846. **-----------------------------------------------------------------------------
  847. **  Name:       PaintPaused
  848. **  Purpose:    Paint the window as Paused
  849. **  Notes:      
  850. **
  851. **  1.  We show the paused state by drawing a text string
  852. **      in the client area of the window.
  853. **
  854. **-----------------------------------------------------------------------------
  855. */
  856.  
  857. void PaintPaused (HWND hWindow, HDC hdc)
  858. {
  859.     HPEN     hOldPen;
  860.     HBRUSH   hOldBrush;
  861.     COLORREF crOldTextColor;
  862.     INT      oldMode;
  863.     INT      x;
  864.     INT      y;
  865.     SIZE     size;
  866.     RECT     rect;
  867.     INT      nStrLen;
  868.  
  869.     //
  870.     // Black background.
  871.     //
  872.     hOldPen   = (HPEN)SelectObject (hdc, GetStockObject (NULL_PEN));
  873.     hOldBrush = (HBRUSH)SelectObject (hdc, GetStockObject (BLACK_BRUSH));
  874.  
  875.     //
  876.     // White text.
  877.     //
  878.     oldMode = SetBkMode (hdc, TRANSPARENT);
  879.     crOldTextColor = SetTextColor (hdc, RGB(255, 255, 255));
  880.  
  881.     // 
  882.     GetClientRect (hWindow, &rect);
  883.  
  884.     //
  885.     // Clear the client area.
  886.     //
  887.     Rectangle (hdc, rect.left, rect.top, rect.right + 1, rect.bottom + 1);
  888.  
  889.     //
  890.     // Draw the string centered in the client area.
  891.     //
  892.     nStrLen = strlen (g_szPaused);
  893.     GetTextExtentPoint32 (hdc, g_szPaused, nStrLen, &size);
  894.     x = (rect.right  - size.cx) / 2;
  895.     y = (rect.bottom - size.cy) / 2;
  896.     TextOut (hdc, x, y, g_szPaused, nStrLen);
  897.  
  898.     // Cleanup
  899.     SetTextColor (hdc, crOldTextColor);
  900.     SetBkMode (hdc, oldMode);
  901.  
  902.     SelectObject (hdc, hOldBrush);
  903.     SelectObject (hdc, hOldPen);
  904. } // End PaintPaused
  905.  
  906.  
  907.  
  908.   
  909. /*
  910. **-----------------------------------------------------------------------------
  911. **    Dialog Functions
  912. **-----------------------------------------------------------------------------
  913. */
  914.  
  915. /*
  916. **-----------------------------------------------------------------------------
  917. **  Name:       DlgDriversInit
  918. **  Purpose:    Set up Drivers for dialog 
  919. **  Notes:        Shows list of current Drivers
  920. **-----------------------------------------------------------------------------
  921. */
  922.  
  923. BOOL DlgDriversInit (HWND hDlg)
  924. {
  925.     LPChangeDDInfo    lpChange;
  926.     LPDDDrvInfo        lpDriver;
  927.     LPDDDrvInfo        lpCurr, lpNext;
  928.     DWORD            dwIndex;
  929.     LPGUID            lpGuidDD;
  930.  
  931.     // Check Parameters
  932.     lpChange = (LPChangeDDInfo)(void *)GetWindowLong (hDlg, DWL_USER);
  933.     if (! lpChange)
  934.         return FALSE;
  935.  
  936.     lpDriver = lpChange->lpDrvNew;
  937.  
  938.     // Validate Driver
  939.     if (! lpDriver)
  940.         lpGuidDD = NULL;
  941.     else
  942.         lpGuidDD = lpDriver->GetGuid ();
  943.     lpDriver = ValidateDriver (lpGuidDD);
  944.     if (! lpDriver)
  945.         return FALSE;
  946.     
  947.     // Dump Driver list to Combo Box
  948.     dwIndex = 0;
  949.     lpCurr = DDDrvMgr::g_lpDriverRoot;
  950.     while (lpCurr)
  951.     {
  952.         TCHAR szBuff[80];
  953.         DWORD dwNew;
  954.         LPGUID lpGuidDD;
  955.  
  956.         lpNext = lpCurr->lpNext;
  957.  
  958.         // Hack: Do a Quick check for the 3Dfx Voodoo driver
  959.         //         which doesn't support windowed mode
  960.         lpGuidDD = lpCurr->GetGuid ();
  961.         if (lpGuidDD)
  962.         {
  963.             if (*lpGuidDD == guid3DfxVoodoo)
  964.             {
  965.                 // Don't add 3Dfx Voodoo driver.
  966.                 // This is a windowed app and it isn't supported
  967.                 lpCurr = lpNext;
  968.                 continue;
  969.             }
  970.         }
  971.  
  972.         if (lpCurr->isPrimary ())
  973.             wsprintf (szBuff, TEXT("%s (Primary)"), lpCurr->szName);
  974.         else
  975.             wsprintf (szBuff, TEXT("%s"), lpCurr->szName);
  976.  
  977.         // Add String to Combo Box
  978.         dwNew = SendDlgItemMessage (hDlg, IDC_DRIVERS, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBuff);
  979.  
  980.         // Set up pointer to driver for this item
  981.         SendDlgItemMessage (hDlg, IDC_DRIVERS, CB_SETITEMDATA, (WPARAM)dwNew, (LPARAM)(void *)lpCurr);
  982.  
  983.         // Is it the current Driver
  984.         if (lpDriver == lpCurr)
  985.         {
  986.             // Set as our current selection
  987.             SendDlgItemMessage (hDlg, IDC_DRIVERS, CB_SETCURSEL, (WPARAM)dwNew, 0L);
  988.         }
  989.  
  990.         lpCurr = lpNext;
  991.     }
  992.  
  993.     // Success
  994.     return TRUE;
  995. } // End DlgDriversInit
  996.     
  997.  
  998.  
  999. /*
  1000. **-----------------------------------------------------------------------------
  1001. **  Name:       DlgDevicesInit
  1002. **  Purpose:    Set up Devices for dialog 
  1003. **  Notes:        Shows list of current Devices
  1004. **-----------------------------------------------------------------------------
  1005. */
  1006.  
  1007. BOOL DlgDevicesInit (HWND hDlg)
  1008. {
  1009.     LPChangeDDInfo    lpChange;
  1010.     LPDDDrvInfo        lpDriver;
  1011.     LPD3DDevInfo    lpDevice;
  1012.     LPD3DDevInfo    lpCurr, lpNext;
  1013.     DWORD            dwIndex;
  1014.     LPGUID            lpGuidD3D;
  1015.  
  1016.     // Check Parameters
  1017.     lpChange = (LPChangeDDInfo)(void *)GetWindowLong (hDlg, DWL_USER);
  1018.     if (! lpChange)
  1019.         return FALSE;
  1020.  
  1021.     lpDriver = lpChange->lpDrvNew;
  1022.     if (! lpDriver)
  1023.         return FALSE;
  1024.  
  1025.     lpDevice = lpChange->lpDevNew;
  1026.  
  1027.     // Validate Device
  1028.     if (! lpDevice)
  1029.         lpGuidD3D = NULL;
  1030.     else
  1031.         lpGuidD3D = &(lpDevice->guid);
  1032.     lpDevice = ValidateDevice (lpDriver, lpGuidD3D, NULL);
  1033.     if (! lpDevice)
  1034.         return FALSE;
  1035.     
  1036.     // Dump Device list to Combo Box
  1037.     dwIndex = 0;
  1038.     lpCurr = lpDriver->lpDeviceRoot;
  1039.     while (lpCurr)
  1040.     {
  1041.         TCHAR szBuff[80];
  1042.         DWORD dwNew;
  1043.  
  1044.         lpNext = lpCurr->lpNext;
  1045.  
  1046.         // Get Device String
  1047.         wsprintf (szBuff, TEXT("%s"), lpCurr->szName);
  1048.  
  1049.         // Add String to Combo Box
  1050.         dwNew = SendDlgItemMessage (hDlg, IDC_DEVICES, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBuff);
  1051.  
  1052.         // Set up pointer to device for this item
  1053.         SendDlgItemMessage (hDlg, IDC_DEVICES, CB_SETITEMDATA, (WPARAM)dwNew, (LPARAM)(void *)lpCurr);
  1054.  
  1055.         // Is it the current device
  1056.         if (lpDevice == lpCurr)
  1057.         {
  1058.             // Set as our current selection
  1059.             SendDlgItemMessage (hDlg, IDC_DEVICES, CB_SETCURSEL, (WPARAM)dwNew, 0L);
  1060.         }
  1061.  
  1062.         lpCurr = lpNext;
  1063.     }
  1064.  
  1065.     // Success
  1066.     return TRUE;
  1067. } // End DlgDevicesInit
  1068.  
  1069.  
  1070.  
  1071. /*
  1072. **-----------------------------------------------------------------------------
  1073. **  Name:       CompareModes
  1074. **  Purpose:    Comparision function used with Quick sort 
  1075. **                to get sorted list of modes
  1076. **-----------------------------------------------------------------------------
  1077. */
  1078.  
  1079. int _cdecl CompareModes (const void * element1, const void * element2) 
  1080. {
  1081.     LPDDModeInfo lpMode1;
  1082.     LPDDModeInfo lpMode2;
  1083.     DWORD w1, h1, bpp1, refresh1;
  1084.     DWORD w2, h2, bpp2, refresh2;
  1085.     int   iCompare = 0;
  1086.  
  1087.     lpMode1 = *((LPDDModeInfo *)element1);
  1088.     lpMode2 = *((LPDDModeInfo *)element2);
  1089.  
  1090.     // Handle Null pointers
  1091.     if ((! lpMode1) && (! lpMode2))
  1092.         return 0;
  1093.     if ((lpMode1) && (! lpMode2))
  1094.         return -1;
  1095.     if ((! lpMode2) && (lpMode2))
  1096.         return 1;
  1097.  
  1098.     // Get Mode Data
  1099.     lpMode1->GetMode (w1, h1, bpp1, refresh1);
  1100.     lpMode2->GetMode (w2, h2, bpp2, refresh2);
  1101.  
  1102.     // Sort first on BPP then width then height
  1103.     if (bpp1 < bpp2)
  1104.         iCompare = -1;
  1105.     else if (bpp1 > bpp2)
  1106.         iCompare = 1;
  1107.     else if (w1 < w2)
  1108.         iCompare = -1;
  1109.     else if (w1 > w2)
  1110.         iCompare = 1;
  1111.     else if (h1 < h2)
  1112.         iCompare = -1;
  1113.     else if (h1 > h2)
  1114.         iCompare = 1;
  1115.  
  1116.     // Equality
  1117.     return iCompare;
  1118. } // End CompareModes
  1119.  
  1120.  
  1121.   
  1122. /*
  1123. **-----------------------------------------------------------------------------
  1124. **  Name:       DlgModesInit
  1125. **  Purpose:    Set up Modes for dialog 
  1126. **  Notes:        Shows list of current modes, compatible with the current 
  1127. **                device.  This list is displayed in sorted order (bpp, w, h)
  1128. **-----------------------------------------------------------------------------
  1129. */
  1130.  
  1131. BOOL DlgModesInit (HWND hDlg)
  1132. {
  1133.     LPChangeDDInfo    lpChange;
  1134.     LPDDDrvInfo        lpDriver;
  1135.     LPD3DDevInfo    lpDevice;
  1136.     LPDDModeInfo    lpModeCurr, lpModeRoot, lpCurr, lpNext;
  1137.     DWORD            cModes;
  1138.     DWORD            cbSize;
  1139.     DWORD            dwIndex;
  1140.     LPDDModeInfo *    lpModes;
  1141.  
  1142.     // Check Parameters
  1143.     lpChange = (LPChangeDDInfo)(void *)GetWindowLong (hDlg, DWL_USER);
  1144.     if (! lpChange)
  1145.         return FALSE;
  1146.  
  1147.     lpDriver   = lpChange->lpDrvNew;
  1148.     lpDevice   = lpChange->lpDevNew;
  1149.     lpModeCurr = lpChange->lpModeNew;
  1150.  
  1151.     if (! lpDriver)
  1152.         return FALSE;
  1153.  
  1154.     if (! lpDevice)
  1155.     {
  1156.         lpDevice = ValidateDevice (lpDriver, NULL, NULL);
  1157.         if (! lpDevice)
  1158.             return FALSE;
  1159.     }
  1160.  
  1161.     lpModeRoot = lpDriver->lpModeRoot;
  1162.     if (! lpModeRoot)
  1163.         return FALSE;
  1164.  
  1165.     cModes = lpDriver->countModes ();
  1166.     if (! cModes)
  1167.         return FALSE;
  1168.     
  1169.     if (! lpModeCurr)
  1170.     {
  1171.         lpModeCurr = ValidateMode (lpDriver, 640, 480, 16, 0, lpDevice);
  1172.     }
  1173.  
  1174.     // Get memory for Mode list
  1175.     cbSize = cModes * sizeof (LPDDModeInfo);
  1176.     lpModes = (LPDDModeInfo *) malloc (cbSize);
  1177.     if (! lpModes)
  1178.         return FALSE;
  1179.  
  1180.     // Create Mode List
  1181.     dwIndex = 0;
  1182.     lpCurr = lpModeRoot;
  1183.     while (lpCurr)
  1184.     {
  1185.         lpNext = lpCurr->lpNext;
  1186.  
  1187.         lpModes[dwIndex] = lpCurr;
  1188.  
  1189.         dwIndex++;
  1190.  
  1191.         lpCurr = lpNext;
  1192.     }
  1193.  
  1194.     // Sort Mode list
  1195.     qsort ((void *)lpModes, (size_t)cModes, sizeof(LPDDModeInfo), CompareModes);
  1196.  
  1197.     // Dump Mode list to Combo Box
  1198.     for (dwIndex = 0; dwIndex < cModes; dwIndex++)
  1199.     {
  1200.         // Make sure mode is supported by D3D device
  1201.         if ((lpModes[dwIndex]) && 
  1202.             (lpModes[dwIndex]->ModeSupported (lpDevice)))
  1203.         {
  1204.             TCHAR szBuff[80];
  1205.             DWORD w, h, bpp, refresh;
  1206.             DWORD dwNew;
  1207.  
  1208.             lpModes[dwIndex]->GetMode (w, h, bpp, refresh);
  1209.             
  1210.             // Set up Mode String
  1211.             if (refresh)
  1212.                 wsprintf (szBuff, TEXT("%4d x %4d x %4d (%4d Hz)"), 
  1213.                           w, h, bpp, refresh);
  1214.             else
  1215.                 wsprintf (szBuff, TEXT("%4d x %4d x %4d"), 
  1216.                           w, h, bpp);
  1217.  
  1218.             // Add String to Combo Box
  1219.             dwNew = SendDlgItemMessage (hDlg, IDC_MODES, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBuff);
  1220.  
  1221.             // Set up pointer to Mode Info for this item
  1222.             SendDlgItemMessage (hDlg, IDC_MODES, CB_SETITEMDATA, (WPARAM)dwNew, (LPARAM)(void *)lpModes[dwIndex]);
  1223.  
  1224.             // Is it the current Mode 
  1225.             if (lpModeCurr == lpModes[dwIndex])
  1226.             {
  1227.                 // Set as our current selection
  1228.                 SendDlgItemMessage (hDlg, IDC_MODES, CB_SETCURSEL, (WPARAM)dwNew, 0L);
  1229.             }
  1230.         }
  1231.     }    
  1232.  
  1233.     // Cleanup Memory
  1234.     free (lpModes);
  1235.     lpModes = NULL;
  1236.  
  1237.     // Success
  1238.     return TRUE;
  1239. } // End DlgModesInit
  1240.  
  1241.  
  1242.  
  1243.   
  1244. /*
  1245. **-----------------------------------------------------------------------------
  1246. **  Name:       DlgGetDriver
  1247. **  Purpose:    Get current driver selection
  1248. **-----------------------------------------------------------------------------
  1249. */
  1250.  
  1251. LPDDDrvInfo DlgGetDriver (HWND hDlg)
  1252. {
  1253.     DWORD dwIndex = SendDlgItemMessage (hDlg, IDC_DRIVERS, CB_GETCURSEL, 0, 0);
  1254.     if (dwIndex != CB_ERR)
  1255.     {
  1256.         // Get pointer to driver
  1257.         LPDDDrvInfo lpDriver = (LPDDDrvInfo) SendDlgItemMessage (hDlg, 
  1258.                                                                    IDC_DRIVERS, 
  1259.                                                                  CB_GETITEMDATA, 
  1260.                                                                  (WPARAM)dwIndex, 
  1261.                                                                  (LPARAM)0);
  1262.         return lpDriver;
  1263.     }            
  1264.  
  1265.     // Failure
  1266.     return NULL;
  1267. } // End DlgGetDriver
  1268.  
  1269.  
  1270.   
  1271. /*
  1272. **-----------------------------------------------------------------------------
  1273. **  Name:       DlgGetDevice
  1274. **  Purpose:    Get current device selection
  1275. **-----------------------------------------------------------------------------
  1276. */
  1277.  
  1278. LPD3DDevInfo DlgGetDevice (HWND hDlg)
  1279. {
  1280.     DWORD dwIndex = SendDlgItemMessage (hDlg, IDC_DEVICES, CB_GETCURSEL, 0, 0);
  1281.     if (dwIndex != CB_ERR)
  1282.     {
  1283.         // Get pointer to device
  1284.         LPD3DDevInfo lpDevice = (LPD3DDevInfo) SendDlgItemMessage (hDlg, 
  1285.                                                                      IDC_DEVICES, 
  1286.                                                                    CB_GETITEMDATA, 
  1287.                                                                    (WPARAM)dwIndex, 
  1288.                                                                    (LPARAM)0);
  1289.         return lpDevice;
  1290.     }            
  1291.  
  1292.     // Failure
  1293.     return NULL;
  1294. } // End DlgGetDevice
  1295.  
  1296.  
  1297.   
  1298. /*
  1299. **-----------------------------------------------------------------------------
  1300. **  Name:       DlgGetMode
  1301. **  Purpose:    Get current mode selection
  1302. **-----------------------------------------------------------------------------
  1303. */
  1304.  
  1305. LPDDModeInfo DlgGetMode (HWND hDlg)
  1306. {
  1307.     DWORD dwIndex = SendDlgItemMessage (hDlg, IDC_MODES, CB_GETCURSEL, 0, 0);
  1308.     if (dwIndex != CB_ERR)
  1309.     {
  1310.         // Get pointer to device
  1311.         LPDDModeInfo lpMode = (LPDDModeInfo) SendDlgItemMessage (hDlg, 
  1312.                                                                  IDC_MODES, 
  1313.                                                                  CB_GETITEMDATA, 
  1314.                                                                  (WPARAM)dwIndex, 
  1315.                                                                  (LPARAM)0);
  1316.         return lpMode;
  1317.     }            
  1318.  
  1319.     // Failure
  1320.     return NULL;
  1321. } // End DlgGetMode
  1322.  
  1323.   
  1324.  
  1325.  
  1326.   
  1327. /*
  1328. **-----------------------------------------------------------------------------
  1329. **  Name:       OnChangeDriver
  1330. **  Purpose:    Allows user to choose a new Driver from dialog
  1331. **    Notes:        User can also choose a new device and mode
  1332. **-----------------------------------------------------------------------------
  1333. */
  1334.  
  1335. void OnChangeDriver (HWND hWindow, int idDialog)
  1336. {
  1337.     HINSTANCE        hInstance;
  1338.     int                fResult;
  1339.     ChangeDDInfo    changeInfo;
  1340.     LPD3DWindow        lpd3dWindow;
  1341.  
  1342.     // Get application instance
  1343.     hInstance = (HINSTANCE) GetWindowLong (hWindow, GWL_HINSTANCE);
  1344.     if (! hInstance)
  1345.         return;
  1346.  
  1347.     // Get D3D Window pointer
  1348.     lpd3dWindow =  (LPD3DWindow)GetWindowLong (hWindow, GWL_USERDATA);
  1349.     if (! lpd3dWindow)
  1350.         return;
  1351.  
  1352.     // Setup Change info
  1353.     changeInfo.lpDrvOrig    = lpd3dWindow->GetDriverInfo ();
  1354.     changeInfo.lpDrvNew        = changeInfo.lpDrvOrig;
  1355.  
  1356.     changeInfo.lpDevOrig    = lpd3dWindow->GetDeviceInfo ();
  1357.     changeInfo.lpDevNew        = changeInfo.lpDevOrig;
  1358.  
  1359.     changeInfo.lpModeOrig    = lpd3dWindow->GetModeInfo ();
  1360.     changeInfo.lpModeNew    = changeInfo.lpModeOrig;
  1361.  
  1362.  
  1363.     // Pause App
  1364.     OnPause (hWindow, TRUE);
  1365.  
  1366.     // Do Change Mode Dialog here
  1367.     fResult = DialogBoxParam (hInstance, MAKEINTRESOURCE (idDialog), 
  1368.                               hWindow, (DLGPROC)ChangeDriverProc,
  1369.                               (LPARAM)(void *)&changeInfo);
  1370.  
  1371.     // UnPause app
  1372.     OnPause (hWindow, FALSE);
  1373.  
  1374.     // Did user request a change ?!?
  1375.     if (fResult == TRUE)
  1376.     {
  1377.         LPGUID lpGuidDD, lpGuidD3D;
  1378.  
  1379.         if (changeInfo.lpDrvOrig != changeInfo.lpDrvNew)
  1380.         {
  1381.             if (changeInfo.lpDrvNew)
  1382.                 lpGuidDD = changeInfo.lpDrvNew->GetGuid ();
  1383.             else
  1384.                 lpGuidDD = NULL;
  1385.  
  1386.             lpd3dWindow->ChangeDriver (lpGuidDD, changeInfo.lpDevNew);
  1387.         }
  1388.         else if (changeInfo.lpDevOrig != changeInfo.lpDevNew)
  1389.         {
  1390.             if (changeInfo.lpDevNew)
  1391.                 lpGuidD3D = &(changeInfo.lpDevNew->guid);
  1392.             else
  1393.                 lpGuidD3D = NULL;
  1394.  
  1395.             lpd3dWindow->ChangeDevice (lpGuidD3D);
  1396.         }
  1397.     }
  1398. } // End OnChangeDriver
  1399.   
  1400.  
  1401.  
  1402. /*
  1403. **-----------------------------------------------------------------------------
  1404. **  Name:       ChangeDriverProc
  1405. **  Purpose:    handles messages for Change Driver,
  1406. **                D3D device, and mode dialog boxes
  1407. **-----------------------------------------------------------------------------
  1408. */
  1409.  
  1410. BOOL CALLBACK ChangeDriverProc(
  1411.     HWND hDlg,        // handle to dialog box
  1412.     UINT uiMsg,        // message
  1413.     WPARAM wParam,    // first message parameter
  1414.     LPARAM lParam)     // second message parameter
  1415. {
  1416.     BOOL            fChanged;
  1417.     LPChangeDDInfo  lpChange;
  1418.     LPDDDrvInfo        lpDriver;
  1419.     LPDDModeInfo    lpMode;
  1420.     LPD3DDevInfo    lpDevice;
  1421.  
  1422.     switch (uiMsg)
  1423.     {
  1424.     case WM_COMMAND:
  1425.         switch (LOWORD(wParam))
  1426.         {
  1427.         case IDOK:
  1428.             // Get Change Info
  1429.             lpChange = (LPChangeDDInfo) GetWindowLong (hDlg, DWL_USER);
  1430.             if (! lpChange)
  1431.                 EndDialog (hDlg, FALSE);
  1432.  
  1433.             fChanged = FALSE;
  1434.  
  1435.             // Get New Driver
  1436.             lpDriver = DlgGetDriver (hDlg);
  1437.             if ((lpDriver) && (lpDriver != lpChange->lpDrvOrig))
  1438.             {
  1439.                 fChanged = TRUE;
  1440.                 lpChange->lpDrvNew = lpDriver;
  1441.             }
  1442.             else
  1443.                 lpChange->lpDrvNew = lpChange->lpDrvOrig;
  1444.  
  1445.             // Get New Device
  1446.             lpDevice = DlgGetDevice (hDlg);
  1447.             if ((lpDevice) && (lpDevice != lpChange->lpDevOrig))
  1448.             {
  1449.                 fChanged = TRUE;
  1450.                 lpChange->lpDevNew = lpDevice;
  1451.             }
  1452.             else
  1453.                 lpChange->lpDevNew = lpChange->lpDevOrig;
  1454.             
  1455.             // Get New Mode
  1456.             lpMode = DlgGetMode (hDlg);
  1457.             if ((lpMode) && (lpMode != lpChange->lpModeOrig))
  1458.             {
  1459.                 fChanged = TRUE;
  1460.                 lpChange->lpModeNew = lpMode;
  1461.             }
  1462.             else
  1463.                 lpChange->lpModeNew = lpChange->lpModeOrig;
  1464.  
  1465.             // Return success/failure
  1466.             EndDialog (hDlg, fChanged);
  1467.             break;
  1468.  
  1469.         case IDCANCEL:
  1470.             EndDialog (hDlg, FALSE);
  1471.             break;
  1472.  
  1473.         case IDC_DRIVERS:
  1474.             switch (HIWORD (wParam))
  1475.             {
  1476.             case CBN_SELENDOK:
  1477.                 // User has changed the current driver
  1478.                 lpChange = (LPChangeDDInfo) GetWindowLong (hDlg, DWL_USER);
  1479.             
  1480.                 // Check if user has changed the Driver
  1481.                 lpDriver = DlgGetDriver (hDlg);
  1482.                 if ((lpDriver) && (lpDriver != lpChange->lpDrvNew))
  1483.                 {
  1484.                     lpChange->lpDrvNew = lpDriver;
  1485.                     lpChange->lpDevNew = NULL;    // Pick a new device
  1486.                     lpChange->lpModeNew = NULL;    // Pick a new mode
  1487.                     
  1488.                     // Update the Device list
  1489.                     SendDlgItemMessage (hDlg, IDC_DEVICES, CB_RESETCONTENT, 0, 0);
  1490.                     DlgDevicesInit (hDlg);
  1491.  
  1492.                     // Update the Mode list
  1493.                     SendDlgItemMessage (hDlg, IDC_MODES, CB_RESETCONTENT, 0, 0);
  1494.                     DlgModesInit (hDlg);
  1495.                 }
  1496.                 break;
  1497.             }
  1498.             break;
  1499.  
  1500.         case IDC_DEVICES:
  1501.             switch (HIWORD (wParam))
  1502.             {
  1503.             case CBN_SELENDOK:
  1504.                 // User has changed the current device
  1505.                 lpChange = (LPChangeDDInfo) GetWindowLong (hDlg, DWL_USER);
  1506.                 
  1507.                 // Check if user has changed the device
  1508.                 lpDevice = DlgGetDevice (hDlg);
  1509.                 if ((lpDevice) && (lpDevice != lpChange->lpDevNew))
  1510.                 {
  1511.                     lpChange->lpDevNew = lpDevice;
  1512.                     
  1513.                     // Update the Mode list
  1514.                     SendDlgItemMessage (hDlg, IDC_MODES, CB_RESETCONTENT, 0, 0);
  1515.                     DlgModesInit (hDlg);
  1516.                 }
  1517.                 break;
  1518.             }
  1519.             break;
  1520.  
  1521.         case IDC_MODES:
  1522.             switch (HIWORD (wParam))
  1523.             {
  1524.             case CBN_SELENDOK:
  1525.                 // User has changed the current mode
  1526.                 lpChange = (LPChangeDDInfo) GetWindowLong (hDlg, DWL_USER);
  1527.                 
  1528.                 // Check if user has changed the Mode
  1529.                 lpMode = DlgGetMode (hDlg);
  1530.                 if ((lpMode) && (lpMode != lpChange->lpModeNew))
  1531.                 {
  1532.                     lpChange->lpModeNew = lpMode;
  1533.                 }
  1534.                 break;
  1535.             }
  1536.             break;
  1537.         }
  1538.         break;
  1539.  
  1540.     case WM_INITDIALOG:
  1541.         // Save pointer to ChangeInfo
  1542.         SetWindowLong (hDlg, DWL_USER, (long)lParam);
  1543.  
  1544.         // Set up the current driver, device, and mode lists
  1545.         if (GetDlgItem (hDlg, IDC_DRIVERS))
  1546.             if (! DlgDriversInit (hDlg))    
  1547.                 return FALSE;
  1548.  
  1549.         if (GetDlgItem (hDlg, IDC_DEVICES))
  1550.             if (! DlgDevicesInit (hDlg))
  1551.                 return FALSE;
  1552.  
  1553.         if (GetDlgItem (hDlg, IDC_MODES))
  1554.             if (! DlgModesInit (hDlg))
  1555.                 return FALSE;
  1556.  
  1557.         // Successful init
  1558.         return TRUE;
  1559.     }
  1560.     return FALSE;
  1561. } // End ChangeDriverProc 
  1562.  
  1563.  
  1564. /*
  1565. **-----------------------------------------------------------------------------
  1566. **  End of File
  1567. **-----------------------------------------------------------------------------
  1568. */
  1569.  
  1570.  
  1571.