-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: Joystick mit dem Borland C++ Builder abfragen

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578

    Joystick mit dem Borland C++ Builder abfragen

    Anzeige

    Hallo!
    Ich habe ein verdammt großes Problem.
    Und zwar möchte ich in meinem Programm meinen USB Joystick abfragen.
    Ich habe gehört dafür muß man die Direct-X Komponnente Direct-Input verwenden. Leider habe ich bisher noch nicht mit Direct-X gearbeitet.
    Es liegt zwar ein Beispiel in C++ bei, dieses kann ich aber wegen Fehlern nicht selber korrigieren. Auch durch den Quelltext sehe ich durch, alles ist
    schwer lesbar und verschachtelt.
    Kann mir eventuell jemand einen Beispielcode senden?
    Das compilierte Testprogramm funktioniert übrigens gut und erfüllt seine Aufgabe wie gewünscht.

    Ich habe die Quelltextdatei des Beispiels, dass ich nicht durchschaue mal angehangen.


    MfG ACU


    Code:
    //-----------------------------------------------------------------------------
    // File: Joystick.cpp
    //
    // Desc: Demonstrates an application which receives immediate 
    //       joystick data in exclusive mode via a dialog timer.
    //
    // Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
    //-----------------------------------------------------------------------------
    #define STRICT
    #define DIRECTINPUT_VERSION 0x0800
    
    #include <windows.h>
    #include <commctrl.h>
    #include <basetsd.h>
    #include <dinput.h>
    #include "resource.h"
    
    
    
    
    //-----------------------------------------------------------------------------
    // Function-prototypes
    //-----------------------------------------------------------------------------
    INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
    BOOL CALLBACK    EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
    BOOL CALLBACK    EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );
    HRESULT InitDirectInput( HWND hDlg );
    VOID    FreeDirectInput();
    HRESULT UpdateInputState( HWND hDlg );
    
    
    
    
    //-----------------------------------------------------------------------------
    // Defines, constants, and global variables
    //-----------------------------------------------------------------------------
    #define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
    #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
    
    LPDIRECTINPUT8       g_pDI              = NULL;         
    LPDIRECTINPUTDEVICE8 g_pJoystick        = NULL;     
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: WinMain()
    // Desc: Entry point for the application.  Since we use a simple dialog for 
    //       user interaction we don't need to pump messages.
    //-----------------------------------------------------------------------------
    int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
    {
        InitCommonControls();
    
        // Display the main dialog box.
        DialogBox( hInst, MAKEINTRESOURCE(IDD_JOYST_IMM), NULL, MainDlgProc );
        
        return TRUE;
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: MainDialogProc
    // Desc: Handles dialog messages
    //-----------------------------------------------------------------------------
    INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
    {
        switch( msg ) 
        {
            case WM_INITDIALOG:
                if( FAILED( InitDirectInput( hDlg ) ) )
                {
                    MessageBox( NULL, TEXT("Error Initializing DirectInput"), 
                                TEXT("DirectInput Sample"), MB_ICONERROR | MB_OK );
                    EndDialog( hDlg, 0 );
                }
    
                // Set a timer to go off 30 times a second. At every timer message
                // the input device will be read
                SetTimer( hDlg, 0, 1000 / 30, NULL );
                return TRUE;
    
            case WM_ACTIVATE:
                if( WA_INACTIVE != wParam && g_pJoystick )
                {
                    // Make sure the device is acquired, if we are gaining focus.
                    g_pJoystick->Acquire();
                }
                return TRUE;
    
            case WM_TIMER:
                // Update the input device every timer message
                if( FAILED( UpdateInputState( hDlg ) ) )
                {
                    KillTimer( hDlg, 0 );    
                    MessageBox( NULL, TEXT("Error Reading Input State. ") \
                                TEXT("The sample will now exit."), TEXT("DirectInput Sample"), 
                                MB_ICONERROR | MB_OK );
                    EndDialog( hDlg, TRUE ); 
                }
                return TRUE;
    
            case WM_COMMAND:
                switch( LOWORD(wParam) )
                {
                    case IDCANCEL:
                        EndDialog( hDlg, 0 );
                        return TRUE;
                }
    
            case WM_DESTROY:
                // Cleanup everything
                KillTimer( hDlg, 0 );    
                FreeDirectInput();    
                return TRUE;    
        }
    
        return FALSE; // Message not handled 
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: InitDirectInput()
    // Desc: Initialize the DirectInput variables.
    //-----------------------------------------------------------------------------
    HRESULT InitDirectInput( HWND hDlg )
    {
        HRESULT hr;
    
        // Register with the DirectInput subsystem and get a pointer
        // to a IDirectInput interface we can use.
        // Create a DInput object
        if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                             IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
            return hr;
    
        // Look for a simple joystick we can use for this sample program.
        if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, 
                                             EnumJoysticksCallback,
                                             NULL, DIEDFL_ATTACHEDONLY ) ) )
            return hr;
    
        // Make sure we got a joystick
        if( NULL == g_pJoystick )
        {
            MessageBox( NULL, TEXT("Joystick not found. The sample will now exit."),  
                        TEXT("DirectInput Sample"), 
                        MB_ICONERROR | MB_OK );
            EndDialog( hDlg, 0 );
            return S_OK;
        }
    
        // Set the data format to "simple joystick" - a predefined data format 
        //
        // A data format specifies which controls on a device we are interested in,
        // and how they should be reported. This tells DInput that we will be
        // passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
        if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) )
            return hr;
    
        // Set the cooperative level to let DInput know how this device should
        // interact with the system and with other DInput applications.
        if( FAILED( hr = g_pJoystick->SetCooperativeLevel( hDlg, DISCL_EXCLUSIVE | 
                                                                 DISCL_FOREGROUND ) ) )
            return hr;
    
        // Enumerate the joystick objects. The callback function enabled user
        // interface elements for objects that are found, and sets the min/max
        // values property for discovered axes.
        if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback, 
                                                    (VOID*)hDlg, DIDFT_ALL ) ) )
            return hr;
    
        return S_OK;
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: EnumJoysticksCallback()
    // Desc: Called once for each enumerated joystick. If we find one, create a
    //       device interface on it so we can play with it.
    //-----------------------------------------------------------------------------
    BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
                                         VOID* pContext )
    {
        HRESULT hr;
    
        // Obtain an interface to the enumerated joystick.
        hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
    
        // If it failed, then we can't use this joystick. (Maybe the user unplugged
        // it while we were in the middle of enumerating it.)
        if( FAILED(hr) ) 
            return DIENUM_CONTINUE;
    
        // Stop enumeration. Note: we're just taking the first joystick we get. You
        // could store all the enumerated joysticks and let the user pick.
        return DIENUM_STOP;
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: EnumObjectsCallback()
    // Desc: Callback function for enumerating objects (axes, buttons, POVs) on a 
    //       joystick. This function enables user interface elements for objects
    //       that are found to exist, and scales axes min/max values.
    //-----------------------------------------------------------------------------
    BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                       VOID* pContext )
    {
        HWND hDlg = (HWND)pContext;
    
        static int nSliderCount = 0;  // Number of returned slider controls
        static int nPOVCount = 0;     // Number of returned POV controls
    
        // For axes that are returned, set the DIPROP_RANGE property for the
        // enumerated axis in order to scale min/max values.
        if( pdidoi->dwType & DIDFT_AXIS )
        {
            DIPROPRANGE diprg; 
            diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
            diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
            diprg.diph.dwHow        = DIPH_BYID; 
            diprg.diph.dwObj        = pdidoi->dwType; // Specify the enumerated axis
            diprg.lMin              = -1000; 
            diprg.lMax              = +1000; 
        
            // Set the range for the axis
            if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) 
                return DIENUM_STOP;
             
        }
    
    
        // Set the UI to reflect what objects the joystick supports
        if (pdidoi->guidType == GUID_XAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_X_AXIS ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_X_AXIS_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_YAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_Y_AXIS ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_Y_AXIS_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_ZAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_Z_AXIS ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_Z_AXIS_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_RxAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_X_ROT ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_X_ROT_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_RyAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_Y_ROT ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_Y_ROT_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_RzAxis)
        {
            EnableWindow( GetDlgItem( hDlg, IDC_Z_ROT ), TRUE );
            EnableWindow( GetDlgItem( hDlg, IDC_Z_ROT_TEXT ), TRUE );
        }
        if (pdidoi->guidType == GUID_Slider)
        {
            switch( nSliderCount++ )
            {
                case 0 :
                    EnableWindow( GetDlgItem( hDlg, IDC_SLIDER0 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_SLIDER0_TEXT ), TRUE );
                    break;
    
                case 1 :
                    EnableWindow( GetDlgItem( hDlg, IDC_SLIDER1 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_SLIDER1_TEXT ), TRUE );
                    break;
            }
        }
        if (pdidoi->guidType == GUID_POV)
        {
            switch( nPOVCount++ )
            {
                case 0 :
                    EnableWindow( GetDlgItem( hDlg, IDC_POV0 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_POV0_TEXT ), TRUE );
                    break;
    
                case 1 :
                    EnableWindow( GetDlgItem( hDlg, IDC_POV1 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_POV1_TEXT ), TRUE );
                    break;
    
                case 2 :
                    EnableWindow( GetDlgItem( hDlg, IDC_POV2 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_POV2_TEXT ), TRUE );
                    break;
    
                case 3 :
                    EnableWindow( GetDlgItem( hDlg, IDC_POV3 ), TRUE );
                    EnableWindow( GetDlgItem( hDlg, IDC_POV3_TEXT ), TRUE );
                    break;
            }
        }
    
        return DIENUM_CONTINUE;
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: UpdateInputState()
    // Desc: Get the input device's state and display it.
    //-----------------------------------------------------------------------------
    HRESULT UpdateInputState( HWND hDlg )
    {
        HRESULT     hr;
        TCHAR       strText[512]; // Device state text
        DIJOYSTATE2 js;           // DInput joystick state 
        TCHAR*      str;
    
        if( NULL == g_pJoystick ) 
            return S_OK;
    
        // Poll the device to read the current state
        hr = g_pJoystick->Poll(); 
        if( FAILED(hr) )  
        {
            // DInput is telling us that the input stream has been
            // interrupted. We aren't tracking any state between polls, so
            // we don't have any special reset that needs to be done. We
            // just re-acquire and try again.
            hr = g_pJoystick->Acquire();
            while( hr == DIERR_INPUTLOST ) 
                hr = g_pJoystick->Acquire();
    
            // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
            // may occur when the app is minimized or in the process of 
            // switching, so just try again later 
            return S_OK; 
        }
    
        // Get the input's device state
        if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) )
            return hr; // The device should have been acquired during the Poll()
    
        // Display joystick state to dialog
    
        // Axes
        wsprintf( strText, TEXT("%ld"), js.lX ); 
        SetWindowText( GetDlgItem( hDlg, IDC_X_AXIS ), strText );
        wsprintf( strText, TEXT("%ld"), js.lY ); 
        SetWindowText( GetDlgItem( hDlg, IDC_Y_AXIS ), strText );
        wsprintf( strText, TEXT("%ld"), js.lZ ); 
        SetWindowText( GetDlgItem( hDlg, IDC_Z_AXIS ), strText );
        wsprintf( strText, TEXT("%ld"), js.lRx ); 
        SetWindowText( GetDlgItem( hDlg, IDC_X_ROT ), strText );
        wsprintf( strText, TEXT("%ld"), js.lRy ); 
        SetWindowText( GetDlgItem( hDlg, IDC_Y_ROT ), strText );
        wsprintf( strText, TEXT("%ld"), js.lRz ); 
        SetWindowText( GetDlgItem( hDlg, IDC_Z_ROT ), strText );
    
        // Slider controls
        wsprintf( strText, TEXT("%ld"), js.rglSlider[0] ); 
        SetWindowText( GetDlgItem( hDlg, IDC_SLIDER0 ), strText );
        wsprintf( strText, TEXT("%ld"), js.rglSlider[1] ); 
        SetWindowText( GetDlgItem( hDlg, IDC_SLIDER1 ), strText );
    
        // Points of view
        wsprintf( strText, TEXT("%ld"), js.rgdwPOV[0] );
        SetWindowText( GetDlgItem( hDlg, IDC_POV0 ), strText );
        wsprintf( strText, TEXT("%ld"), js.rgdwPOV[1] );
        SetWindowText( GetDlgItem( hDlg, IDC_POV1 ), strText );
        wsprintf( strText, TEXT("%ld"), js.rgdwPOV[2] );
        SetWindowText( GetDlgItem( hDlg, IDC_POV2 ), strText );
        wsprintf( strText, TEXT("%ld"), js.rgdwPOV[3] );
        SetWindowText( GetDlgItem( hDlg, IDC_POV3 ), strText );
     
       
        // Fill up text with which buttons are pressed
        str = strText;
        for( int i = 0; i < 128; i++ )
        {
            if ( js.rgbButtons[i] & 0x80 )
                str += wsprintf( str, TEXT("%02d "), i );
        }
        *str = 0;   // Terminate the string 
    
        SetWindowText( GetDlgItem( hDlg, IDC_BUTTONS ), strText );
    
        return S_OK;
    }
    
    
    
    
    //-----------------------------------------------------------------------------
    // Name: FreeDirectInput()
    // Desc: Initialize the DirectInput variables.
    //-----------------------------------------------------------------------------
    VOID FreeDirectInput()
    {
        // Unacquire the device one last time just in case 
        // the app tried to exit while the device is still acquired.
        if( g_pJoystick ) 
            g_pJoystick->Unacquire();
        
        // Release any DirectInput objects.
        SAFE_RELEASE( g_pJoystick );
        SAFE_RELEASE( g_pDI );
    }
    http://www.roboterbastler.de
    endlich wieder online

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578
    Ich habe vorhin einen Tipp bekommen auf die Seite
    http://code.dreamincode.net/snippet434.htm zu schauen.
    Die Header Datei von dort sieht recht vielversprechend aus, leider werden 3 Fehler angezeigt, sobald ich sie einbinde.
    Die dinput.lib ist drin.

    [C++ Fehler] Joyplug.h(41): E2268 Aufruf der undefinierten Funktion 'DirectInputCreate'
    [C++ Fehler] Joyplug.h(43): E2268 Aufruf der undefinierten Funktion 'write_debug'
    [C++ Fehler] Joyplug.h(45): E2451 Undefiniertes Symbol 'DIDEVTYPE_JOYSTICK'
    http://www.roboterbastler.de
    endlich wieder online

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.11.2004
    Ort
    München
    Alter
    30
    Beiträge
    447
    Hallo,
    Wenn du das nicht unbedingt mit direct input machen willst kannst du die funktion joyGetPos (und was dazu gehört) benutzen.
    Das erfüllt meist den gleichen Zweck und ist wesentlich einfacher.

    MfG Alex

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578
    Hallo!
    Das klingt ja interessant.
    Kann ich da auch abfragen, ob bzw. welche Taste gedrückt wurde?
    Wäre ja eine Klasse sache, wenn das so einfach ginge.


    MfG ACU
    http://www.roboterbastler.de
    endlich wieder online

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.11.2004
    Ort
    München
    Alter
    30
    Beiträge
    447
    Hallo,
    Natürlich geht das, schau am Besten mal in der msdn nach der Dokumentation der Funktionen.
    Da steht alles genau beschrieben.

    MfG Alex

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578
    Ich habe mal was rausgesucht, falls jemand anderes sich auch dafür interessiert.
    http://msdn.microsoft.com/library/de..._reference.asp
    Hier müsste man alles finden.
    Da bin ich wahrscheinlich um Direct-X drum rumgekommen aber ich befürchte irgendwann holts mich ein .


    MfG ACU
    http://www.roboterbastler.de
    endlich wieder online

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578
    Ich bins nochmal!
    Ich habe eben ein bischen mit den Funktionen rumprobiert.
    Leider noch mit nur mäßigem Erfolg.

    Ich habe aus dem MSDN diese Testfunktion:
    Code:
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     Label8->Caption=IntToStr(JoysticksConnected());
     Label10->Caption=IntToStr(njoyId);
    
    
    }
    
       int JoysticksConnected( )
       {  njoyId=0;
       // determine number of joysticks installed in Windows 95
    
          JOYINFOEX info;      // extended information
    
               // first joystick
    
          int nConnected = 0;  // goal - number of joysticks connected
    
          MMRESULT dwResult;   // examine return values
    
       // Loop through all possible joystick IDs until we get the error
       // JOYERR_PARMS. Count the number of times we get JOYERR_NOERROR
       // indicating an installed joystick driver with a joystick currently
       // attached to the port.
    
          while ((dwResult = joyGetPosEx(njoyId++,&info)) != JOYERR_PARMS)
    
          if (dwResult == JOYERR_NOERROR)
             ++nConnected;    // the count of connected joysticks
    
          return nConnected;  // return the count of joysticks found
    
       } // JoysticksConnected
    Sie gibt aus, wieviele Joysticks sich im System befinden.
    Außerdem kann man die Adresse, an der was gefunden wurde ja auslesen.
    Es wurde angezeigt, dass ich einen Joystick habe (auch richtig) und dieser sich an der Adresse 2 befindet.

    Soweit so gut, jetzt habe ich versucht die Koordinaten auszulesen.
    Mit diesem Code:
    JOYINFOEX *Zwei;
    joyGetPosEx(2,Zwei);
    Label6->Caption=IntToStr(&Zwei->dwPOV);
    Leider wird egal, was ich abfrage nur eine 1 zurückgeliefert.

    Wo liegt mein Fehler?


    Mfg ACU
    http://www.roboterbastler.de
    endlich wieder online

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    24.11.2003
    Ort
    Leipzig
    Alter
    31
    Beiträge
    578
    So die Probleme sind gelöst, jetzt geht alles.
    Da ich doch Recht heftige Probleme habe, werde ich auf meiner Seite mal ein kleines Tutorial veröffentlichen.


    MfG ACU
    http://www.roboterbastler.de
    endlich wieder online

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.11.2004
    Ort
    München
    Alter
    30
    Beiträge
    447
    Hi,
    Wollte grad sagen, dass du da mit den pointern mist machst , aber wenns jetzt geht wirst du das schon bemerkt haben.

    MfG Alex

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    05.01.2008
    Ort
    Erlangen
    Alter
    25
    Beiträge
    58
    ähm könntest du das fertig funktionierende programm viell mal für normal sterbliche reinstellen, ACU ???


    thx schonma mfg

    Theux

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •