Tasteneingabe an Spiel senden
-
Hallo,
ich hab ein Problem was ich auch nach längerdem rum experimentieren nicht lösen konnte.Wenn im Spiel eine bestimmte Farbe erscheint dann wird die Taste 1 gedrückt, wenn die Farbe danach nochmal erscheint passiert jedoch gar nichts die SendInput Funktion scheint gar nicht ausgelöst zu werden.
Wenn ich dann jedoch selbst einmal die 1 auf meiner Tastatur drück und die Farbe erneut im Spiel erscheint dann wird mein Tastendruck ausgelöst.
Weiss wer woran das liegen kann ? Mir fällt da nichts zu ein.
#include <windows> #include <iostream> using namespace std; int main(int argc, char* argv[]) { bool terminate = false; COLORREF ref; Sleep(3000); UINT key; HWND hwnd; HWND foc; DWORD getThreadID; DWORD getThreadProcessID; bool Attach; hwnd = FindWindow (0,"Guild Wars"); if ( hwnd == 0 ) { cout<<"FindWindow error code:"<<GetLastError(); } HDC hdc = GetDC(0); getThreadID = GetCurrentThreadId(); getThreadProcessID = GetWindowThreadProcessId(hwnd,0); Attach = AttachThreadInput( getThreadID , getThreadProcessID , true ); if ( Attach == 0) { cout<<"AttachThreadInput error code: "<<GetLastError()<<endl; system("PAUSE"); } while ( terminate == false) { ref = GetPixel( hdc, 424, 93 ); if (ref == 0xDAE7A1) { key = MapVirtualKey( 0x31,0 ); INPUT data; data.type = INPUT_KEYBOARD; data.ki.wVk = 0x31; data.ki.wScan = key; data.ki.dwFlags = 0; data.ki.time =0; data.ki.dwExtraInfo = 0; SendInput (1 , &data, sizeof(data)); } if (GetAsyncKeyState(VK_ESCAPE) ==-32767) { AttachThreadInput( getThreadID , getThreadProcessID , false ); terminate = true; } } return 0; }
-
Tasten sind mechanische Elemente mit zwei zuständen: gedrückt und nicht gedrückt.
Wenn sie gedrückt sind, kann man sie nicht noch mal drücken!
-
Also müsste ich die Taste welche gedrückt wurde wieder loslassen?
In der MSDN habe ich zu SendInput folgendes noch gelesen:
http://msdn.microsoft.com/en-us/library/ms646310(v=vs.85).aspxThis function does not reset the keyboard's current state. Any keys that are already pressed when the function is called might interfere with the events that this function generates. To avoid this problem, check the keyboard's state with the GetAsyncKeyState function and correct as necessary.
This function does not reset the keyboard's current state <-- Oder muss ich noch den Status ändern?
-
Es ist ganz einfach: Wenn Du eine Taste drückst, musst Du sie auch wieder loslassen.... es braucht also immer min. 2 (in Worten: ZWEI) Events um einen Tastendruck zu simulieren...
-
Also müsste es so aussehen ?
#include <windows> #include <iostream> using namespace std; int main(int argc, char* argv[]) { bool terminate = false; COLORREF ref; Sleep(3000); UINT key; HWND hwnd; HWND foc; DWORD getThreadID; DWORD getThreadProcessID; bool Attach; hwnd = FindWindow (0,"Guild Wars"); if ( hwnd == 0 ) { cout<<"FindWindow error code:"<<GetLastError(); } HDC hdc = GetDC(0); getThreadID = GetCurrentThreadId(); getThreadProcessID = GetWindowThreadProcessId(hwnd,0); Attach = AttachThreadInput( getThreadID , getThreadProcessID , true ); if ( Attach == 0) { cout<<"AttachThreadInput error code: "<<GetLastError()<<endl; system("PAUSE"); } while ( terminate == false) { ref = GetPixel( hdc, 424, 93 ); if (ref == 0xDAE7A1) { key = MapVirtualKey( 0x31,0 ); INPUT data; data.type = INPUT_KEYBOARD; data.ki.wVk = 0x31; data.ki.wScan = key; data.ki.dwFlags = 0; data.ki.time =0; data.ki.dwExtraInfo = 0; SendInput (1 , &data, sizeof(data)); // Taste drücken SendInput (1 , &data, sizeof(data)); // Taste loslassen } if (GetAsyncKeyState(VK_ESCAPE) ==-32767) { AttachThreadInput( getThreadID , getThreadProcessID , false ); terminate = true; } } return 0; }
-
WO lässt Du denn da die Taste los?
Hast Du schon mal einen Blick ind ie Doku geworfen und die Millionen Beispiele im Internet angeschaut?
-
Jochen Kalmbach schrieb:
...und die Millionen Beispiele im Internet angeschaut?
Gut, ich muss mich korrigieren, Google kennt nur 313000 Treffer für SendInput...
-
Kleiner Tipp: Stichwort KEYEVENTF_KEYUP
HTH,
Martin
-
Hier sind wir im Forum WinApi unterwegs. Da gibt es noch die Möglichkeit, alle Maus- und Tastatureingaben vor der vorgesehenen Verarbeitung mit Subclassing selbst umzubiegen und anderes zu veranlassen.
-
Hallo berniebutt,
so wie es der Fragesteller formuliert hat, wird es mit dem Subclassing kaum funktionieren. Da er die Tasten an einen anderen Prozeß senden muß.db* schrieb:
Hallo ich versuche gerade eine Tasteneingabe an ein Spiel zu senden jedoch funktioniert es einfach nicht.
Oder hast Du in Verbindung mit DLL-Injektion gemeint?
Ok, da muß ich passen, mit DLL-Injektion kenne ich mich nicht so gut aus.HTH,
Martin
-
berniebutt schrieb:
Hier sind wir im Forum WinApi unterwegs. Da gibt es noch die Möglichkeit, alle Maus- und Tastatureingaben vor der vorgesehenen Verarbeitung mit Subclassing selbst umzubiegen und anderes zu veranlassen.
Bringt nur was, wenn das Zielprogramm auch WM_KEYDOWN&Partner verwendet.
-
injektion->Adminrecht schrieb:
berniebutt schrieb:
Hier sind wir im Forum WinApi unterwegs. Da gibt es noch die Möglichkeit, alle Maus- und Tastatureingaben vor der vorgesehenen Verarbeitung mit Subclassing selbst umzubiegen und anderes zu veranlassen.
Bringt nur was, wenn das Zielprogramm auch WM_KEYDOWN&Partner verwendet.
Bitt laß diesen Unfug mit WM_KEYDOWN & Co zu senden!
Siehe auch "Die Unsitte Tastatureingaben mit WM_KEYDOWN Nachrichten zu simulieren" (Link habe ich bereits weiter oben angegeben)Martin
-
Mmacher schrieb:
Bitt laß diesen Unfug mit WM_KEYDOWN & Co zu senden!
ich habe nie Vorgeschlgen mit subclassing zu arbeiten
-
Hallo, ich hab irgendwann damit aufgeben mit dem Tastendruch an Guild Wars senden.
Jetzt wollte ich es aber nochmal wissen, also hab ich AutoIT wieder installiert und geschrieben:AutoIT Code
Sleep(2000) Send("1")
Dann das Programm compiliert und den OllyDebugger ausgepackt. ( Das hätte ich mal ehr machen sollen ... )
Und das Geheimnis der ganzen Sache ist der Scancode.
Und so funktioniert es perfekt:
Ohne AttachThreadInput und so späße.#include <windows> #include <iostream> using namespace std; int main(int argc, char* argv[]) { Sleep(2000); INPUT data; data.type = INPUT_KEYBOARD; data.ki.wVk = 0x31; data.ki.wScan = 2; // scan code für taste 1 data.ki.dwFlags = 0; data.ki.time =0; data.ki.dwExtraInfo = 0; SendInput (1 , &data, sizeof(data)); // taste drücken data.ki.dwFlags = KEYEVENTF_KEYUP; SendInput (1 , &data, sizeof(data)); // taste loslassen return 0; } //---------------------------------------------------------------------------
-
Btw. AutoIT verwendet die Funktion: keybd_event Die sollten vielleicht auch mal ein Update machen.^^