RawInput freezed das Fenster



  • Hallo!

    Nach dem Aufruf von RegisterRawInputDevices() reagiert mein Fenster nicht mehr. Jedoch die Abfrage des RawInputs funktioniert dabei noch.

    RAWINPUTDEVICE Rid[2];
    
    	Rid[0].usUsagePage = 0x01; 
    	Rid[0].usUsage = 0x02; 
    	Rid[0].dwFlags = RIDEV_NOLEGACY;
    	Rid[0].hwndTarget = 0;
    
    	Rid[1].usUsagePage = 0x01; 
    	Rid[1].usUsage = 0x06; 
    	Rid[1].dwFlags = RIDEV_NOLEGACY;
    	Rid[1].hwndTarget = 0;
    
    	RegisterRawInputDevices(Rid, 2, sizeof(Rid[0]));
    
    ...
    	case WM_INPUT: 
    		{
    			UINT dwSize;
    			GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
    			LPBYTE lpb = new BYTE[dwSize];
    			GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
    			RAWINPUT* raw = (RAWINPUT*)lpb;
    
    			if(raw->data.keyboard.VKey == 27)
    			{
    				PostQuitMessage(0);
    				return 1;
    			}
    
    			delete[] lpb; 
    		} break;
    ...
    

    MfG



  • Ja, weil du dieses Verhalten mit RIDEV_NOLEGACY auch explizit anforderst 🙂
    (sobald du das Flag setzt bekommt dein Fenster *nurmehr* WM_INPUT und keine Nachrichten wie WM_MOUSEMOVE/WM_LBUTTONDOWN/... mehr die normalerweise auf Grund des Inputs erzeugt würden)

    p.S.: ersetze RIDEV_NOLEGACY in deinem Beispiel durch 0 und alles wird wieder gehen - nur falls das nicht klar genug rüberkam 🙂



  • Aha interessant, danke!

    Heißt das dann, wenn ich erst nach DirectX-Vollbildinitialisierung die Devices registriere, kann ich es so lassen?



  • Hmm, ist das nun schneller oder lahmer als DirectInput?

    class RawInput
    {
    	RawInput();
    
    	RAWINPUTDEVICE  RIDev[2];
    	RAWINPUT        RI;
    public:
    	~RawInput();
    	static RawInput& getInstance();
    
    	void Update(RAWINPUT&);
    
    	RAWINPUT& getInput();
    };
    
    ...
    	while(msg.message != WM_QUIT)
    	{
    	    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
            }
    		else
    		{
    			if(RawInput::getInstance().getInput().data.keyboard.VKey == 27)
    				PostQuitMessage(0);
    		}
        }
    ...
    
    ...
    	case WM_INPUT: 
    		{
    			UINT dwSize;
    			GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
    			LPBYTE lpb = new BYTE[dwSize];
    			GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
    			RAWINPUT* raw = (RAWINPUT*)lpb;
    
    			RawInput::getInstance().Update(*raw);
    
    			delete[] lpb; 
    		} break;
    ...
    

    MfG



  • Keine Ahnung was schneller/langsamer ist. Wenn ich raten müsste würde ich sagen raw input sollte schneller sein. Wenn du aber sowieso pollen willst, und es keinen Grund gibt nicht DirectInput zu verwenden würde ich immer DirectInput nehmen, ganz einfach weil man mehr Doku & Beispiele dazu findet, weils auch noch unter Win 2000 läuft etc.



  • Ich bekomme doch genauso einen ASCII Code.

    Pollen? Bedeutet das ungepuffertes Lesen?

    MfG



  • Heißt das dann, wenn ich erst nach DirectX-Vollbildinitialisierung die Devices registriere, kann ich es so lassen?

    Das hatte ich vorhin übersehen. Du "kannst" es auf jeden Fall so lassen, ob du es willst ist halt die Frage. Wirklich schaden sollte es nicht -- probier einfach aus ob diverse Tastenkombinationen ala control-shift-escape, control-alt-delete und alt-tab noch "funktionieren". Und ob child Fenster noch input bekommen - wäre doof wenn irgendwo ne MessageBox oder so angezeigt wird, und der User da nichtmehr reinklicken kann.

    Pollen? Bedeutet das ungepuffertes Lesen?

    Öh. "polling" nennt man es wenn man einen Wert/mehrere Werte ständig überprüft (abfragt), also z.B. wie du das "VKey" member dieser einen Struktur abfragst.

    Das Gegenteil wäre "event driven", wo z.B. "das Keyboard" dir eine Nachricht schickt (wie auch immer, über einen Queue, über nen Socket, über eine Callback-Funktion, ...) wenn z.B. eine Taste gedrückt wurde, also z.B. wie das mit der message queue funktioniert wenn einem Windows ein WM_CHAR oder sowas schickt.

    Da man beim "polling" Zeit damit verschwendet immer wieder einen Wert abzufragen, obwohl sich der in den meisten Fällen wo man ihn abfragt nicht verändert haben wird, ist polling meist langsamer als wenn man einfach auf einen Event wartet.

    Da polling in DirectInput aber sehr einach ist meinte ich halt wenn du sowieso "pollen" willst, dann kannst du gleich DirectInput verwenden. (BTW: ich weiss garnicht ob man in DirectInput irgendwie event-driven arbeiten kann -- hab das bisher immer nur mit polling verwendet).

    BTW: dein message loop ist übel, solange keine Messages kommen läuft der ständig und fragt immer bloss ob VKey gleich 27 ist -- verbrät ziemlich sinnlos Rechenzeit. Für ein Spiel wäre es ok, wenn z.B. pro Schleifendurchlauf noch 1x die "Update" Methode des Spiels aufgerufen wird, die halt quasi das nächste Frame berechnet und ausgibt. Bei einem Spiel kanns einem ja meist egal sein ob andere Prozesse noch viel Rechenzeit bekommen, und Threads die z.B. nen Sound streamen müssen bekommen dann sowieso ne höhere Priorität.



  • Ok alles klar, danke!

    MfG


Anmelden zum Antworten