DirectX Input Frage



  • Hi.

    Ich habe eine Vollbild Direct Draw Anwendung und nutze DirectInput für Tastatur Eingaben.

    //---------------------------------------------------------------------------
    BOOL InputManager::Init(HWND hWnd,HINSTANCE hInst)
    {    
        // DirectInput8-Objekt anlegen
        if(FAILED(DirectInput8Create(hInst, DIRECTINPUT_VERSION, 
                                     IID_IDirectInput8,(void**)&lpDI,NULL)))
        { 
           Error("Fehler beim Anlegen des DirectInput8-Objekts");
        } 
    
        // gewähltes Gerät initialisieren
        initKeyboard(hWnd);
    	initMouse(hWnd);
    
        return TRUE;
    }
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    int InputManager::getKeyboardInput(void)
    {
           // alle Tasten der Tastatur
            char buffer[256]; 
    
            if(FAILED(lpDIDeviceTastatur->GetDeviceState(sizeof(buffer),(LPVOID)&buffer))) 
            { 
                // die Tastatur wurde zwischenzeitlich 
                // durch eine andere Anwendung genutzt
                // Kontrolle wiederholen
                lpDIDeviceTastatur->Acquire();
                return 0;
            } 
    
            // bestimmen welche Taste gedrückt wurde
            // und Tastenkombination zurückgeben
            int Keys = 0;
    
    		if (buffer[DIK_Z])
    			Keys=ABC_z;
    
    // Mehr Code....
    }
    

    Mein Problem ist jetzt, das wenn ich auf der Tastatur das Z drücke ein Y erscheint und andersrum. Ja mein System ist auf "DE" ^^

    Das / DIK_SLASH muss ich auch über SHIFT+"-" aktivieren statt SHIFT+"7"

    Kann mir jemand sagen wieso dies so ist?



  • Karsten schrieb:

    Kann mir jemand sagen wieso dies so ist?

    Weil DirectInput nicht dafür gemacht wurde, um in Word einen Text in Deiner Lieblingssprache zu tippen.

    Dafür nimmst Du die schon seit Windows 3.0 (?) existenten Window-Messages (WM_KEYDOWN, WM_KEYUP, WM_CHAR) und vor den Verarbeitungsaufrufen in Deiner Schleife TranslateMessage() und dieses zweite, was ich immer vergesse. Das wandelt die Scancodes entsprechend Deinen Ländereinstellungen in ASCII-Codes um.

    Für schnelle Spiele ist das aber zu langsam. Dort möchte man gerne näher an die Tastatur dran kommen. Und für Spiele liegen meist Aktionen wie "vorwärts", "links drehen", "schiessen", "Raketenluftsack benutzen" auf den Tasten. Was die Taste wirklich bedeutet ist völlig unerheblich. Also nimmt man die Tastatur einfach als einen Riesen-Joystick ohne Achsen, Ruder, und Coolie-Hat, aber dafür mit 105 verschiedenen Tasten. Um beim Programmieren aber nicht völlig wirr rumraten zu müssen, werden diese Knöpfe nach dem amerikanischen Tastaturlayout bezeichnet. Sachen wie verschiedene Layouts werden aber natürlich NICHT berücksichtigt. Wie gesagt: Dafür wurde's nicht gemacht.



  • Das sollte mir jetzt nicht wirklich helfen, oder? 🙄

    Wenn ich SHIFT+"7" drücke, dann sollte auch das entsprechende Zeichen kommen und nicht das ich erst durch suchen bei SHIFT+"-"

    EDIT: Soweit ich nun rausbekommen habe geht es über lpDIDeviceTastatur->SetDataFormat(&c_dfDIKeyboard) allerdings habe ich noch keine Ahnung wie ich c_dfDIKeyboard setzen muss und mit was das es Deutsch wird.



  • Karsten schrieb:

    Das sollte mir jetzt nicht wirklich helfen, oder? 🙄

    Du bist anscheinend zu blöd für DirectInput. 🙄



  • Sgt. Nukem schrieb:

    Du bist anscheinend zu blöd für DirectInput. 🙄

    Hat ganz den anschein. Wenn du es besser weisst, wäre ich erfreut wenn deine Weissheit mit mir teilen würdest.



  • Karsten schrieb:

    Sgt. Nukem schrieb:

    Du bist anscheinend zu blöd für DirectInput. 🙄

    Hat ganz den anschein. Wenn du es besser weisst, wäre ich erfreut wenn deine Weissheit mit mir teilen würdest.

    Okay, da Du's nochmal probierst (und sogar (im Gegensatz zu mir ;)) ohne ausfallend zu werden), versuch' auch ich es nochmal:

    Du benutzt das falsche Werkzeug (Werkzeug = DirectInput), wenn Du über die Tastatur Texte eingeben willst.

    DirectInput ist für Spiele entwickelt worden, das die Tastatur als 105-Knopf-Joystick ohne Dauerfeuer betrachtet, nicht als Utensil um Text einzugeben.

    Das heißt im Klartext: Die Taste wo bei Dir "Z" draufsteht, ist für DirectInput einfach "Knopf Nummer 56".

    Du kannst also einfach in einem Spiel abfragen "Wenn Knopf Nummer 56 gedrückt wurde, feuer eine Rakete in Richtung Fadenkreuz".

    Du kannst aber nicht davon ausgehen, daß auf dem Knopf Nummer 56 immer "Z" steht. Bei deutschem Layout bzw. deutschen Tastaturen stimmt das zwar meistens, auf amerikanischen Tastaturen (bzw. mit amerikanischem Layout) steht auf Knopf Nummer 56 aber höchstwahrscheinlich "Y". Und auf einer französischen vielleicht "é".

    Du könntest zwar sowas einbauen:

    if(SpielWurdeInDeutschlandGestartet)
    {
        if(buttons[DIK_Z])
           MessageBox("Z wurde gedrückt!");
    }
    else
        if(buttons[DIK_Z]
           MessageBox("Y has been pressed!");
    

    Dann bau' aber bitte auch Abfrage für Frankreich, Dänemark, Ungarn, ... ein! ⚠

    Falls Du Text eingeben lassen willst, dann ist DirectInput eigentlich das falsche Werkzeug. (Es geht zwar, aber nicht sehr gut!)

    Das macht die WinAPI viel besser:

    int WindowProc(...)
    {
        if(msg == WM_CHAR)
           if(lparam == VK_Z)
               MessageBox("Z wurde gedrückt / has been pressed!");
    }
    

    Da kommt in den USA, Deutschland, Frankreich, und allen anderen Ländern auch 'Z' raus, wenn 'Z' gedrückt wurde! 💡

    In der MSDN nach "WM_CHAR", "WM_KEYDOWN", "VK_RETURN"/"VK_ENTER", "WindowProc" suchen, dann bist Du hoffentlich schlauer. 💡

    HTH



  • Achja, in der Hilfe die Du beim DirectX SDK dabeibekommen hast, steht unter "Introduction to DirectInput" folgendes:

    The Power of DirectInput
    Apart from providing services for devices not supported by the Microsoft Win32 API, DirectInput gives faster access to input data by communicating directly with the hardware drivers rather than relying on Microsoft Windows messages.

    DirectInput enables an application to retrieve data from input devices even when the application is in the background. It also provides full support for any type of input device, as well as for force feedback.

    Through action mapping, applications can retrieve input data without needing to know what kind of device is being used to generate it.

    The extended services and improved performance of DirectInput make it a valuable tool for games, simulations, and other real-time interactive applications running under Windows.

    DirectInput does not provide any advantages for applications that use the keyboard for text entry or the mouse for navigation. For more information, see Interaction with Windows.

    Und weiter:

    Interaction with Windows
    Because DirectInput works directly with the device drivers, it either suppresses or ignores Windows mouse and keyboard messages. It also ignores mouse and keyboard settings made by the user in Control Panel. It does, however, use the calibrations set for a joystick or other game controller.

    DirectInput does not recognize keyboard character repeat settings. When using buffered data, DirectInput interprets each press and release as a single event with no repetition. When using immediate data, DirectInput is concerned only with the present physical state of the keys, not with keyboard events as interpreted by Windows.

    DirectInput does not perform any character conversion or translation. For example, the SHIFT key is treated like any other key, not as a modifier of another keypress. Keys return the same identifiers regardless of the user's system language settings.

    Achja, fällt mir g'rad' ein: SHIFT hättest Du in Deinem Beispiel eigentlich nicht drücken müssen. Die "+"/"*"/"~"-Taste links neben ENTER sollte genügen. 🕶





  • Danke. Ich benutze bereits beide Varianten im Programm. Wobei aber die Eingabe von Text in Eingabefeldern über DirectInput gelöst ist und das jetzt alles umzuschreiben wegen 5 Tasten habe ich erlich gesagt keine Lust ^^.

    Ich habe aber bei meinem googlen erfahren, das man mit Hilfe von lpDIDeviceTastatur->SetDataFormat(...) es auf Deutsch einstellen können soll. Allerdings wird nirgends erklärt wie.

    Ich find erlich gesagt dämlich das einem DirectX Anfänger erst DirectInput so untergejubelt wird und sich dann als teilweise untauglich herrausstellt ^^



  • Karsten schrieb:

    Ich find erlich gesagt dämlich das einem DirectX Anfänger erst DirectInput so untergejubelt wird

    Von wem denn?!

    Vielleicht hast Du einfach die falschen Fragen gestellt?! 🤡

    Karsten schrieb:

    und sich dann als teilweise untauglich herrausstellt ^^

    Naja, Du wolltest den schneebedeckten Hügel zügig runterkommen und man hat Dir eine Bratpfanne gegeben.

    Use the right tools for the right job! 💡



  • Geht es denn, beides gleichzeitig zu benutzen? Ich bekomme keine WM_KEYDOWN / WM_CHAR - Messages, wenn ich DirectInput benutze.
    Der Kooperationsmodus ist DISCL_FOREGROUND | DISCL_EXCLUSIVE. Mit DISCL_FOREGROUND | DISCL_NONEXCLUSIVE werden zwar die Messages empfangen, aber im Fenstermodus bleibt die normale Windows - Maus außerhalb des Fensters, mit der man blöderweise leicht aus Versehen das Spiel in den Hintergrund klickt.

    Oder muss man jedes Mal, wenn der Benutzer im Hauptmenü ist (und dort eventuell Text eingibt), DirectInput runterfahren, und wenn er das Spiel spielt DirectInput wieder initialisieren?
    Und wenn während des Spiels Text eingegeben werden soll?



  • Nonexclusive ist die Lösung, deswegen musst du ja nicht gleich in den Fenstermodus gehen 😕

    MfG SideWinder



  • Hm ja. Hat sich erledigt - da ich die Input - Komponente der TriBase hergenommen hab und ich mich mit dem Thema nicht weiter beschäftigt hab, wusste ich nicht, dass man für verschiedene Geräte (Tastatur, Maus) verschiedene Kooperationsmodi hernehmen kann.

    Als ich alles auf nonexclusive gestellt hab, funktionierte die Maus nicht mehr richtig - im Fenstermodus hatte man dan teilweies 2 Mäuse (die im Spiel und die von Windows, die nicht an derselben Positions sein müssen), im Vollbildmodus erschien die Windows - Maus, wenn man in die Ecken fuhr.

    Ich denke, dass sich das Problem damit löst, dass ich die Maus auf exclusive und die Tastatur auf nonexclusive stell.
    Trotzdem danke!


Anmelden zum Antworten