Trouble setting cooperative level [SharpDX]

Jayme65

Active member
Joined
Apr 5, 2011
Messages
35
Programming Experience
Beginner
Hi,
I'm using SharpDX for DirectInput joystick management...and I can't resolve the problem I get while setting cooperative level
VB.NET:
Imports SharpDX
Imports SharpDX.DirectInput
Imports System.Windows.Interop

Class MainWindow
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        MainForJoystick()
    End Sub
    '
    Private Shared Sub MainForJoystick()
        ' Initialize DirectInput
        Dim directInput As New DirectInput

        ' Find a Joystick Guid
        Dim joystickGuid = Guid.Empty

        For Each deviceInstance As DeviceInstance In directInput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices)
            joystickGuid = deviceInstance.InstanceGuid
        Next

        ' If Gamepad not found, look for a Joystick
        If joystickGuid = Guid.Empty Then
            For Each deviceInstance As DeviceInstance In directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices)
                joystickGuid = deviceInstance.InstanceGuid
            Next
        End If

        ' If Joystick not found, throws an error
        If joystickGuid = Guid.Empty Then
            Debug.Print("No joystick/Gamepad found.")
        End If

        ' Instantiate the joystick
        Dim hwnd As IntPtr = New WindowInteropHelper(Application.Current.MainWindow).EnsureHandle()
        Dim joystick = New Joystick(directInput, joystickGuid)
        [B]joystick.SetCooperativeLevel(hwnd, CooperativeLevel.Foreground)[/B]
        Debug.Print("Found Joystick/Gamepad with GUID: {0}", joystickGuid)

        ' Set BufferSize in order to use buffered data.
        joystick.Properties.BufferSize = 128

        ' Acquire the joystick
        joystick.Acquire()

        ' Poll events from joystick
        While True
            joystick.Poll()
            Dim datas = joystick.GetBufferedData()
            For Each state As JoystickUpdate In datas
                Debug.Print(state.ToString)
                ' Example detecting 'Up' button
                If state.Offset = 60 Then
                    If state.Value = 128 Then
                        Debug.Print("Up button pressed")
                    End If
                End If
            Next
        End While
    End Sub
End Class

The problem comes from here:
joystick.SetCooperativeLevel(hwnd, CooperativeLevel.Foreground)

SharpDX.SharpDXException was unhandled
HResult=-2147024809
Message=HRESULT: [0x80070057], Module: [SharpDX.DirectInput], ApiCode: [DIERR_INVALIDPARAM/InvalidParam], Message: Incorrect parameter.

Please would you please help me understand what I'm doing wrong? I've been searching for days to resolve this!!

Many thanks!
 
Last edited:
Documentation says:

public void SetCooperativeLevel(

Control control,
CooperativeLevel level
)


Parameters

control Type: System.Windows.Forms.Control
Window control to be associated with the device. This parameter must be a valid top-level window handle that belongs to the process. The window associated with the device must not be destroyed while it is still active in a DirectInput device. level Type: SharpDX.DirectInput.CooperativeLevel
Flags that specify the cooperative level to associate with the input device.

And you are passing it a pointer. Try passing it "Me" instead. The EnsureHandle method is not really necessary if you make sure to dispose of all your SharpDX objects before closing the form. IDisposable is already implemented in the form designer, so you can do is within the Form with the HandleDestroyed event:

    Private Sub MainWindow_HandleDestroyed(sender As Object, e As EventArgs) Handles Me.HandleDestroyed
        ' During the HandleDestroyed event, the control is still a valid Windows control and the Handle can be recreated by calling the RecreateHandle method.

        ' Dispose of SharpDX objects here.
    End Sub
 
Last edited:
Herman,

Thank you very much for your reply!!

Unfortunately,
VB.NET:
Dim hwnd As IntPtr = New WindowInteropHelper(Me).EnsureHandle()
joystick.SetCooperativeLevel(hwnd, CooperativeLevel.Foreground)
gives an error with: 'Me' is valid only within an instance method.

Then I discover that 'Me' cannot be used in a shared method, I remove it..and get the same error than initially:

HRESULT: [0x80070057], Module: [SharpDX.DirectInput], ApiCode: [DIERR_INVALIDPARAM/InvalidParam], Message: Incorrect Parameter. !!
 
Last edited:
Yes I am sorry I didn't see sooner that you were working in WPF. The SharpDX library expects a Winforms handle, so you must maintain one for it. Here I remodeled your code a bit to detect multiple joysticks and poll for them in a background thread, so you can do other things at the same time. If you look at the bottom I also show how to dispose of the SharpDX objects.

VB.NET:
Imports SharpDX
Imports SharpDX.DirectInput
Imports System.Threading

Class MainWindow

    ' Initialize DirectInput
    Private directInput As New DirectInput

    ' Initialize a Windows Form handle to bind the SharpDX objects to.
    Private WithEvents frmHandle As New System.Windows.Forms.Form

    ' Initialize a dictionary to hold and name our detected joysticks.
    Private ReadOnly dictJoysticks As New Dictionary(Of String, Joystick)

    ' Initialize a polling thread for the joystick polling, so we can do other things at the same time.
    Private ReadOnly pollingThread As New Thread(AddressOf PollJoysticks) With {.IsBackground = True}


    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        InitializeJoysticks()
    End Sub


    Private Sub InitializeJoysticks()
        Dim cnt = 0

        ' Look for both joysticks and gamepads, and add each one to the dictionary with a sequential name "joy0, joy1, etc.."
        For Each di As DeviceInstance In directInput.GetDevices(DeviceType.Joystick Or DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices)
            Dim js As New Joystick(directInput, di.InstanceGuid)
            js.SetCooperativeLevel(frmHandle, CooperativeLevel.Foreground)
            ' Set BufferSize in order to use buffered data.
            js.Properties.BufferSize = 128
            js.Acquire()
            dictJoysticks.Add("joy" & cnt, js)
            Debug.Print("Found Joystick/Gamepad with GUID: {0}", di.InstanceGuid)
            cnt += 1
        Next

        Debug.Print("Initialized {0} joysticks/gamepads", dictJoysticks.Count)

        pollingThread.Start()
    End Sub


    Private Sub PollJoysticks()
        ' Poll events from joystick until the polling thread is aborted.
        While True
            Try
                For Each js In dictJoysticks
                    js.Value.Poll()
                    Dim data = js.Value.GetBufferedData
                    For Each state As JoystickUpdate In data
                        Debug.Print(String.Format("{0} : {1}", js.Key, state.ToString))
                        ' Example detecting 'Up' button
                        If state.Offset = 60 Then
                            If state.Value = 128 Then
                                Debug.Print(String.Format("{0} : {1}", js.Key, "Up button pressed"))
                            End If
                        End If
                    Next
                Next
            Catch ex As ThreadAbortException
                Exit While
            End Try
        End While
    End Sub


    Private Sub frmHandle_HandleDestroyed(sender As Object, e As EventArgs) Handles frmHandle.HandleDestroyed
        ' When the WinForm handle is destroyed, stop the polling thread and dispose of the joystick references.
        pollingThread.Abort()
        Do While pollingThread.IsAlive : Loop
        For Each js In dictJoysticks
            js.Value.Dispose()
        Next
        dictJoysticks.Clear()
    End Sub

End Class

Hmm the XCode tags are playing tricks, they keep adding <acronym> tags in the displayed code...
 
Herman,

Thank you so much for taking time to write me all this example!! Thanks, really!!

That's true that there's no error anymore...but for now I (I don't know for you) get this in the immediate window:
Initialized 0 joysticks/gamepads
 
Well I get the same but I have no joystick connected... Is your joystick properly configured and functional in the Control Panel's Joystick config applet (Start > Run > joy.cpl)?
 
Okay I just installed a dummy joystick driver, and it is being recognized as DeviceType 24, "FirstPerson".

However SetCooperativeLevel still gives the same error. However when I comment that line the rest works fine, so you might as well try that...

VB.NET:
Found Joystick/Gamepad with GUID: 56b47180-a3e2-11e4-8001-444553540000
Initialized 1 joysticks/gamepads
joy0 : Offset: PointOfViewControllers1, Value: 17999 Timestamp: 933712 Sequence: 1
 
I've 3 different gamepads here.
Two of them, which are generic joypad, are recognized in the control panel and in games..but don't work with this code.
The third one is a XBox 360 controller..and works with this code!!
Don't know why...I will have to investigate (these 2 controllers 'works' fine with the code I initially posted here!!)
EDIT: the 'problem' comes from this line:
VB.NET:
For Each di As DeviceInstance In directInput.GetDevices(DeviceType.Joystick Or DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices)
If I remove 'Or DeviceType.Gamepad' all joystick are seen.


I know you already did much..but would you have another idea concerning this CooperativeLevel!!?
 
Last edited:
Back
Top