Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

where's the controller ID?

Posted on 2004-10-30
10
Medium Priority
?
1,784 Views
Last Modified: 2013-12-26
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(DI8DEVTYPE_JOYSTICK, DIEDFL_ATTACHEDONLY)

Set diJoystick = DInput.CreateDevice(DDeviceEnum.GetItem(1).GetGuidInstance)

For x = 1 To DDeviceEnum.GetCount
    Set DDeviceInst = DDeviceEnum.GetItem(x)
    Debug.Print DDeviceInst.GetProductName
Next x
'// ====================================
0
Comment
Question by:RobK6364
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 1

Author Comment

by:RobK6364
ID: 12455738
P.S.  yeah, this is VB... but if you give me help in C++, that's cool too :)
0
 
LVL 17

Expert Comment

by:davebytes
ID: 12479445
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.GetInstanceName for a human-readable form of 'controller ID', like "Joystick 1" (the example the MSDN website gives..).

d
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:RobK6364
ID: 12480122
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.
0
 
LVL 17

Expert Comment

by:davebytes
ID: 12480176
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.
0
 
LVL 1

Author Comment

by:RobK6364
ID: 12480387
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.GetInstanceName

any ideas how this can be done without directx?
0
 
LVL 17

Expert Comment

by:davebytes
ID: 12484155
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
0
 
LVL 1

Author Comment

by:RobK6364
ID: 12485349
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\CurrentJoystickSettings
 joyGetDevCaps((id-1), &JoyCaps, sizeof(JoyCaps));
 sprintf(szKey,
   "%s\\%s\\%s",
   REGSTR_PATH_JOYCONFIG,
   JoyCaps.szRegKey,
   REGSTR_KEY_JOYCURR);

 lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (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_MACHINE, 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.
0
 
LVL 1

Author Comment

by:RobK6364
ID: 12486328
nevermind... i found regstr.h and converted the function to VB... works like a charm :)


'//====================================
Const REGSTR_PATH_CURRENT_CONTROL_SET As String = "System\CurrentControlSet\Control"
Const REGSTR_PATH_MEDIARESOURCES As String = REGSTR_PATH_CURRENT_CONTROL_SET & "\MediaResources"
Const REGSTR_PATH_MEDIAPROPERTIES As String = REGSTR_PATH_CURRENT_CONTROL_SET & "\MediaProperties"
Const REGSTR_PATH_PRIVATEPROPERTIES As String = REGSTR_PATH_MEDIAPROPERTIES & "\PrivateProperties"
Const REGSTR_PATH_JOYOEM As String = REGSTR_PATH_PRIVATEPROPERTIES & "\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\CurrentJoystickSettings
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_MACHINE, 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_MACHINE, 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
'//====================================
0
 
LVL 1

Accepted Solution

by:
GhostMod earned 0 total points
ID: 12508994
PAQd, 125 points refunded - asker posted solution

GhostMod
Community Support Moderator
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Artificial Intelligence comes in many forms, and for game developers, Path-Finding is an important ability for making an NPC (Non-Playable Character) maneuver through terrain.  A* is a particularly easy way to approach it.  I’ll start with the algor…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question