home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / samples / multimedia / directinput / diconfig / cfrmwrk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-05  |  6.1 KB  |  254 lines

  1. //-----------------------------------------------------------------------------
  2. // File: cfrmwrk.cpp
  3. //
  4. // Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
  5. //       contains everything else. Its functionality is provided by one
  6. //       method: ConfigureDevices.
  7. //
  8. //       InternalConfigureDevices is called by the CDirectInputActionFramework
  9. //       class. This function actually contains the initialization code and
  10. //       the message pump for the UI.
  11. //
  12. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  13. //-----------------------------------------------------------------------------
  14.  
  15. #include "common.hpp"
  16.  
  17.  
  18. //QueryInterface
  19. STDMETHODIMP CDirectInputActionFramework::QueryInterface(REFIID iid, LPVOID* ppv)
  20. {
  21.     //null the out param
  22.     *ppv = NULL;
  23.  
  24.     if ((iid == IID_IUnknown) || (iid == IID_IDIActionFramework))
  25.     {
  26.         *ppv = this;
  27.         AddRef();
  28.         return S_OK;
  29.     }
  30.  
  31.     return E_NOINTERFACE;
  32. }
  33.  
  34.  
  35. //AddRef
  36. STDMETHODIMP_(ULONG) CDirectInputActionFramework::AddRef()
  37. {
  38.     return InterlockedIncrement(&m_cRef);
  39. }
  40.  
  41.  
  42. //Release
  43. STDMETHODIMP_(ULONG) CDirectInputActionFramework::Release()
  44. {
  45.  
  46.     if (InterlockedDecrement(&m_cRef) == 0)
  47.     {
  48.         delete this;
  49.         return 0;
  50.     }
  51.  
  52.     return m_cRef;
  53. }
  54.  
  55. // Manages auto loading/unloading WINMM.DLL
  56. // There will only be one instance of this class: inside InternalConfigureDevicees.
  57. class CWinMmLoader
  58. {
  59. public:
  60.     CWinMmLoader()
  61.     {
  62.         if (!g_hWinMmDLL)
  63.         {
  64.             g_hWinMmDLL = LoadLibrary(_T("WINMM.DLL"));
  65.             if (g_hWinMmDLL)
  66.             {
  67.                 *(FARPROC*)(&g_fptimeSetEvent) = GetProcAddress(g_hWinMmDLL, "timeSetEvent");
  68.             }
  69.         }
  70.     }
  71.     ~CWinMmLoader()
  72.     {
  73.         if (g_hWinMmDLL)
  74.         {
  75.             FreeLibrary(g_hWinMmDLL);
  76.             g_hWinMmDLL = NULL;
  77.             g_fptimeSetEvent = NULL;
  78.         }
  79.     }
  80. };
  81.  
  82.  
  83.  
  84.  
  85. // internal, which api wraps around
  86. static HRESULT InternalConfigureDevices(LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  87.                                         LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  88.                                         DWORD                        dwFlags,
  89.                                         LPVOID                       pvRefData)
  90. {
  91.     tracescope(__ts, _T("InternalConfigureDevices()\n"));
  92.  
  93.     CWinMmLoader g_WinMmLoadingHelper;  // Automatically call LoadLibrary and FreeLibrary on WINMM.DLL
  94.  
  95.     // check that we're at least 256 colors
  96.     HDC hMemDC = CreateCompatibleDC(NULL);
  97.     if (hMemDC == NULL)
  98.     {
  99.         etrace(_T("Can't get a DC! Exiting.\n"));
  100.         return E_FAIL;
  101.     }
  102.  
  103.     int bpp = GetDeviceCaps(hMemDC, BITSPIXEL);
  104.     DeleteDC(hMemDC);
  105.     if (bpp < 8)
  106.     {
  107.         etrace1(_T("Screen is not at least 8bpp (bpp = %d)\n"), bpp);
  108.         return E_FAIL;
  109.     }
  110.  
  111.     // do it...
  112.     {
  113.         // create the globals
  114.         CUIGlobals uig(
  115.             dwFlags,
  116.             lpdiCDParams->lptszUserNames,
  117.             lpdiCDParams->dwcFormats,
  118.             lpdiCDParams->lprgFormats,
  119.             &(lpdiCDParams->dics),
  120.             lpdiCDParams->lpUnkDDSTarget,
  121.             lpdiCallback,
  122.             pvRefData
  123.         );
  124.         HRESULT hr = uig.GetInitResult();
  125.         if (FAILED(hr))
  126.         {
  127.             etrace(_T("CUIGlobals.Init() failed\n"));
  128.             return hr;
  129.         }
  130.  
  131.         // make sure the flexwnd window class is registered only during possible use
  132.         {
  133.             struct flexwndscope {
  134.                 flexwndscope(CUIGlobals &uig) : m_uig(uig) {CFlexWnd::RegisterWndClass(m_uig.GetInstance());}
  135.                 ~flexwndscope() {CFlexWnd::UnregisterWndClass(m_uig.GetInstance());}
  136.                 CUIGlobals &m_uig;
  137.             } scope(uig);
  138.  
  139.             // create the main window
  140.             CConfigWnd cfgWnd(uig);
  141.             if (!cfgWnd.Create(lpdiCDParams->hwnd))
  142.             {
  143.                 etrace(_T("Failed to create main window\n"));
  144.                 return E_FAIL;
  145.             }
  146.  
  147.             // Initialize the shared tooltip object.
  148.             RECT rc = {0, 0, 0, 0};
  149.             CFlexWnd::s_ToolTip.Create(cfgWnd.m_hWnd, rc, TRUE);
  150.             if (!CFlexWnd::s_ToolTip.m_hWnd)
  151.             {
  152.                 etrace(_T("Failed to create tooltip window\n"));
  153.                 return E_FAIL;
  154.             }
  155.             ::ShowWindow(CFlexWnd::s_ToolTip.m_hWnd, SW_HIDE);  // Hide window by default
  156.  
  157.             // enter message loop
  158.             MSG msg;
  159.             while (GetMessage(&msg, NULL, 0, 0))
  160.             {
  161.                 // If this is a message for the parent window (game window), only dispatch if it's WM_PAINT.
  162.                 if (!cfgWnd.InRenderMode() && msg.hwnd == lpdiCDParams->hwnd && msg.message != WM_PAINT)
  163.                     continue;
  164.                 TranslateMessage(&msg);
  165.                 DispatchMessage(&msg);
  166.             }
  167.         }
  168.  
  169.         return uig.GetFinalResult();
  170.     }
  171. }
  172.  
  173.  
  174. BOOL AreAcForsGood(LPDIACTIONFORMATW lpAcFors, DWORD dwNumAcFors)
  175. {
  176.     if (lpAcFors == NULL)
  177.         return FALSE;
  178.  
  179.     if (dwNumAcFors < 1)
  180.         return FALSE;
  181.  
  182.     if (lpAcFors->dwNumActions == 0)
  183.         return FALSE;
  184.  
  185.     return TRUE;
  186. }
  187.  
  188.  
  189. //ConfigureDevices
  190. STDMETHODIMP CDirectInputActionFramework::ConfigureDevices(
  191.             LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  192.             LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  193.             DWORD                        dwFlags,
  194.             LPVOID                       pvRefData)
  195. {
  196.     tracescope(__ts,_T("CDirectInputActionFramework::ConfigureDevices()\n"));
  197.  
  198.     trace(_T("\nConfigureDevices() called...\n\n"));
  199.  
  200.     // check parameters
  201.     if (lpdiCDParams == NULL)
  202.     {
  203.         etrace(_T("NULL params structure passed to ConfigureDevices()\n"));
  204.         return E_INVALIDARG;
  205.     }
  206.  
  207.     // save passed params in case we change 'em
  208.     LPDIACTIONFORMATW lpAcFors = lpdiCDParams->lprgFormats;
  209.     DWORD dwNumAcFors = lpdiCDParams->dwcFormats;
  210.  
  211. #ifdef CFGUI__FORCE_GOOD_ACFORS
  212.  
  213.     if (!AreAcForsGood(lpdiCDParams->lprgFormats, lpdiCDParams->dwcFormats))
  214.     {
  215.         etrace(_T("Passed ActionFormats aren't good...  Using GetTestActionFormats() (just 2 of them).\n"));
  216.         lpdiCDParams->dwcFormats = 2;
  217.         lpdiCDParams->lprgFormats = GetTestActionFormats();
  218.     }
  219.  
  220. #endif
  221.  
  222.     HRESULT hr = InternalConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData);
  223.  
  224.     // restore passed params in case changed
  225.     lpdiCDParams->lprgFormats = lpAcFors;
  226.     lpdiCDParams->dwcFormats = dwNumAcFors;
  227.  
  228.     trace(_T("\n"));
  229.  
  230.     if (FAILED(hr))
  231.         etrace1(_T("ConfigureDevices() failed, returning 0x%08x\n"), hr);
  232.     else
  233.         trace1(_T("ConfigureDevices() suceeded, returning 0x%08x\n"), hr);
  234.  
  235.     trace(_T("\n"));
  236.  
  237.     return hr;
  238. }
  239.  
  240.  
  241. //constructor
  242. CDirectInputActionFramework::CDirectInputActionFramework()
  243. {
  244.     //set ref count
  245.     m_cRef = 1;
  246. }
  247.  
  248.  
  249. //destructor
  250. CDirectInputActionFramework::~CDirectInputActionFramework()
  251. {
  252.     // not necessary to cleanup action format here
  253. }
  254.