Zeichen und Tastennachrichten darstellen



  • also das mit dem iType hab ich jetzt auch verstanden.

    und das mit den Bits auch.
    hab auch ein wenig gegoogelt und dabei einige infos zu bytes und bits gefunden.

    jetzt probier ich herum, was in szBuffer alles gespeichert wird.
    hab auch schon viel rausgefunden und verstanden.

    nur folgende Zeile bereitet mir noch Probleme:

    szMessage[pmsg[i].message - WM_KEYFIRST]

    außerdem leuchtet mir nicht ganz ein wie man auf die zahlen kommt:
    HIWORD (pmsg[i].lParam) & 0xFF,
    0x01000000 & pmsg[i].lParam ? szYes : szNo,
    0x20000000 & pmsg[i].lParam ? szYes : szNo,
    0x40000000 & pmsg[i].lParam ? szDown : szUp,
    0x80000000 & pmsg[i].lParam ? szUp : szDown));



  • Hier mal ein Auszug aus der WinUser.h - vielleicht hilft er dir ein wenig für das Verständnis:

    #define WM_KEYFIRST                     0x0100
    #define WM_KEYDOWN                      0x0100
    #define WM_KEYUP                        0x0101
    #define WM_CHAR                         0x0102
    #define WM_DEADCHAR                     0x0103
    #define WM_SYSKEYDOWN                   0x0104
    #define WM_SYSKEYUP                     0x0105
    #define WM_SYSCHAR                      0x0106
    #define WM_SYSDEADCHAR                  0x0107
    

    Wie du sehen kannst sind die Konstanten fortlaufend durchnummeriert. Wenn man nun von pmsg[i].message WM_KEYFIRST abzieht erhält man also für diese Messages einen Wert zwischen 0 (WM_KEYDOWN) und 7 (WM_SYSDEADCHAR), welcher dann als Index für das String-Array szMessage verwendet wird, in dem zu genau diese Konstanten jeweils ihre Textform als String hinterlegt ist.

    Zu den Zahlen: z.B. hier kannst du sehen, in welchen Bits welche Information abgelegt ist. Diese Zahlen sind nur die entsprechende Hexadezimal-Darstellungen davon...
    Eine Ziffer fasst dabei immer 4 Bits zusammen:

    0000 => 0
    0001 => 1
    0010 => 2
    0100 => 4
    1000 => 8

    0xFF => 1111 1111 (filtert also die unteren 8 Bits heraus)



  • aha.
    interessant.

    vielend danke flenders, jetzt hab ich alles gut verstanden 👍 👍

    mfg
    roozy



  • da ich nicht ein neues thema aufmachen wollte frag ich jetzt hier.

    also:

    static PMSG pmsg;
    	static TCHAR *szText="Tastendruck darstellen";
    	static TCHAR szBuffer[128];
    	static TCHAR szKeyName[32];
    
    	switch(message)
    	{
    	case WM_CREATE:
    		return 0;
    	case WM_KEYDOWN:
    		hdc=GetDC(hwnd);
                      pmsg.lParam=lParam;
    		GetKeyNameText(pmsg->lParam, szKeyName, sizeof(szKeyName) /sizeof (TCHAR));
    		TextOut(hdc, 20,20, szBuffer,wsprintf(szBuffer, "%s", szKeyName));
    
    		ReleaseDC(hwnd,hdc);
    		return 0;
    	case WM_PAINT:
    		hdc=BeginPaint(hwnd, &ps);
    		TextOut (hdc, 0, 0, szText, lstrlen(szText));
    
    		EndPaint(hwnd, &ps);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return DefWindowProc(hwnd, message, wParam, lParam);
    
    }
    

    wenn ich das Programm laufen lass wird es immer mit einem Fehler unterbrochen, sobald ich eine Taste drücke...
    wieso, und was muss ich anders machen?
    (ich möchte die eingegebene Taste dastellen...

    1. wieso muss ich hier über "->" zugreifen
      im obigen quelltext muss ich das doch auch net?


  • Das liegt daran, dass deine Zeigervariable pmsg
    Siehe hier:

    // Definition:
    static PMSG pmsg;
    // Verwendung in deinem WM_KEYDOWN-Handler:
    pmsg.lParam=lParam;
    

    vorher nicht mit einem gültigen Speicherbereich initialisiert wurde.
    Du kannst entweder mit new/malloc Speicher allokieren, oder du verzichtest
    hier vollständig auf den Zeiger (meines Erachtens die bessere Wahl 😉 ).



  • aha.

    und wie weiß ich ihr zuerst einen gültigen Speicherbereich zu?



  • pmsg = new MSG;
    

    oder eben gar keinen Pointer sondern so:

    MSG msg;
    

    Wenn du einen Pointer hast greifst du mit -> auf die Member zu, wenn du direkt eine Instanz / Struktur / etc. hast, dann nimmst du dazu .

    Wobei ich bei deinem Beispielcode nicht so ganz verstehe, wozu du das mit der MSG-Struktur überhaupt machst und nicht gleich so:

    GetKeyNameText(lParam, szKeyName, sizeof(szKeyName) /sizeof (TCHAR));
    

    Zeichnen sollte man außerdem normalerweise nur in WM_PAINT...



  • ich machs mit dem pointer, damit ich das ein bisschen üben kann,
    wie du siehst bin ich da noch ziemlich unsicher...

    wenn ich das mit new mach kommen folgende 4 Fehler/Warnungen:

    C:\Programme\Microsoft Visual Studio\MyProjects\WinApi\Keylogger_v1\Keylogger_v1.c(56) : error C2065: 'new' : nichtdeklarierter Bezeichner
    C:\Programme\Microsoft Visual Studio\MyProjects\WinApi\Keylogger_v1\Keylogger_v1.c(56) : warning C4047: '=' : Anzahl der Dereferenzierungen bei 'struct tagMSG *' und 'int ' unterschiedlich
    C:\Programme\Microsoft Visual Studio\MyProjects\WinApi\Keylogger_v1\Keylogger_v1.c(56) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'MSG'
    C:\Programme\Microsoft Visual Studio\MyProjects\WinApi\Keylogger_v1\Keylogger_v1.c(56) : error C2275: "MSG" : Ungültige Verwendung dieses Typs als  Ausdruck
            c:\programme\microsoft visual studio\vc98\include\winuser.h(1236) : Siehe Deklaration von 'MSG'
    

    ich machs so:

    static PMSG pmsg;
    //anderer Quelltext
    pmsg= new MSG;
    pmsg->lParam=lParam;
    //ausgabe:
    GetKeyNameText(pmsg->lParam, szKeyName, sizeof(szKeyName) /sizeof (TCHAR));
    TextOut(hdc, 20,20, szBuffer,wsprintf(szBuffer, "%s", szKeyName));
    


  • flenders schrieb:

    Wenn du einen Pointer hast greifst du mit -> auf die Member zu, wenn du direkt eine Instanz / Struktur / etc. hast, dann nimmst du dazu .

    Ergänzend: Das wär auch noch möglich:

    PMSG pMsg = new MSG;
    (*pMsg).lParam = ...;
    // oder wie flenders schon gesagt hat, mit dem Pfeiloperator:
    pMsg->lParam = ...;
    

    Aber der Pfeiloperator bietet sich natürlich mehr als an :p .

    PS: Was hast du für einen Compiler ?



  • ich hab Microsoft Visual C++

    wieso?



  • roozy schrieb:

    ich hab Microsoft Visual C++

    Hm weil ich mich Frage, warum er 'new' nicht kennt...
    Welche Version ?



  • 6.0



  • Oh, jo ist klar....Fällt mir jetzt erst auf:
    Du musst, wenn du C++ verwendest, als Dateiendung '*.cpp' angeben. Oder du benutzt malloc ( ➡ memory allocation). Das wäre C, ist aber natürlich 'etwas veraltet' 😉 .



  • ich tippe, du hast eine Datei .c und nicht .cpp und da new eben C++ ist musst du dem Compiler auch sagen, dass du das als C++ kompilieren willst (oder du verwendest eben malloc) 🙄

    edit: zu langsmam...



  • 4 Sekunden 😃 ...



  • mit malloc(sizeof(MSG)); hats super hingehauen.

    danke nochmal an alle die mir geholfen haben

    mfg


Anmelden zum Antworten