Eingabe ohne Konsole



  • SammyRukka schrieb:

    Danke!

    Bitte schön. Schon gewusst ? Man kann auch in einem Windowsprogramm eine Konsole starten.
    MfG



  • Winconsole schrieb:

    Schon gewusst ? Man kann auch in einem Windowsprogramm eine Konsole starten.

    Ja, das wußte sogar ich schon. Habe das anfangs zum Debuggen benutzt. Ist aber nichts für die Endversion meines Programms.
    Jetzt bin ich aber damit noch nicht ganz durch:
    Ich habe mir die beiden Threads zum Thema angesehen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39383.html
    http://www.c-plusplus.net/forum/viewtopic-var-p-is-89220.html(Vorgeschichte dazu)

    Jetzt meine Fragen:

    • Wie kommt man auf '1073741824' und was bedeutet
    (lParam & 1073741824) != 1073741824
    

    und woher kommt 1073741824? (das != habe ich verstanden 🙂 )

    • Wo kommt das 'SendMessage' denn eigentlich an? In einer bei mir nicht vorhandenen Message-Queue? Mein Programm hat ja nicht mal ein Fenster.
    • Kann man das Ganze nur als DLL benutzen? Ich wollte die Funktionen 'SetWindowsHookEx' und 'KeyboardProc' so benutzen, habe das aber nicht hinbekommen (z.B. wg. der vorherigen Frage).
    • Ist es nicht möglich, einfache Tastatureingabe ohne Konsole oder Hooks zu bekommen. Dann würde ich mich auch nicht so wie ein Hacker fühlen.... nur gut, dass ich mich auf Windows beschränke und nicht auch noch Linux hacken muss 😕 😉 .


  • 1073741824 == 0x40000000 - das ist ein int-Wert, bei dem NUR Bit 30 gesetzt ist (das Bit kennzeichnet laut MSDN, ob die Taste gedrückt oder losgelassen wurde).

    PS: Wenn du keine Konsole und keine MessageQueue hast, wie lässt sich dein Programm dann steuern?



  • 1073741824 ist 2^30, also in binärdarstellung eine 1, gefolgt von 30 nullen. wenn man das binär mit einer anderen zahl mittels logischem und verbindet, blendet man alle ziffern bis auf das 31. bit aus. soll bedeuten, (lParam & 1073741824) != 1073741824 ist genau dann true, wenn bei lParam das 31. bit nicht gesetzt ist.
    warum das allerdings geprüft wird, keine ahnung ^^



  • thordk schrieb:

    warum das allerdings geprüft wird, keine ahnung ^^

    Weil die Hook-Funktion dort einen Statuswert übergeben bekommt, der von Interesse ist 😉

    MSDN - KeyBoardProc schrieb:

    Value  Description 
    0–15   Specifies the repeat count. The value is the number of times the
           keystroke is repeated as a result of the user's holding down the key. 
    16–23  Specifies the scan code. The value depends on the original equipment
           manufacturer (OEM).
    24     Specifies whether the key is an extended key, such as a function key or
           a key on the numeric keypad. The value is 1 if the key is an extended
           key; otherwise, it is 0. 
    25–28  Reserved. 
    29     Specifies the context code. The value is 1 if the alt key is down;
           otherwise, it is 0. 
    [b]30[/b]     Specifies the previous key state. The value is 1 if the key is down
           before the message is sent; it is 0 if the key is up.
    31     Specifies the transition state. The value is 0 if the key is being
           pressed and 1 if it is being released.
    


  • CStoll schrieb:

    PS: Wenn du keine Konsole und keine MessageQueue hast, wie lässt sich dein Programm dann steuern?

    Der Lauser schreibt ein Keyboard-Hook, die Steuerung kann an dann in die Hookfunktion(KeyboardHookProc) eingebaut werden. 😃





  • Danke für die Erklärungen. 2^30 habe ich auch entdeckt, habe aber immer an Gigabytes denken müssen....

    CStoll schrieb:

    PS: Wenn du keine Konsole und keine MessageQueue hast, wie lässt sich dein Programm dann steuern?

    Logitech G15 - Tastatur mit Display und paar Buttons. Die Buttons reichen normal, ich wollt aber einen String eingeben. Meine Main-Loop prüft nur auf gedrückte LCD-Buttons.

    • Wo kommt das 'SendMessage' denn eigentlich an? In einer bei mir nicht vorhandenen Message-Queue? Mein Programm hat ja nicht mal ein Fenster.
    • Kann man das Ganze nur als DLL benutzen? Ich wollte die Funktionen 'SetWindowsHookEx' und 'KeyboardProc' so benutzen, habe das aber nicht hinbekommen (z.B. wg. der vorherigen Frage).
    • Ist es nicht möglich, einfache Tastatureingabe ohne Konsole oder Hooks zu bekommen. Dann würde ich mich auch nicht so wie ein Hacker fühlen.... nur gut, dass ich mich auf Windows beschränke und nicht auch noch Linux hacken muss 😕 😉 .

    Einfacher geht's also nicht?! Und wenn kompliziert, dann richtig und nur als ddl?



  • Kann mir denn jetzt noch jemand sagen, wie die Nachrichten des Hooks (SendMessage) bei mir jetzt ankommen? Wie bekomme ich die Info denn an meine Klasse, die gerade in einer Loop läuft?
    Ausserdem habeich im Moment auch keine Ahnung, wie ich den Code bei mir einbinde. Wie compiliere ich den denn? Einfach mit oder extra als dll, die ich dann importiere oder wie ist das gemeint?

    Wär mir aber sowieso lieber, das würde einfacher gehen und nicht auf so dunklen Pfaden :). Kann man nicht auch den Standareingabe-Stream anlegen/umswitchen?



  • SammyRukka schrieb:

    Aber Konsole schreibt man doch mit 'K'!

    Im Deutschen schon...



  • SammyRukka schrieb:

    Kann mir denn jetzt noch jemand sagen, wie die Nachrichten des Hooks (SendMessage) bei mir jetzt ankommen? Wie bekomme ich die Info denn an meine Klasse, die gerade in einer Loop läuft?

    Wenn du keine Message-Queue hast, brauchst du die Information auch nicht per SendMessage() weiterschicken. Stattdessen kannst du direkt in der Behandlungsfunktion das machen, was du für nötig hältst.

    Ausserdem habeich im Moment auch keine Ahnung, wie ich den Code bei mir einbinde. Wie compiliere ich den denn? Einfach mit oder extra als dll, die ich dann importiere oder wie ist das gemeint?

    Als Extra-DLL brauchst du das nur, wenn du alle Tastatureingaben im System abfangen willst.

    *grübelt* C++ ist es egal, was am anderen Ende von cin/cout steckt. Vermutlich kannst du ja auch direkt auf den Tastaturtreiber zugreifen, um die Tastendrücke in cout einzuschleusen.

    PS: Und ganz klar ist mir der Aufbau deines Systems noch nicht 😉



  • Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • CStoll schrieb:

    ....
    PS: Und ganz klar ist mir der Aufbau deines Systems noch nicht 😉

    Wenn ich ehrlich bin, dann ist mir jetzt immernoch nicht klar, was ich machen kann. Aber damit wenigstens einer von uns klar sieht ;):
    Ich habe eine G15 von Logitech, das ist eine Tastatur mit einem kleinen Display mit 4 Knöpfen. Den Treibern lieht auch ein SDK bei, mit einigen API-Klassen für die Ansteuerung des LCD.
    Um die Buttons 'abzufangen' läßt man sein Prg. dann in einer (Event-)Loop laufen. Im Prinzip will ich bei einem Button solange eine Texteingabe einlesen, bis dieser wieder gedrückt wird.

    Als Extra-DLL brauchst du das nur, wenn du alle Tastatureingaben im System abfangen willst.

    Das will ich dann wohl nicht (also kein Keylogger). Habe ja nur einen ganz definierten Zeitpunkt.
    Trotzdem weiß ich nicht genau, wie ich mit dem Code umgehen soll. Mir reicht ja ein

    ....mach was...Text-Einlesen starten......Eingabe.....Text-Einlesen beenden....mach weiter.
    

    Das weiß ich:

    SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc, hDllInstance, NULL);
    

    'Aktiviert den Hook', wobei mich nur noch 'KeyboardHookProc' interessieren düfte, das ist die Funktion, wo die Events gemeldet werden. 'hDllInstance' kann ich auf Null setzen?!

    LRESULT CALLBACK KeyboardHookProc (int nCode, WPARAM wParam, LPARAM lParam)
    

    Hier kommen die 'gehookten' Events an.

    SendMessage ((HWND) hWindow, (WM_USER + 2), (WPARAM) wParam, (LPARAM) lParam) ;
    

    Da kann ich nach Deiner Aussage drauf verzichten, habe nur keine Ahnung, wie ich dann die Eingaben 'in meine Loop bekomme'.

    return CallNextHookEx (hhkHook, nCode, wParam, lParam) ;

    Ich bin mir nicht sicher, ob ich das machen muss, bzw. ob ich hhkHook überhaupt habe, wenn ich nicht mit einer DLL arbeiten will.

    UnhookWindowsHookEx (hhkHook) ;
    

    Hier wird der Hook beendet. OK, hhkHook habe ich, nur muss es global sein?

    ----

    Bitte sagt mir, dass es nach meiner ausführlichen 🙂 Beschreibung dessen, was mein Prg. ist und macht, eine vieeeel einfache Methode gibt!!!

    btw: Ist nicht so, dass ich hier nur frage, ich habe auch damit herumgespielt. Aber leider greift der Hook anscheinend auch nicht.

    --- EDIT:

    So, Budder bei die Fisches:
    Unabhängig vom Verständnis des Ganzen habe ich mich daran trotzdem versucht. Der Code klappt aber nicht. Wie auch immer ich an der markierten Stelle weiterarbeiten würde, sie wird leider niemals erreicht:

    HHOOK hhkHook;
    
    LRESULT CALLBACK KeyboardHookProc (int nCode, WPARAM wParam, LPARAM lParam) {
    [b]/// HIER LANDE ICH NIEMALSE!!![/b]
        if (nCode == HC_ACTION){
            if ((lParam & 1073741824) != 1073741824){
                //SendMessage ((HWND) hWindow, (WM_USER + 2), (WPARAM) wParam, (LPARAM) lParam) ;
            }
        }
        return CallNextHookEx (hhkHook, nCode, wParam, lParam) ;
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
            // Init LCD etc.....
    
    	while(a_lcd->IsConnected()) {
    		if (a_lcd->ButtonTriggered(LG_BUTTON_1)) {
    			a_lcd->SetText( a_zeile1, _T("Eingabe startet") );
    			[b]hhkHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, NULL, 0);
        // GetCurrentThreadId() statt '0' geht auch nicht, scheint aber wenigstens dazu zu führen, dass hhkHook != 0 ist (laut MSDN auch unlogisch).[/b]
       		} else if (a_lcd->ButtonIsPressed(LG_BUTTON_4)) {
                    [b]UnhookWindowsHookEx (hhkHook);[/b]
    			break;
    		}
        }
        // ....
    }
    

    Button 1 startet die Eingabe, Button 4 beendet (alles). Den Fall Button 4 ohne Button 1 vorher ignorieren wir mal 😃



  • Und woher kommen die Tastatureingaben? Von der normalen PC-Tastatur oder deinem G15 (btw, hast du mal ein Bild, wie das Ding aussieht?)?

    @SendMessage() - das wurde bei dem Beispielprogramm verwendet, um die ankommenden Tasten an das Programm weiterzuschicken. Du könntest dir einen globalen string anlegen und jede Taste dort reinpacken (bei Button1 räumst du den String auf und startest den Hook, bei Button4 stoppst du den Hook und schaust nach, was im String eingetragen ist.

    (und noch etwas: "If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL).")



  • CStoll schrieb:

    Und woher kommen die Tastatureingaben? Von der normalen PC-Tastatur oder deinem G15 (btw, hast du mal ein Bild, wie das Ding aussieht?)?

    Ist eine normale USB-Tastatur, die halt per Treiber das Display ansteuert:
    http://www.logitech.com/index.cfm/keyboards/keyboard/devices/180&cl=de,de

    CStoll schrieb:

    @SendMessage() - das wurde bei dem Beispielprogramm verwendet, um die ankommenden Tasten an das Programm weiterzuschicken. Du könntest dir einen globalen string anlegen und jede Taste dort reinpacken (bei Button1 räumst du den String auf und startest den Hook, bei Button4 stoppst du den Hook und schaust nach, was im String eingetragen ist.

    OK, dann geht's also nur per globaler Variable, das ist aber auch OK. Da ich aber gern die Eingabe auf dem LCD mit ausgeben will, werde ich wohl auch hier ein 'API'-Object erzeugen, dass per Mutex den Zugriff regelt, nicht, dass ich Buchstaben verliere oder doppelt habe.

    CStoll schrieb:

    (und noch etwas: "If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL).")

    Ich weiß nicht, was mit mir los ist. Vermutlich fehlte mir die Fettschrift beim MDSN. Hatte genau das gelesen und war der Meinung, dass ganau die '0' bedeuten würde, dass alle Threads des erzeugenden Processes erreicht werden.... war wohl zu wenig Schlaf.

    Nur warum komme ich in meinem Code nicht an den Haltepunkt?

    -> Edit: Ich sehe gerade, dass VS mir nach dem Starten beim Haltepunkt die Meldung 'ungültige Dateizeile' ausgibt, ich habe aber keine Ahnung, warum.



  • Vielleicht bin ich jetzt weiter:
    - Die Meldung beim Haltepunkt kam vermutlich, weil die Zeit wegoptimiert wurde.
    - Bwim Haltepunkt bin ich deshalb nicht angekommen, weil die Eingabe nicht in meinem Prozess gemacht wurde, denn ich habe ja kein Fenster, das den Focus haben könnte.
    Nachdem ich ein Msg-Window eingebaut habe (testweise) und das den Focus hatte, kamen ich auch zum Haltepunkt.

    Dann muß ich wohl doch eine DLL bauen, die ich an alle Prozesse hänge. Gibt's auch Tips zum Erstellen der DLL? Habe auf die Schnelle nichts gefunden.



  • Sorry!

    Jetzt muss ich doch noch mal nerven. Nachdem ich ja herausgefunden habe, was der Grund für die vorherigen Probleme ist, habe ich das Ganze etwas liegen lassen und an anderer Stelle weiter gemacht.

    Jetzt möchte ich hier aber wieder einsteigen, habe aber keinen Plan, wie ich vorgehen muss.

    Den Code von http://www.c-plusplus.net/forum/viewtopic-var-t-is-39383.html muss ich benutzen und zwar auch als DLL, weil mein Prg. kein Fenster hat, ich also auch Keys anderer Programme abfangen muss (es hat immer jemand anders den Focus).

    Die direkte Codeumgebung sieht so aus (in 'Lautschrift'):

    // Hook starten
    while (LCD-Button nicht gedrückt && kein Return) {
      if (Tastenevent(s)) {
        // auf LCD ausgeben
        // an Puffer anhängen
      }
      Sleep(50);
    }
    // Puffer ins Modell ueberfuehren
    // Hook beenden
    

    Meine Probleme/Fragen:

    • Wie binde ich den Code ein, dazu muss ich doch eine DLL kompilieren, oder? Wie mache ich das.
    • Im Beispiel geht die Message mit den Keyevents an eine Funktion meines Programms. Wie bekomme ich die in While-Schleife? Kann ich da nur mit SharedMemorie / Mutex / was auch immer arbeiten? (Stichworte?)

    Sorry, mir fehlt gänzlich der Ansatz. Im Moment weiss ich nicht mal, wie ich daran rumprobieren soll. 😕



  • ---- Sry, ersteinmal zurück. Bin etwas weitergekommen...


Anmelden zum Antworten