Jump to content
  • Advertisement
Sign in to follow this  

[.net] read joystick buttons using windows api without DirectX

This topic is 3737 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to use joyGetPosEx to read the buttons pressed. First I use joyGetNumDevs to get the number of controls, but 81269371174928 is what is returned. Shouldn't it return the number of controllers? Also, joygetposex just returns 165, which also doesnt make sense. Could someone please tell me what I'm doing wrong?

Share this post

Link to post
Share on other sites
81269371174928 is unlikely as the joyGetNumDevs() function returns a UINT, and that number would be far outside of the range of an unsigned 32 bit integer. Of course, that's assuming you're returning an unsigned integer (if it's a long/int64 then you have the function declared incorrectly). How is your p/invoke declaration for that function set up? I have mine as:

/// <summary>
/// Function to return the number of joystick devices supported by the current driver.
/// </summary>
/// <returns>Number of joysticks supported, 0 if no driver is installed.</returns>
[DllImport("WinMM.dll"), System.Security.SuppressUnmanagedCodeSecurity]
public static extern int joyGetNumDevs();

And that works perfectly for me.

Also, you're getting error code 165 from joyGetPos? That error would be:
JOYERR_PARMS /* bad parameters */ (according to mmsystem.h)

According to MSDN, that means the ID of the joystick isn't valid.

Also make sure your joysticks showing up in the joystick control panel.

Share this post

Link to post
Share on other sites
Hi, and thanks for your response.

I tried ID's 0-15 and all of them return 165 even when the joysticks show up in the joystick control panel.

Share this post

Link to post
Share on other sites
I finally got getjoyposex to work, but it isn't returning any of the joystick information, such as the x position or the buttons pressed. So i tried my code in vb 6.0 and it works fine! Why would my code work in vb 6.0 and not in vb.net?

Public Class Form1
Public Const JOY_RETURNBUTTONS = &H80&
Public Const JOY_RETURNCENTERED = &H400&
Public Const JOY_RETURNPOV = &H40&
Public Const JOY_RETURNR = &H8&
Public Const JOY_RETURNU = &H10
Public Const JOY_RETURNV = &H20
Public Const JOY_RETURNX = &H1&
Public Const JOY_RETURNY = &H2&
Public Const JOY_RETURNZ = &H4&

Public Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As UInteger, ByRef pji As JOYINFOEX) As Integer

Public Structure JOYINFOEX
Dim dwSize As Long ' size of structure
Dim dwFlags As Long ' flags to indicate what to return
Dim dwXpos As Long ' x position
Dim dwYpos As Long ' y position
Dim dwZpos As Long ' z position
Dim dwRpos As Long ' rudder/4th axis position
Dim dwUpos As Long ' 5th axis position
Dim dwVpos As Long ' 6th axis position
Dim dwButtons As Long ' button states
Dim dwButtonNumber As Long ' current button number pressed
Dim dwPOV As Long ' point of view state
Dim dwReserved1 As Long ' reserved for communication between winmm driver
Dim dwReserved2 As Long ' reserved for future expansion
End Structure


Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

joy.dwSize = Len(joy)
joy.dwFlags = JOY_RETURNALL
joyGetPosEx(0, joy)

Label2.Text = joy.dwXpos
End Sub

End Class

Share this post

Link to post
Share on other sites
I don't know VB.NET but in C# you should declare joyGetPosEx with either "[Out]ref JOYINFOEX" or "out JOYINFOEX", otherwise it will only be marshalled from managed to unmanaged code, not the other way around.

Share this post

Link to post
Share on other sites
You don't have the [StructLayout(LayoutKind.Sequential)] attribute defined for the JOYINFOEX value type. If you don't define that attribute, the runtime will possibly rearrange your value type for a number of reasons (e.g. performance, because it's evil, etc...). Specifying sequential will tell the runtime that the fields should stay in the order in which they're declared. You can learn more about it on the MSDN.

Here's what I've got:

/// <summary>
/// Value type containing joystick position information.
/// </summary>
internal struct JOYINFOEX
/// <summary>Size of structure, in bytes.</summary>
public int Size;
/// <summary>Flags to indicate what information is valid for the device.</summary>
public JoystickInfoFlags Flags;
/// <summary>X axis.</summary>
public int X;
/// <summary>Y axis.</summary>
public int Y;
/// <summary>Z axis.</summary>
public int Z;
/// <summary>Rudder position.</summary>
public int Rudder;
/// <summary>5th axis position.</summary>
public int Axis5;
/// <summary>6th axis position.</summary>
public int Axis6;
/// <summary>State of buttons.</summary>
public JoystickButtons Buttons;
/// <summary>Currently pressed button.</summary>
public int ButtonNumber;
/// <summary>Angle of the POV hat, in degrees (0 - 35900, divide by 100 to get 0 - 359 degrees.</summary>
public int POV;
/// <summary>Reserved.</summary>
int Reserved1;
/// <summary>Reserved.</summary>
int Reserved2;

In VB.NET that attribute would be declared like this (and don't forget to import the System.Runtime.InteropServices namespace):
<StructLayout(LayoutKind.Sequential)> _
Public Structure JOYINFOEX

Also I noticed you have all your fields declared as "Long" in your VB6 version. If you haven't changed those already, know that it's not going to work in VB.NET. You need to declare those fields as Integer in VB.NET. This is because in VB6, Long was a 32 bit integer, while in VB.NET Long is a 64 bit integer.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!