RobK6364
asked on
where's the controller ID?
hello experts, i'm trying to enumerate all the joysticks on my pc... and i've been had some success, i got the names... but where is the controller ID? can i assume the controller ID's are coming back in the order of enumeration? in other words in my code below... is GetItem(1) always controller ID 1? and GetItem(2) always ID 2 and so forth?
and also another side question... below my references are for DirectX8... if i use DirectX7 instead, will that allow me to perform this simple enumeration on DirectX7 or later? or do i need to detect the DirectX version on the user's os and use the references that match his version?
'// ========================== ==========
Dim x As Integer
Dim diJoystick As DirectInputDevice8
Dim enumDevice As DirectInputEnumDevices8
Dim DirectX As DirectX8
Dim DInput As DirectInput8
Dim DDeviceEnum As DirectInputEnumDevices8
Dim DDeviceInst As DirectInputDeviceInstance8
Set DirectX = New DirectX8
Set DInput = DirectX.DirectInputCreate( )
Set DDeviceEnum = DInput.GetDIDevice(DI8DEVT YPE_JOYSTI CK, DIEDFL_ATTACHEDONLY)
Set diJoystick = DInput.CreateDevice(DDevic eEnum.GetI tem(1).Get GuidInstan ce)
For x = 1 To DDeviceEnum.GetCount
Set DDeviceInst = DDeviceEnum.GetItem(x)
Debug.Print DDeviceInst.GetProductName
Next x
'// ========================== ==========
and also another side question... below my references are for DirectX8... if i use DirectX7 instead, will that allow me to perform this simple enumeration on DirectX7 or later? or do i need to detect the DirectX version on the user's os and use the references that match his version?
'// ==========================
Dim x As Integer
Dim diJoystick As DirectInputDevice8
Dim enumDevice As DirectInputEnumDevices8
Dim DirectX As DirectX8
Dim DInput As DirectInput8
Dim DDeviceEnum As DirectInputEnumDevices8
Dim DDeviceInst As DirectInputDeviceInstance8
Set DirectX = New DirectX8
Set DInput = DirectX.DirectInputCreate(
Set DDeviceEnum = DInput.GetDIDevice(DI8DEVT
Set diJoystick = DInput.CreateDevice(DDevic
For x = 1 To DDeviceEnum.GetCount
Set DDeviceInst = DDeviceEnum.GetItem(x)
Debug.Print DDeviceInst.GetProductName
Next x
'// ==========================
each version of directx uses slightly different interfaces, and exposes different capabilities. You'd probably want to use DX8 or DX9, and not go back to DX7 unless you need to support really old machines.
what 'controller ID' are you looking for? You are already using GetGuidInstance to create the device linkage -- that's a unique identifier for the device on that system.
You can also use DDeviceInst.GetInstanceNam e for a human-readable form of 'controller ID', like "Joystick 1" (the example the MSDN website gives..).
d
what 'controller ID' are you looking for? You are already using GetGuidInstance to create the device linkage -- that's a unique identifier for the device on that system.
You can also use DDeviceInst.GetInstanceNam
d
ASKER
i'm looking for the controller id in respect to functions like..
joyGetPosEx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joygetposex.asp
or..
joyGetDevCaps
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joygetposex.asp
joyGetPosEx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joygetposex.asp
or..
joyGetDevCaps
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joygetposex.asp
ASKER
maybe joystick id is the correct term... unless those are 2 different things? all i want to do is put a "human-readable" name in a combobox... and then query joyGetDevCaps for the info for the controller name that the user selects from that combo... for instance.
The two API sets are completely different -- I don't know of any connection between the old joyGetZZZ calls and DirectX. There a reason you are trying to mix the two?
GetInstanceName (and/or GetProductName) are your best human-readable strings for devices under DirectX.
GetInstanceName (and/or GetProductName) are your best human-readable strings for devices under DirectX.
ASKER
well.. basically i have developed my app around the joyGetZZZ API calls... figuring later to create the user interface. it's just now that i am trying to build the combobox that i mentioned... which should hold 'human-readable' controller names... yet i need to know which joyID to enter into my functions based on that.
so if there is no connection between the directx and the api... do you know of a way to get a 'human readable' names for your controllers another way?
the JOYCAPS structure returned by joyGetDevCaps contains ...
wMid
Manufacturer identifier. Manufacturer identifiers are defined in Manufacturer and Product Identifiers.
wPid
Product identifier. Product identifiers are defined in Manufacturer and Product Identifiers.
szPname
Null-terminated string containing the joystick product name.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joycaps_str.asp
... but none of those seem to lead to a human-readable name. the product name returned is "Microsoft Joystick 1" or something like that, and not the nice name returned by DDeviceInst.GetProductName or DDeviceInst.GetInstanceNam e
any ideas how this can be done without directx?
so if there is no connection between the directx and the api... do you know of a way to get a 'human readable' names for your controllers another way?
the JOYCAPS structure returned by joyGetDevCaps contains ...
wMid
Manufacturer identifier. Manufacturer identifiers are defined in Manufacturer and Product Identifiers.
wPid
Product identifier. Product identifiers are defined in Manufacturer and Product Identifiers.
szPname
Null-terminated string containing the joystick product name.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_joycaps_str.asp
... but none of those seem to lead to a human-readable name. the product name returned is "Microsoft Joystick 1" or something like that, and not the nice name returned by DDeviceInst.GetProductName
any ideas how this can be done without directx?
Not off the top of my head. It's been a loooooong time since I used the joyZZZ functions, since DirectInput has much more control (and information, as you are noting!).
It is possible there's a way to look up the longer string in the registry (szRegKey), but I don't know of it. That doesn't mean it doesn't exist. You can also potentially use the manufacturer and product IDs, if you have the most up-to-date mmreg.h, but I've no clue if you can get to a string from that.
Yeah, unfortunately, you're hitting the wall that was why DirectInput was created -- it exposed everything developers needed! ;)
-d
It is possible there's a way to look up the longer string in the registry (szRegKey), but I don't know of it. That doesn't mean it doesn't exist. You can also potentially use the manufacturer and product IDs, if you have the most up-to-date mmreg.h, but I've no clue if you can get to a string from that.
Yeah, unfortunately, you're hitting the wall that was why DirectInput was created -- it exposed everything developers needed! ;)
-d
ASKER
hmm... i found this in the MSDN
// -------------------------- ---------- ---------- ---------- ---------- ----------
//
// Function: joyGetOEMProductName
// Parameters: UINT id - Joystick ID from JOYSTICKID1 to JOYSTICK16
// TCHAR * pszName - String storage for the OEM Product name
// for the selected Joystick device specified
// by the parameter "id"
//
// Returns: If Successful, pszName contains OEM product name for JOYSTICKID
// else Failure, returns MMRESULT error code, and pszName is cleared.
//
// Comments:
// JOYSTICKID1 to JOYSTICKID16 is zero-based, while the registry entries are
// 1-based. This routine expects the parameter "id" to be using JOYSTICKID1
// to JOYSTICKID16 which are defined in the multimedia header file mmsystem.h
// The following registry keys/values are defined in the header file
// regstr.h:
// REGSTR_PATH_JOYCONFIG
// REGSTR_PATH_JOYOEM
// REGSTR_VAL_JOYOEMNAME
//
// -------------------------- ---------- ---------- ---------- ---------- ----------
MMRESULT joyGetOEMProductName(UINT id, TCHAR * pszName)
{
JOYCAPS JoyCaps;
TCHAR szKey[256];
TCHAR szValue[256];
UCHAR szOEMKey[256];
HKEY hKey;
DWORD dwcb;
LONG lr;
// Note: JOYSTICKID1-16 is zero-based; registry entries for VJOYD areis 1-based.
id++;
if (id > joyGetNumDevs() ) return JOYERR_NOCANDO;
// Open .. MediaResources\CurrentJoys tickSettin gs
joyGetDevCaps((id-1), &JoyCaps, sizeof(JoyCaps));
sprintf(szKey,
"%s\\%s\\%s",
REGSTR_PATH_JOYCONFIG,
JoyCaps.szRegKey,
REGSTR_KEY_JOYCURR);
lr = RegOpenKeyEx(HKEY_LOCAL_MA CHINE, (LPTSTR) &szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Key name. If the query is unsuccessful, then Null the string and return
// an Error.
dwcb = sizeof(szOEMKey);
sprintf(szValue, "Joystick%d%s", id, REGSTR_VAL_JOYOEMNAME);
lr = RegQueryValueEx(hKey, szValue, 0, 0, (LPBYTE) &szOEMKey, (LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
{
*pszName = 0;
return JOYERR_NOCANDO;
}
// Open OEM Key from ...MediaProperties
sprintf(szKey, "%s\\%s", REGSTR_PATH_JOYOEM, szOEMKey);
lr = RegOpenKeyEx(HKEY_LOCAL_MA CHINE, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Name
dwcb = sizeof(szValue);
lr = RegQueryValueEx( hKey,
REGSTR_VAL_JOYOEMNAME,
0, 0,
(LPBYTE) pszName,
(LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
return JOYERR_NOCANDO;
else
return JOYERR_NOERROR;
}
... i think that may return the name i want, by looking up the szRegKey... but my problem is that i cant find regstr.h to get vb const definitions for REGSTR_PATH_JOYCONFIG, REGSTR_PATH_JOYOEM, or REGSTR_VAL_JOYOEMNAME.
// --------------------------
//
// Function: joyGetOEMProductName
// Parameters: UINT id - Joystick ID from JOYSTICKID1 to JOYSTICK16
// TCHAR * pszName - String storage for the OEM Product name
// for the selected Joystick device specified
// by the parameter "id"
//
// Returns: If Successful, pszName contains OEM product name for JOYSTICKID
// else Failure, returns MMRESULT error code, and pszName is cleared.
//
// Comments:
// JOYSTICKID1 to JOYSTICKID16 is zero-based, while the registry entries are
// 1-based. This routine expects the parameter "id" to be using JOYSTICKID1
// to JOYSTICKID16 which are defined in the multimedia header file mmsystem.h
// The following registry keys/values are defined in the header file
// regstr.h:
// REGSTR_PATH_JOYCONFIG
// REGSTR_PATH_JOYOEM
// REGSTR_VAL_JOYOEMNAME
//
// --------------------------
MMRESULT joyGetOEMProductName(UINT id, TCHAR * pszName)
{
JOYCAPS JoyCaps;
TCHAR szKey[256];
TCHAR szValue[256];
UCHAR szOEMKey[256];
HKEY hKey;
DWORD dwcb;
LONG lr;
// Note: JOYSTICKID1-16 is zero-based; registry entries for VJOYD areis 1-based.
id++;
if (id > joyGetNumDevs() ) return JOYERR_NOCANDO;
// Open .. MediaResources\CurrentJoys
joyGetDevCaps((id-1), &JoyCaps, sizeof(JoyCaps));
sprintf(szKey,
"%s\\%s\\%s",
REGSTR_PATH_JOYCONFIG,
JoyCaps.szRegKey,
REGSTR_KEY_JOYCURR);
lr = RegOpenKeyEx(HKEY_LOCAL_MA
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Key name. If the query is unsuccessful, then Null the string and return
// an Error.
dwcb = sizeof(szOEMKey);
sprintf(szValue, "Joystick%d%s", id, REGSTR_VAL_JOYOEMNAME);
lr = RegQueryValueEx(hKey, szValue, 0, 0, (LPBYTE) &szOEMKey, (LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
{
*pszName = 0;
return JOYERR_NOCANDO;
}
// Open OEM Key from ...MediaProperties
sprintf(szKey, "%s\\%s", REGSTR_PATH_JOYOEM, szOEMKey);
lr = RegOpenKeyEx(HKEY_LOCAL_MA
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Name
dwcb = sizeof(szValue);
lr = RegQueryValueEx( hKey,
REGSTR_VAL_JOYOEMNAME,
0, 0,
(LPBYTE) pszName,
(LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
return JOYERR_NOCANDO;
else
return JOYERR_NOERROR;
}
... i think that may return the name i want, by looking up the szRegKey... but my problem is that i cant find regstr.h to get vb const definitions for REGSTR_PATH_JOYCONFIG, REGSTR_PATH_JOYOEM, or REGSTR_VAL_JOYOEMNAME.
ASKER
nevermind... i found regstr.h and converted the function to VB... works like a charm :)
'//======================= ========== ===
Const REGSTR_PATH_CURRENT_CONTRO L_SET As String = "System\CurrentControlSet\ Control"
Const REGSTR_PATH_MEDIARESOURCES As String = REGSTR_PATH_CURRENT_CONTRO L_SET & "\MediaResources"
Const REGSTR_PATH_MEDIAPROPERTIE S As String = REGSTR_PATH_CURRENT_CONTRO L_SET & "\MediaProperties"
Const REGSTR_PATH_PRIVATEPROPERT IES As String = REGSTR_PATH_MEDIAPROPERTIE S & "\PrivateProperties"
Const REGSTR_PATH_JOYOEM As String = REGSTR_PATH_PRIVATEPROPERT IES & "\Joystick\OEM"
Const REGSTR_PATH_JOYCONFIG As String = REGSTR_PATH_MEDIARESOURCES & "\Joystick"
Const REGSTR_VAL_JOYOEMNAME As String = "OEMName"
Const REGSTR_KEY_JOYCURR As String = "CurrentJoystickSettings"
Public Function joyGetOEMProductName(joyID As Integer) As String
'// Note: JOYSTICKID1-16 is zero-based, registry entries for VJOYD are 1-based.
Dim lR As Long
Dim oJoyCaps As JOYCAPS
Dim szKey As String
Dim szValue As String
Dim szOEMKey As String * 256
Dim hKey As Long
Dim sRegKey As String
Dim sResult As String * 256
If (joyID > joyGetNumDevs()) Then Exit Function
'// Open .. MediaResources\CurrentJoys tickSettin gs
Call joyGetDevCaps(joyID, oJoyCaps, Len(oJoyCaps))
sRegKey = Left(oJoyCaps.szRegKey, InStr(oJoyCaps.szRegKey, vbNullChar) - 1)
szKey = REGSTR_PATH_JOYCONFIG & "\" & sRegKey & "\" & REGSTR_KEY_JOYCURR
lR = RegOpenKeyEx(HKEY_LOCAL_MA CHINE, szKey, 0, KEY_ALL_ACCESS, hKey)
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Get OEM Key name. If the query is unsuccesful, then Null the string and return an Error.
szValue = "Joystick" & (joyID + 1) & REGSTR_VAL_JOYOEMNAME
lR = RegQueryValueEx(hKey, szValue, 0, 0, ByVal szOEMKey, Len(szOEMKey))
Call RegCloseKey(hKey)
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Open OEM Key from ...MediaProperties
szKey = REGSTR_PATH_JOYOEM & "\" & szOEMKey
lR = RegOpenKeyEx(HKEY_LOCAL_MA CHINE, szKey, 0, KEY_ALL_ACCESS, hKey)
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Get OEM Name
lR = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, ByVal sResult, Len(sResult))
Call RegCloseKey(hKey)
'// return the product name
If (lR = ERROR_SUCCESS) Then joyGetOEMProductName = Left(sResult, InStr(sResult, vbNullChar) - 1)
End Function
'//======================= ========== ===
'//=======================
Const REGSTR_PATH_CURRENT_CONTRO
Const REGSTR_PATH_MEDIARESOURCES
Const REGSTR_PATH_MEDIAPROPERTIE
Const REGSTR_PATH_PRIVATEPROPERT
Const REGSTR_PATH_JOYOEM As String = REGSTR_PATH_PRIVATEPROPERT
Const REGSTR_PATH_JOYCONFIG As String = REGSTR_PATH_MEDIARESOURCES
Const REGSTR_VAL_JOYOEMNAME As String = "OEMName"
Const REGSTR_KEY_JOYCURR As String = "CurrentJoystickSettings"
Public Function joyGetOEMProductName(joyID
'// Note: JOYSTICKID1-16 is zero-based, registry entries for VJOYD are 1-based.
Dim lR As Long
Dim oJoyCaps As JOYCAPS
Dim szKey As String
Dim szValue As String
Dim szOEMKey As String * 256
Dim hKey As Long
Dim sRegKey As String
Dim sResult As String * 256
If (joyID > joyGetNumDevs()) Then Exit Function
'// Open .. MediaResources\CurrentJoys
Call joyGetDevCaps(joyID, oJoyCaps, Len(oJoyCaps))
sRegKey = Left(oJoyCaps.szRegKey, InStr(oJoyCaps.szRegKey, vbNullChar) - 1)
szKey = REGSTR_PATH_JOYCONFIG & "\" & sRegKey & "\" & REGSTR_KEY_JOYCURR
lR = RegOpenKeyEx(HKEY_LOCAL_MA
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Get OEM Key name. If the query is unsuccesful, then Null the string and return an Error.
szValue = "Joystick" & (joyID + 1) & REGSTR_VAL_JOYOEMNAME
lR = RegQueryValueEx(hKey, szValue, 0, 0, ByVal szOEMKey, Len(szOEMKey))
Call RegCloseKey(hKey)
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Open OEM Key from ...MediaProperties
szKey = REGSTR_PATH_JOYOEM & "\" & szOEMKey
lR = RegOpenKeyEx(HKEY_LOCAL_MA
If (lR <> ERROR_SUCCESS) Then Exit Function
'// Get OEM Name
lR = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, ByVal sResult, Len(sResult))
Call RegCloseKey(hKey)
'// return the product name
If (lR = ERROR_SUCCESS) Then joyGetOEMProductName = Left(sResult, InStr(sResult, vbNullChar) - 1)
End Function
'//=======================
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER