- Yesterday, plugged in a USB 360 controller, used it, unplugged it.
- Today, plugged in a wireless receiver and connected a wireless 360 controller.
- Ran the following script:
if name := GetKeyState(A_Index "JoyName")
list .= A_Index ": " name "`n"
MsgBox % list
This produced the following:
2: Microsoft PC-joystick driver
The wireless controller is Joystick 2. If the USB controller is plugged in, it is Joystick 1. As far as I can tell, Windows remembers each controller, and they are always assigned the same ID regardless of which order they are disconnected/connected in.
I have verified that if joyGetDevCaps
(which is used by GetKeyState) is called while the controller is connected, calling it again from the same process will succeed (and produce a name) even if the controller is no longer connected. This API is part of Windows, hence "the OS says there's a controller".
VarSetCapacity(caps, 728, 0)
if DllCall("winmm\joyGetDevCapsW", "uint", ID-1, "ptr", &caps, "uint", 728) != 0
return StrGet(&caps+4, "UTF-16")
MsgBox % joyGetName(1)
So as I said, your script is flawed - it relies on the name being blank when the controller is disconnected. This is probably based on a false assumption in the joystick test script. If you want to know whether a joystick is actually connected and
you know that it has at least one axis (all 360 controller's do), query for JoyX
. If it is blank/empty, the controller is not connected.
The number of controllers shown in Control Panel is not relevant. Windows is a complicated mess of numerous components, and has many inconsistencies. One such inconsistency is that the joystick ID used by the multimedia API and the controller number used by XInput
(and lit up on the controller) do not match. This makes sense, as the multimedia API can support up to 16 joysticks with greatly varying capabilities, whereas I believe XInput supports only 4 controllers and expects them to support certain features.
in the XInput script (link above) returns 0 if the controller is not connected, or an object containing the state of the controller's buttons, axes, etc. if it is connected. It also supports other capabilities of the controller that aren't supported by GetKeyState.