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

Windows编程

开发平台:

Visual C++

  1. /****************************************************************************
  2.     Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  3.     PROGRAM: dinput.c
  4.     PURPOSE: DirectX Device Viewer - DirectInput module
  5.     FUNCTIONS:
  6.     COMMENTS:
  7. ****************************************************************************/
  8. #include "dxview.h"
  9. #define DICAPDEF(name,val,flag) {name, FIELD_OFFSET(DIDEVCAPS,val), flag}
  10. #define DIVALDEF(name,val)      {name, FIELD_OFFSET(DIDEVCAPS,val), 0}
  11. /****************************************************************************
  12.  *
  13.  *  DI_CreateDI
  14.  *
  15.  *  Create a DirectInput pointer.  Try the current DirectInput version
  16.  *  first; if that doesn't work, try version 3.0.
  17.  *
  18.  ****************************************************************************/
  19. LPDIRECTINPUT
  20. DI_CreateDI(void)
  21. {
  22.     LPDIRECTINPUT pdi;
  23.     if (SUCCEEDED(DirectInputCreate(g_hInstance, DIRECTINPUT_VERSION,
  24.                                     &pdi, NULL))) {
  25.     } else
  26.     if (SUCCEEDED(DirectInputCreate(g_hInstance, 0x0300,
  27.                                     &pdi, NULL))) {
  28.     } else {
  29.         pdi = 0;
  30.     }
  31.     return pdi;
  32. }
  33. /****************************************************************************
  34.  *
  35.  *  DI_CreateDevice
  36.  *
  37.  *  Create a device with the specified instance GUID.
  38.  *
  39.  ****************************************************************************/
  40. LPDIRECTINPUTDEVICE
  41. DI_CreateDevice(LPCGUID pguid)
  42. {
  43.     LPDIRECTINPUT pdi;
  44.     LPDIRECTINPUTDEVICE pdev;
  45.     pdi = DI_CreateDI();
  46.     if (pdi) {
  47.         if (SUCCEEDED(IDirectInput_CreateDevice(pdi, pguid, &pdev, NULL))) {
  48.         } else {
  49.             pdev = 0;
  50.         }
  51.         IDirectInput_Release(pdi);
  52.     } else {
  53.         pdev = 0;
  54.     }
  55.     return pdev;
  56. }
  57. /****************************************************************************
  58.  *
  59.  *  DI3Info
  60.  *
  61.  *      Structure that describes the caps maintained by DIDEVCAPS
  62.  *      that existed in DirectX 3.
  63.  *
  64.  ****************************************************************************/
  65. CAPDEF DI3Info[] =
  66. {
  67.     DIVALDEF("Axes",                dwAxes),
  68.     DIVALDEF("Buttons",             dwButtons),
  69.     DIVALDEF("POVs",                dwPOVs),
  70.     DICAPDEF("ATTACHED",            dwFlags,        DIDC_ATTACHED),
  71.     DICAPDEF("POLLEDDEVICE",        dwFlags,        DIDC_POLLEDDEVICE),
  72.     DICAPDEF("EMULATED",            dwFlags,        DIDC_EMULATED),
  73.     {"", 0, 0}
  74. };
  75. /****************************************************************************
  76.  *
  77.  *  DI5Info
  78.  *
  79.  *      Structure that describes the caps maintained by DIDEVCAPS
  80.  *      that exist in DirectX 5 and were't in DirectX 3.
  81.  *
  82.  ****************************************************************************/
  83. CAPDEF DI5Info[] =
  84. {
  85.     DICAPDEF("FORCEFEEDBACK",       dwFlags,        DIDC_FORCEFEEDBACK),
  86.     DICAPDEF("FFATTACK",            dwFlags,        DIDC_FFATTACK),
  87.     DICAPDEF("FFFADE",              dwFlags,        DIDC_FFFADE),
  88.     DICAPDEF("SATURATION",          dwFlags,        DIDC_SATURATION),
  89.     DICAPDEF("POSNEGCOEFFICIENTS",  dwFlags,        DIDC_POSNEGCOEFFICIENTS),
  90.     DICAPDEF("POSNEGSATURATION",    dwFlags,        DIDC_POSNEGSATURATION),
  91.     DIVALDEF("FFSamplePeriod",      dwFFSamplePeriod),
  92.     DIVALDEF("FFMinTimeResolution", dwFFMinTimeResolution),
  93.     {"", 0, 0}
  94. };
  95. /****************************************************************************
  96.  *
  97.  *  DISubTypeList
  98.  *
  99.  *      List of various DirectInput device subtypes and their names.
  100.  *
  101.  ****************************************************************************/
  102. typedef struct SUBTYPEINFO {
  103.     DWORD dwDevType;
  104.     LPCTSTR pszName;
  105. } SUBTYPEINFO;
  106. #define SUBTYPE(type, subtype, name)    
  107.     {   MAKEWORD(DIDEVTYPE_##type, 
  108.         DIDEVTYPE##type##_##subtype), 
  109.         TEXT("%d - ") TEXT(name) }
  110. SUBTYPEINFO DISubTypes[] = {
  111.     SUBTYPE(MOUSE,          UNKNOWN,            "Unknown"),
  112.     SUBTYPE(MOUSE,          TRADITIONAL,        "Traditional"),
  113.     SUBTYPE(MOUSE,          FINGERSTICK,        "Fingerstick"),
  114.     SUBTYPE(MOUSE,          TOUCHPAD,           "Touchpad"),
  115.     SUBTYPE(MOUSE,          TRACKBALL,          "Trackball"),
  116.     SUBTYPE(KEYBOARD,       UNKNOWN,            "Unknown"),
  117.     SUBTYPE(KEYBOARD,       PCXT,               "XT"),
  118.     SUBTYPE(KEYBOARD,       OLIVETTI,           "Olivetti"),
  119.     SUBTYPE(KEYBOARD,       PCAT,               "AT"),
  120.     SUBTYPE(KEYBOARD,       PCENH,              "Enhanced"),
  121.     SUBTYPE(KEYBOARD,       NOKIA1050,          "Nokia 1050"),
  122.     SUBTYPE(KEYBOARD,       NOKIA9140,          "Nokia 9140"),
  123.     SUBTYPE(KEYBOARD,       NEC98,              "NEC98"),
  124.     SUBTYPE(KEYBOARD,       NEC98LAPTOP,        "NEC98 Laptop"),
  125.     SUBTYPE(KEYBOARD,       NEC98106,           "NEC98 106"),
  126.     SUBTYPE(KEYBOARD,       JAPAN106,           "Japan 106"),
  127.     SUBTYPE(KEYBOARD,       JAPANAX,            "Japan AX"),
  128.     SUBTYPE(KEYBOARD,       J3100,              "J3100"),
  129.     SUBTYPE(JOYSTICK,       UNKNOWN,            "Unknown"),
  130.     SUBTYPE(JOYSTICK,       TRADITIONAL,        "Traditional"),
  131.     SUBTYPE(JOYSTICK,       FLIGHTSTICK,        "Flightstick"),
  132.     SUBTYPE(JOYSTICK,       GAMEPAD,            "Gamepad"),
  133.     SUBTYPE(JOYSTICK,       RUDDER,             "Rudder"),
  134.     SUBTYPE(JOYSTICK,       WHEEL,              "Wheel"),
  135.     SUBTYPE(JOYSTICK,       HEADTRACKER,        "Head tracker"),
  136.     { 0, 0 },
  137. };
  138. /****************************************************************************
  139.  *
  140.  *  DIAddRow
  141.  *
  142.  *  Add a row to the growing two-column listview or printer.
  143.  *
  144.  *      lpInfo = print context or NULL if adding to listview
  145.  *      pszName = name of cap
  146.  *      pszFormat = wsprintf-style format string
  147.  *      ... = inserts for wsprintf
  148.  *
  149.  ****************************************************************************/
  150. BOOL __cdecl
  151. DIAddRow(PRINTCBINFO *lpInfo, LPCTSTR pszName, LPCTSTR pszFormat, ...)
  152. {
  153.     BOOL fRc;
  154.     TCHAR szBuf[1024];
  155.     int cch;
  156.     va_list ap;
  157.     va_start(ap, pszFormat);
  158.     cch = wvsprintf(szBuf, pszFormat, ap);
  159.     va_end(ap);
  160.     if (lpInfo == NULL) {
  161.         LVAddText(g_hwndLV, 0, pszName, 0);
  162.         LVAddText(g_hwndLV, 1, TEXT("%s"), szBuf);
  163.     } else {
  164.         int xName, xVal, yLine;
  165.         // Calculate Name and Value column x offsets
  166.         xName   = (lpInfo->dwCurrIndent * DEF_TAB_SIZE * lpInfo->dwCharWidth);
  167.         xVal    = xName + (32 * lpInfo->dwCharWidth);
  168.         yLine = lpInfo->dwCurrLine * lpInfo->dwLineHeight;
  169.         // Print name
  170.         fRc = PrintLine(xName, yLine, pszName, lstrlen(pszName), lpInfo);
  171.         if (!fRc) goto done;
  172.         // Print value
  173.         fRc = PrintLine(xVal, yLine, szBuf, cch, lpInfo);
  174.         if (!fRc) goto done;
  175.         // Advance to next line on page
  176.         fRc = PrintNextLine(lpInfo);
  177.         if (!fRc) goto done;
  178.     }
  179.     fRc = TRUE;
  180. done:;
  181.     return fRc;
  182. }
  183. /****************************************************************************
  184.  *
  185.  *  DIAddTypes
  186.  *
  187.  *  Emit the device type information to the output device.
  188.  *
  189.  *      lpInfo = print context or NULL if adding to listview
  190.  *      dwDevType = device type to decode
  191.  *
  192.  ****************************************************************************/
  193. BOOL DIAddTypes(PRINTCBINFO *lpInfo, DWORD dwDevType)
  194. {
  195.     BOOL fRc;
  196.     DWORD dwType;
  197.     LPCTSTR pszValue;
  198.     SUBTYPEINFO *psti;
  199.     /*
  200.      *  Add the type code.
  201.      */
  202.     dwType = GET_DIDEVICE_TYPE(dwDevType);
  203.     switch (dwType) {
  204.     case DIDEVTYPE_MOUSE:   pszValue = TEXT("%d - Mouse"); break;
  205.     case DIDEVTYPE_KEYBOARD:pszValue = TEXT("%d - Keyboard"); break;
  206.     case DIDEVTYPE_JOYSTICK:pszValue = TEXT("%d - Joystick"); break;
  207.     default:                pszValue = TEXT("%d"); break;
  208.     }
  209.     fRc = DIAddRow(lpInfo, "Type", pszValue, dwType);
  210.     if (!fRc) goto done;
  211.     /*
  212.      *  Add the sub type code.
  213.      */
  214.     pszValue = TEXT("%d");
  215.     for (psti = DISubTypes; psti->dwDevType; psti++) {
  216.         if (psti->dwDevType == (dwDevType & 0xFFFF)) {
  217.             pszValue = psti->pszName;
  218.             break;
  219.         }
  220.     }
  221.     fRc = DIAddRow(lpInfo, TEXT("Subtype"), pszValue,
  222.                    GET_DIDEVICE_SUBTYPE(dwDevType));
  223.     if (!fRc) goto done;
  224.     fRc = TRUE;
  225. done:;
  226.     return fRc;
  227. }
  228. /****************************************************************************
  229.  *
  230.  *  DIAddCapsToTarget
  231.  *
  232.  *  Add the caps either to the listview or to the printer.
  233.  *
  234.  *      lpInfo = print context or NULL if adding to listview
  235.  *      pcd = pointer to CAPDEF array describing the caps
  236.  *      pv = pointer to structure to be parsed
  237.  *
  238.  ****************************************************************************/
  239. BOOL
  240. DIAddCapsToTarget(PRINTCBINFO *lpInfo, CAPDEF *pcd, LPVOID pv)
  241. {
  242.     BOOL fRc;
  243.     if (lpInfo) {
  244.         fRc = PrintCapsToDC(pcd, pv, lpInfo);
  245.     } else {
  246.         AddMoreCapsToLV(pcd, pv);
  247.         fRc = TRUE;
  248.     }
  249.     return fRc;
  250. }
  251. /****************************************************************************
  252.  *
  253.  *  DIPrintCaps
  254.  *
  255.  *      lpInfo = print context or NULL if adding to listview
  256.  *      lParam1 = state info recorded by DIEnumDevCallback (LPGUID)
  257.  *      lParam2 = refdata (not used)
  258.  *
  259.  ****************************************************************************/
  260. BOOL
  261. DIPrintCaps(LPARAM lParam1, LPARAM lParam2, PRINTCBINFO *lpInfo)
  262. {
  263.     BOOL fRc;
  264.     LPGUID pguid = (LPGUID)lParam1;
  265.     LPDIRECTINPUTDEVICE pdev;
  266.     if (lpInfo == NULL) {
  267.         AddColsToLV();
  268.     }
  269.     fRc = TRUE;
  270.     pdev = DI_CreateDevice(pguid);
  271.     if (pdev) {
  272.         DIDEVCAPS caps;
  273.         HRESULT hres;
  274.         /*
  275.          *  First use the DX3 caps.
  276.          */
  277.         caps.dwSize = sizeof(DIDEVCAPS_DX3);
  278.         hres = IDirectInputDevice_GetCapabilities(pdev, &caps);
  279.         if (SUCCEEDED(hres)) {
  280.             fRc = DIAddTypes(lpInfo, caps.dwDevType) &&
  281.                   DIAddCapsToTarget(lpInfo, DI3Info, &caps);
  282.         }
  283.         /*
  284.          *  Now get the DX5 caps if we haven't cancelled printing yet.
  285.          */
  286.         if (fRc) {
  287.             caps.dwSize = sizeof(DIDEVCAPS);
  288.             hres = IDirectInputDevice_GetCapabilities(pdev, &caps);
  289.             if (SUCCEEDED(hres)) {
  290.                 fRc = DIAddCapsToTarget(lpInfo, DI5Info, &caps);
  291.             }
  292.         }
  293.         IDirectInputDevice_Release(pdev);
  294.     }
  295.     return fRc;
  296. }
  297. /****************************************************************************
  298.  *
  299.  *  DIAddCaps
  300.  *
  301.  *      lParam1 = state info recorded by DIEnumDevCallback (LPGUID)
  302.  *      lParam2 = refdata (not used)
  303.  *
  304.  ****************************************************************************/
  305. void
  306. DIAddCaps(LPARAM lParam1, LPARAM lParam2)
  307. {
  308.     DIPrintCaps(lParam1, lParam2, NULL);
  309. }
  310. /****************************************************************************
  311.  *
  312.  *  DIEnumEffCallback
  313.  *
  314.  *  Add the enumerated DirectInput effect to the listview.
  315.  *
  316.  ****************************************************************************/
  317. BOOL CALLBACK
  318. DIEnumEffCallback(LPCDIEFFECTINFO pei, LPVOID lpInfo)
  319. {
  320.     BOOL fRc;
  321.     const GUID *pguid = &pei->guid;
  322.     fRc = DIAddRow(lpInfo, pei->tszName,
  323.                    TEXT("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  324.                     pguid->Data1, pguid->Data2, pguid->Data3,
  325.                     pguid->Data4[0], pguid->Data4[1],
  326.                     pguid->Data4[2], pguid->Data4[3],
  327.                     pguid->Data4[4], pguid->Data4[5],
  328.                     pguid->Data4[6], pguid->Data4[7]);
  329.     if (fRc) {
  330.         return DIENUM_CONTINUE;
  331.     } else {
  332.         return DIENUM_STOP;
  333.     }
  334. }
  335. /****************************************************************************
  336.  *
  337.  *  DIPrintEffects
  338.  *
  339.  *      lpInfo = print context or NULL if adding to listview
  340.  *      lParam1 = state info recorded by DIEnumDevCallback (LPGUID)
  341.  *      lParam2 = refdata (not used)
  342.  *
  343.  ****************************************************************************/
  344. BOOL
  345. DIPrintEffects(LPARAM lParam1, LPARAM lParam2, PRINTCBINFO *lpInfo)
  346. {
  347.     BOOL fRc;
  348.     LPGUID pguid = (LPGUID)lParam1;
  349.     LPDIRECTINPUTDEVICE pdev;
  350.     /*
  351.      *  The effects are not a simple name/value thing.
  352.      *  But DXView doesn't like multiple nesting levels,
  353.      *  so we mash it into the name/value paradigm
  354.      *  because I'm lazy.  Someday I won't be quite so
  355.      *  lazy and do it right.
  356.      */
  357.     if (lpInfo == NULL) {
  358.         AddColsToLV();
  359.     }
  360.     fRc = TRUE;
  361.     pdev = DI_CreateDevice(pguid);
  362.     if (pdev) {
  363.         LPDIRECTINPUTDEVICE2 pdev2;
  364.         HRESULT hres;
  365.         hres = IDirectInputDevice_QueryInterface(
  366.                         pdev, &IID_IDirectInputDevice2, (LPVOID *)&pdev2);
  367.         if (SUCCEEDED(hres)) {
  368.             /*
  369.              *  Enumerate the effects and add them to the listview.
  370.              */
  371.             IDirectInputDevice2_EnumEffects(pdev2,
  372.                                             DIEnumEffCallback, lpInfo,
  373.                                             DIEFT_ALL);
  374.             IDirectInputDevice2_Release(pdev2);
  375.         }
  376.         IDirectInputDevice_Release(pdev);
  377.     }
  378.     return fRc;
  379. }
  380. /****************************************************************************
  381.  *
  382.  *  DIAddEffects
  383.  *
  384.  *      lParam1 = state info recorded by DIEnumDevCallback (LPGUID)
  385.  *      lParam2 = refdata (not used)
  386.  *
  387.  ****************************************************************************/
  388. void
  389. DIAddEffects(LPARAM lParam1, LPARAM lParam2)
  390. {
  391.     DIPrintEffects(lParam1, lParam2, NULL);
  392. }
  393. /****************************************************************************
  394.  ***************************************************************************/
  395. CAPDEFS DICapDefs[] =
  396. {
  397.     {"",                    DIAddCaps,          0,              DIPrintCaps},
  398.     {"Effects",             DIAddEffects,       0,              DIPrintEffects},
  399.     {NULL, 0, 0, NULL}
  400. };
  401. /****************************************************************************
  402.  *
  403.  *  DIEnumDevCallback
  404.  *
  405.  *  Add the enumerated DirectInput device to the treeview.
  406.  *
  407.  ****************************************************************************/
  408. BOOL CALLBACK
  409. DIEnumDevCallback(LPCDIDEVICEINSTANCE pinst, LPVOID pv)
  410. {
  411.     HTREEITEM hParent = pv;
  412.     TCHAR     szText[MAX_PATH + 2 + MAX_PATH + 2];
  413.     LPGUID    pguid;
  414.     pguid = LocalAlloc(LPTR, sizeof(GUID));
  415.     if (pguid == NULL) {
  416.         return DIENUM_STOP;
  417.     }
  418.     *pguid = pinst->guidInstance;
  419.     wsprintf(szText, "%s (%s)", pinst->tszInstanceName,
  420.                                 pinst->tszProductName);
  421.     DICapDefs[0].szName = szText;
  422.     AddCapsToTV(hParent, DICapDefs, (LPARAM)pguid);
  423.     return(DIENUM_CONTINUE);
  424. }
  425. /****************************************************************************
  426.  *
  427.  *  DI_FillTree
  428.  *
  429.  *  Add the DirectInput nodes to the treeview.
  430.  *
  431.  ****************************************************************************/
  432. void
  433. DI_FillTree(void)
  434. {
  435.     LPDIRECTINPUT pdi;
  436.     HTREEITEM hTree;
  437.     // Add direct input devices if DInput is found
  438.     pdi = DI_CreateDI();
  439.     if (pdi) {
  440.         hTree = TVAddNode(TVI_ROOT, "DirectInput Devices", TRUE,
  441.                           IDI_DIRECTX, NULL, 0, 0, NULL);
  442.         IDirectInput_EnumDevices(pdi, 0, DIEnumDevCallback, hTree,
  443.                                  DIEDFL_ALLDEVICES);
  444.         TreeView_Expand(g_hwndTV, hTree, TVE_EXPAND);
  445.         IDirectInput_Release(pdi);
  446.     }
  447. }