Results 1 to 9 of 9

Thread: Trouble setting cooperative level [SharpDX]

  1. #1
    Jayme65 is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2011
    Posts
    35
    Reputation
    75

    Trouble setting cooperative level [SharpDX]

    Hi,
    I'm using SharpDX for DirectInput joystick management...and I can't resolve the problem I get while setting cooperative level
    Code:
    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)
            joystick.SetCooperativeLevel(hwnd, CooperativeLevel.Foreground)
            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 by Jayme65; 01-23-2015 at 12:16 PM.

  2. #2
    Herman is offline VB.NET Forum Idol
    .NET Framework
    .NET 4.0
    Join Date
    Oct 2011
    Location
    Montreal, QC, CA
    Posts
    866
    Reputation
    1212
    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 by Herman; 01-24-2015 at 1:48 PM.

  3. #3
    Jayme65 is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2011
    Posts
    35
    Reputation
    75
    Herman,

    Thank you very much for your reply!!

    Unfortunately,
    Code:
    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 by Jayme65; 01-24-2015 at 2:38 PM.

  4. #4
    Herman is offline VB.NET Forum Idol
    .NET Framework
    .NET 4.0
    Join Date
    Oct 2011
    Location
    Montreal, QC, CA
    Posts
    866
    Reputation
    1212
    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.

    Code:
    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...

  5. #5
    Jayme65 is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2011
    Posts
    35
    Reputation
    75
    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

  6. #6
    Herman is offline VB.NET Forum Idol
    .NET Framework
    .NET 4.0
    Join Date
    Oct 2011
    Location
    Montreal, QC, CA
    Posts
    866
    Reputation
    1212
    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)?

  7. #7
    Jayme65 is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2011
    Posts
    35
    Reputation
    75
    Yes Herman, the joystick is recognized and properly configured! (I've double checked this)

  8. #8
    Herman is offline VB.NET Forum Idol
    .NET Framework
    .NET 4.0
    Join Date
    Oct 2011
    Location
    Montreal, QC, CA
    Posts
    866
    Reputation
    1212
    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...

    Code:
    Found Joystick/Gamepad with GUID: 56b47180-a3e2-11e4-8001-444553540000
    Initialized 1 joysticks/gamepads
    joy0 : Offset: PointOfViewControllers1, Value: 17999 Timestamp: 933712 Sequence: 1

  9. #9
    Jayme65 is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2011
    Posts
    35
    Reputation
    75
    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:
    Code:
    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 by Jayme65; 01-24-2015 at 5:18 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •