1 /* 2 * PROJECT: ReactX Diagnosis Application 3 * LICENSE: LGPL - See COPYING in the top level directory 4 * FILE: base/applications/dxdiag/input.c 5 * PURPOSE: ReactX diagnosis input page 6 * COPYRIGHT: Copyright 2008 Johannes Anderwald 7 * 8 */ 9 10 #include "precomp.h" 11 12 #include <dinput.h> 13 14 typedef struct 15 { 16 HWND hwndDlg; 17 IDirectInput8W * pObj; 18 HWND hDevList; 19 HWND hPortTree; 20 INT Count; 21 }INPUT_DIALOG_CONTEXT, *PINPUT_DIALOG_CONTEXT; 22 23 24 BOOL CALLBACK DirectInputEnumDevCb( 25 LPCDIDEVICEINSTANCEW lpddi, 26 LPVOID pvRef 27 ) 28 { 29 HRESULT hResult; 30 WCHAR szText[100]; 31 IDirectInputDevice8W * pDev = NULL; 32 //DIPROPGUIDANDPATH GuidPath; 33 //DIPROPSTRING TypeName; 34 DIPROPDWORD VendorID; 35 DIDEVCAPS DevCaps; 36 DWORD dwProductID; 37 DWORD dwManufacturerID; 38 LVITEMW Item; 39 LRESULT lResult; 40 41 PINPUT_DIALOG_CONTEXT pContext = (PINPUT_DIALOG_CONTEXT)pvRef; 42 43 if (!pContext) 44 return DIENUM_STOP; 45 46 ZeroMemory(&Item, sizeof(LVITEMW)); 47 Item.mask = LVIF_TEXT; 48 Item.pszText = (LPWSTR)lpddi->tszProductName; 49 Item.iItem = pContext->Count; 50 /* insert device item */ 51 lResult = SendMessageW(pContext->hDevList, LVM_INSERTITEM, 0, (LPARAM)&Item); 52 if (lResult == -1) 53 return DIENUM_CONTINUE; 54 55 /* is the device attached */ 56 szText[0] = L'\0'; 57 hResult = pContext->pObj->lpVtbl->GetDeviceStatus(pContext->pObj, &lpddi->guidInstance); 58 if (hResult == DI_OK) 59 LoadStringW(hInst, IDS_DEVICE_STATUS_ATTACHED, szText, sizeof(szText) / sizeof(WCHAR)); 60 else if (hResult == DI_NOTATTACHED) 61 LoadStringW(hInst, IDS_DEVICE_STATUS_MISSING, szText, sizeof(szText) / sizeof(WCHAR)); 62 else 63 LoadStringW(hInst, IDS_DEVICE_STATUS_UNKNOWN, szText, sizeof(szText) / sizeof(WCHAR)); 64 65 if (szText[0]) 66 { 67 szText[(sizeof(szText) / sizeof(WCHAR))-1] = L'\0'; 68 Item.iSubItem = 1; 69 Item.pszText = szText; 70 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 71 } 72 73 hResult = pContext->pObj->lpVtbl->CreateDevice(pContext->pObj, &lpddi->guidInstance, &pDev, NULL); 74 75 if (hResult != DI_OK) 76 return DIENUM_STOP; 77 78 ZeroMemory(&VendorID, sizeof(DIPROPDWORD)); 79 VendorID.diph.dwSize = sizeof(DIPROPDWORD); 80 VendorID.diph.dwHeaderSize = sizeof(DIPROPHEADER); 81 82 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_VIDPID, (LPDIPROPHEADER)&VendorID); 83 if (hResult == DI_OK) 84 { 85 /* set manufacturer id */ 86 dwManufacturerID = LOWORD(VendorID.dwData); 87 wsprintfW(szText, L"0x%04X", dwManufacturerID); 88 Item.iSubItem = 3; 89 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 90 /* set product id */ 91 dwProductID = HIWORD(VendorID.dwData); 92 wsprintfW(szText, L"0x%04X", dwProductID); 93 Item.iSubItem = 4; 94 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 95 } 96 else 97 { 98 szText[0] = L'\0'; 99 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText) / sizeof(WCHAR)); 100 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 101 /* set manufacturer id */ 102 Item.iSubItem = 3; 103 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 104 /* set product id */ 105 Item.iSubItem = 4; 106 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 107 } 108 109 /* check for force feedback support */ 110 DevCaps.dwSize = sizeof(DIDEVCAPS); // use DIDEVCAPS_DX3 for DX3 support 111 hResult = pDev->lpVtbl->GetCapabilities(pDev, &DevCaps); 112 szText[0] = L'\0'; 113 if (hResult == DI_OK) 114 { 115 if (DevCaps.dwFlags & DIDC_FORCEFEEDBACK) 116 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR)); 117 else 118 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText)/sizeof(WCHAR)); 119 } 120 else 121 { 122 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText)/sizeof(WCHAR)); 123 } 124 125 Item.iSubItem = 5; 126 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item); 127 128 129 #if 0 130 ZeroMemory(&GuidPath, sizeof(DIPROPGUIDANDPATH)); 131 GuidPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); 132 GuidPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); 133 GuidPath.diph.dwHow = DIPH_DEVICE; 134 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GUIDANDPATH, (LPDIPROPHEADER)&GuidPath); 135 136 ZeroMemory(&TypeName, sizeof(TypeName)); 137 TypeName.diph.dwSize = sizeof(TypeName); 138 TypeName.diph.dwHeaderSize = sizeof(DIPROPHEADER); 139 TypeName.diph.dwHow = DIPH_DEVICE; 140 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GETPORTDISPLAYNAME, (LPDIPROPHEADER)&TypeName); 141 142 143 #endif 144 145 146 pDev->lpVtbl->Release(pDev); 147 pContext->Count++; 148 149 150 return DIENUM_CONTINUE; 151 } 152 153 VOID 154 InputPageInitListViewColumns(PINPUT_DIALOG_CONTEXT pContext) 155 { 156 WCHAR szText[256]; 157 LVCOLUMNW lvcolumn; 158 INT Index; 159 160 161 pContext->hDevList = GetDlgItem(pContext->hwndDlg, IDC_LIST_DEVICE); 162 163 /* Highlights the entire row instead of just the selected item in the first column. 164 This increases readability on the selected item in the list. */ 165 SendMessage(pContext->hDevList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); 166 167 ZeroMemory(&lvcolumn, sizeof(LVCOLUMNW)); 168 lvcolumn.pszText = szText; 169 lvcolumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; 170 lvcolumn.fmt = LVCFMT_LEFT; 171 lvcolumn.cx = 100; 172 173 for(Index = 0; Index < 6; Index++) 174 { 175 szText[0] = L'\0'; 176 LoadStringW(hInst, IDS_DEVICE_NAME + Index, szText, sizeof(szText) / sizeof(WCHAR)); 177 szText[(sizeof(szText) / sizeof(WCHAR))-1] = L'\0'; 178 if (SendMessageW(pContext->hDevList, LVM_INSERTCOLUMNW, Index, (LPARAM)&lvcolumn) == -1) 179 return; 180 } 181 } 182 183 static 184 void 185 InitializeDirectInputDialog(HWND hwndDlg) 186 { 187 INPUT_DIALOG_CONTEXT Context; 188 HRESULT hResult; 189 IDirectInput8W * pObj; 190 191 hResult = DirectInput8Create(hInst, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (LPVOID*)&pObj, NULL); 192 if (hResult != DI_OK) 193 return; 194 195 ZeroMemory(&Context, sizeof(Context)); 196 Context.pObj = pObj; 197 Context.hwndDlg = hwndDlg; 198 InputPageInitListViewColumns(&Context); 199 pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES); 200 201 pObj->lpVtbl->Release(pObj); 202 } 203 204 205 206 INT_PTR CALLBACK 207 InputPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 208 { 209 UNREFERENCED_PARAMETER(lParam); 210 UNREFERENCED_PARAMETER(wParam); 211 switch (message) { 212 case WM_INITDIALOG: 213 { 214 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER); 215 InitializeDirectInputDialog(hDlg); 216 return TRUE; 217 } 218 } 219 220 return FALSE; 221 } 222