Autor
Nachricht
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
16:24:22 31.01.2012 Titel:
Frage zu Simulation von Tastatureingaben
Zitieren
Hallo, ich habe mir gerade diesen Artikel durchgelesen:
http://blog.m-ri.de/index.php/2007/12/27/die-unsit ....... eingaben-mit-wm_keydown-nachrichten-zu-simulieren/
So soll man also Tastatureingaben Simulieren:
Code: 1. Dass Zielfenster, bzw. den Thread in dem das Zielfenster muss ausgewählt werden, damit er diese Eingaben auch erhalten darf. Das wird durch AttachThreadInput erreicht. Denn wir wollen die Daten ja nicht an unsere Applikation senden. Bitte hinterher nicht vergessen AttatchThreadInput mit FALSE aufzurufen und den Thread wieder zu detachen.
2. Man muss den Fokus korrekt setzten für das Fenster, dass die Eingaben erhalten soll!
Ist der Zielthread jetzt an die Eingabequeue angeschlossen, kann man ohne Probleme SetFocus ausführen (was ohne AttachThreadInput normalerweise auch nicht möglich wäre).
3. Wird jetzt SendInput ausgeführt, werden alle Nachrichten korrekt erzeugt und auch alle Commands entsprechend der Tastaturfolge ausgelöst. Auch spezielle Umlaute und Unicode Zeichne lassen sich so erzeugen.
Code: 1. Dass Zielfenster, bzw. den Thread in dem das Zielfenster muss ausgewählt werden, damit er diese Eingaben auch erhalten darf. Das wird durch AttachThreadInput erreicht. Denn wir wollen die Daten ja nicht an unsere Applikation senden. Bitte hinterher nicht vergessen AttatchThreadInput mit FALSE aufzurufen und den Thread wieder zu detachen.
2. Man muss den Fokus korrekt setzten für das Fenster, dass die Eingaben erhalten soll!
Ist der Zielthread jetzt an die Eingabequeue angeschlossen, kann man ohne Probleme SetFocus ausführen (was ohne AttachThreadInput normalerweise auch nicht möglich wäre).
3. Wird jetzt SendInput ausgeführt, werden alle Nachrichten korrekt erzeugt und auch alle Commands entsprechend der Tastaturfolge ausgelöst. Auch spezielle Umlaute und Unicode Zeichne lassen sich so erzeugen.
Code: 1. Dass Zielfenster, bzw. den Thread in dem das Zielfenster muss ausgewählt werden, damit er diese Eingaben auch erhalten darf. Das wird durch AttachThreadInput erreicht. Denn wir wollen die Daten ja nicht an unsere Applikation senden. Bitte hinterher nicht vergessen AttatchThreadInput mit FALSE aufzurufen und den Thread wieder zu detachen.
2. Man muss den Fokus korrekt setzten für das Fenster, dass die Eingaben erhalten soll!
Ist der Zielthread jetzt an die Eingabequeue angeschlossen, kann man ohne Probleme SetFocus ausführen (was ohne AttachThreadInput normalerweise auch nicht möglich wäre).
3. Wird jetzt SendInput ausgeführt, werden alle Nachrichten korrekt erzeugt und auch alle Commands entsprechend der Tastaturfolge ausgelöst. Auch spezielle Umlaute und Unicode Zeichne lassen sich so erzeugen.
Beispiel:
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
void Simulate( string key );
int main()
{
call FindWindow
call GetDC
for (int i=0;i<10;i++) // 10 mal a und b Tastendruck simulieren
{
Simulate( a ); // drücke a
Simulate( b ); // drücke b
}
return 0;
}
void Simulate( string key )
{
//Pseudocode
call GetCurrentThreadId
call GetWindowThreadProcessId
call AttachThreadInput mit true // attach
call SetFocus
call SendInput
AttachThreadInput mit false // detach
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
void Simulate( string key );
int main()
{
call FindWindow
call GetDC
for (int i=0;i<10;i++) // 10 mal a und b Tastendruck simulieren
{
Simulate( a ); // drücke a
Simulate( b ); // drücke b
}
return 0;
}
void Simulate( string key )
{
//Pseudocode
call GetCurrentThreadId
call GetWindowThreadProcessId
call AttachThreadInput mit true // attach
call SetFocus
call SendInput
AttachThreadInput mit false // detach
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
void Simulate( string key );
int main()
{
call FindWindow
call GetDC
for (int i=0;i<10;i++) // 10 mal a und b Tastendruck simulieren
{
Simulate( a ); // drücke a
Simulate( b ); // drücke b
}
return 0;
}
void Simulate( string key )
{
//Pseudocode
call GetCurrentThreadId
call GetWindowThreadProcessId
call AttachThreadInput mit true // attach
call SetFocus
call SendInput
AttachThreadInput mit false // detach
}
Nun zu meiner Frage:
Kann ich die Funktion Simulate(); so verwenden oder ist es ehr schlecht da ich jedes mal wenn ich ein Tastendruck simulieren möchte AttachThreadInput aufrufe?
Früher hatte ich mich schon mal mit dem Thema Tastatureingaben an Fenster senden beschäftigt, da bekam ich ab und zu Probleme wenn ich nach jedem Tastendruck nicht AttachThreadInput mit false (für detach) aufgerufen habe.
Wie seht ihr das?
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
17:10:08 31.01.2012 Titel:
Zitieren
So ich hab nochmal etwas alten Code ausgekramt und rumgetestet:
Das Programm Simuliert eine Tastatur Eingabe im Editor.
Es soll 8 mal die Taste a gedrückt werden.
Manchmal werden nur 3 a´s an den Editor geschickt und manchmal aber auch 8.
Wieso funktioniert das so nicht richtig?
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow (0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
}
for (int i=0;i<8;i++)
{
Simulate(hwnd);
}
system("PAUSE ");
}
void Simulate(HWND hwnd)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = 0x41;
data.ki.dwFlags = KEYEVENTF_EXTENDEDKEY,KEYEVENTF_KEYUP;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow (0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
}
for (int i=0;i<8;i++)
{
Simulate(hwnd);
}
system("PAUSE ");
}
void Simulate(HWND hwnd)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = 0x41;
data.ki.dwFlags = KEYEVENTF_EXTENDEDKEY,KEYEVENTF_KEYUP;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow (0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
}
for (int i=0;i<8;i++)
{
Simulate(hwnd);
}
system("PAUSE ");
}
void Simulate(HWND hwnd)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = 0x41;
data.ki.dwFlags = KEYEVENTF_EXTENDEDKEY,KEYEVENTF_KEYUP;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
17:13:55 31.01.2012 Titel:
Zitieren
Ach mist,
data.ki.dwFlags = KEYEVENTF_EXTENDEDKEY,KEYEVENTF_KEYUP; <-- Ohne das KEYEVENTF_KEYUP
dann geht es. Erst mal meinen alten Code Schnippsel verbessern.
Aber nochmal zu meiner Frage kann man das so machen oder ist das er unsinnig?
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
17:33:51 31.01.2012 Titel:
Zitieren
Geht, doch irgendwie nicht immer -.-
4 mal hintereinander geht es dann nicht mehr.
Es geht erst wieder wenn ich selbst die Taste a einmal drücke, ich weiss echt nicht was da dran falsch sein soll ... Hat wer eine Idee?
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
00:07:20 01.02.2012 Titel:
Zitieren
Hat den keiner eine Idee was ich da falsch mache?
hustbaer
Mitglied
Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
hustbaer Mitglied
01:44:18 01.02.2012 Titel:
Zitieren
hustbaer
Mitglied
Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
hustbaer Mitglied
02:02:26 01.02.2012 Titel:
Zitieren
KbdDrv schrieb: Hat den keiner eine Idee was ich da falsch mache?
du musst zuerst eins ohne "up" schicken (=taste runterdrücken), und dann eins mit "up" (=taste loslassen).
dann wieder runterdrücken, wieder loslassen.
usw.
und was soll das KEYEVENTF_EXTENDEDKEY, wenn du bloss ein 'a' schicken willst?
_________________ "Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
10:44:32 01.02.2012 Titel:
Zitieren
Hallo, danke für die Anwort
So sieht jetzt mein SendInput aus ? Aber es funktioniert noch immer nur sporadisch.
Und warum soll man AttachThreadInput mit false aufrufen bevor SendInput kommt?
C/C++ Code: 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
C/C++ Code: 1 2 3 4 5 6 7 8 9 10
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
C/C++ Code: 1 2 3 4 5 6 7 8 9 10
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
Mein ganzes Programm:
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
}
hustbaer
Mitglied
Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
hustbaer Mitglied
13:13:24 01.02.2012 Titel:
Zitieren
KbdDrv schrieb: Und warum soll man AttachThreadInput mit false aufrufen bevor SendInput kommt?
Das hab ich vielleicht ungünstig formuliert.
Ich meinte nur es müsste auch funktionieren wenn man AttachThreadInput(false) bereits vorher macht.
AttachThreadInput() ist nur nötig damit SetFocus() funktioniert. SendInput() ist nicht von AttachThreadInput() abhängig, und wenn der Fokus vorher korrekt umgesetzt wurde...
Funktioniert es denn zuverlässig wenn du in er 2 Sekunden Pause das Notepad Fenster selbst aktivierst (anklickst)?
_________________ "Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
13:35:54 01.02.2012 Titel:
Zitieren
Wenn ich selber in das Editor Fenster klicke dann funktioniert alles ohne Probleme.
Ebenso wenn ich SetForegroundWindow anstatt SetFocus verwende, dann funktioniert das Programm auch ohne Probleme da muss ich dann auch nicht erst selbst in das Fenster klicken.
Mache ich irgendwas falsch oder ist SetFocus eine verbuggte Funktion.
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++){
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
/*/ Mit SetFocus funktioniert das Programm nur sporadisch -.-
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE");
return ;
}
/*/
foreground = SetForegroundWindow(hwnd);
if ( foreground == false ){
cout<<"SetForeground error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++){
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
/*/ Mit SetFocus funktioniert das Programm nur sporadisch -.-
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE");
return ;
}
/*/
foreground = SetForegroundWindow(hwnd);
if ( foreground == false ){
cout<<"SetForeground error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include <windows>
#include <iostream>
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++){
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
Simulate(hwnd,0x44);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
/*/ Mit SetFocus funktioniert das Programm nur sporadisch -.-
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE");
return ;
}
/*/
foreground = SetForegroundWindow(hwnd);
if ( foreground == false ){
cout<<"SetForeground error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
hustbaer
Mitglied
Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
hustbaer Mitglied
14:35:49 01.02.2012 Titel:
Zitieren
Naja verbuggt ist relativ.
Das is ein Schutzmechanismus von Windows, damit nicht dauernd ein lästiges Programm den Fokus klaut. Grundsätzlich sehr sinnvoll, nur immer dann elendig lästig, wenn man drumrumarbeiten muss.
Ich hatte kürzlich nen ähnlichen Fall, nur musste ich ein Fenster zuverlässig in den Vordergrund zwingen (der Input-Fokus wäre egal gewesen) - egal wie wild der User in ein anderes Fenster reingeklickt und/oder reingetippt hat.
Funktioniert hat bei mir letztlich nur BringWindowToTop. SetForegroundWindow/ActivateWindow/SetFocus waren *nicht* ausreichend. Weiss der Geier wieso.
_________________ "Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
Martin Richter
Moderator
Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13521
Martin Richter Moderator
16:23:35 01.02.2012 Titel:
Zitieren
Das mit SetFocus ist kein Schutzmechanismus und auch nicht verbuggt. Jeder Thread kann sein eigenes Focus Fenster haben und das ändert sich eben nicht wenn ein Threadcontext wechsel stattfindet...
Viele Funktionen liefern threadlokale infos. GetFocus/SetFocus gehören dazu.
Genauso wie GetCurrentDirectory prozessbezogen ist und eben auch nicht für alle Prozesse gilt.
_________________Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
16:44:01 01.02.2012 Titel:
Zitieren
Aber warum funktioniert das Programm nur sporadisch?
Dann muss ich da ja irgendwas falsch machen? Aber was?
Ich versteh echt nicht wieso das mit SetFocus nicht funktioniert.
Das muss doch irgeeennddwiieee gehen.
Andreas XXL
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.01.2004
Beiträge: 915
Andreas XXL Mitglied
19:39:30 01.02.2012 Titel:
Zitieren
Ich kann es nicht genau erläutern, es scheint aber so zu sein, dass keine richtigen Tastaturevents erzeugt werden. Es sieht so aus, als ob in einem kleinen Intervall festgestellt wird, ob die jeweilige Taste gedrückt ist oder nicht. Und wenn nach dem Tastendruck das Loslassen zu schnell kommt wird es vom Programm nicht gemerkt.
(Ich habe damit lange experimentiert)
Wenn du eine Pause zwischen dem Drücken und dem Loslassen der Taste einbaust, sollten alle Tastendrücke erkannt werden. Also in etwa so:
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.dwFlags = 0;
data.ki.time =0;
data.ki.dwExtraInfo = 0;
SendInput (1 , &data, sizeof (data)); // Taste drücken
Sleep(60); // <- neu
data.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1 , &data, sizeof (data)); // Taste loslassen
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.dwFlags = 0;
data.ki.time =0;
data.ki.dwExtraInfo = 0;
SendInput (1 , &data, sizeof (data)); // Taste drücken
Sleep(60); // <- neu
data.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1 , &data, sizeof (data)); // Taste loslassen
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.dwFlags = 0;
data.ki.time =0;
data.ki.dwExtraInfo = 0;
SendInput (1 , &data, sizeof (data)); // Taste drücken
Sleep(60); // <- neu
data.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1 , &data, sizeof (data)); // Taste loslassen
Besonders Programmen, die zu wenig fps haben, "übersehen" häufiger so simulierte Tastendrücke.
Warum aber keine Tastaturevents produziert werden die erst einmal zwischengespeichert werden kann ich mir nicht erklären. Eigentlich sollte es so sein. Es ist aber nicht so.
An einer Lösung des Problems bin ich auch sehr interessiert.
hustbaer
Mitglied
Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
hustbaer Mitglied
20:19:23 01.02.2012 Titel:
Zitieren
@Andreas XXL
Programme die die Tastatur pollen können sowas übersehen, ja.
Programme wie Notepad, die auf Window-Messages reagieren, nicht.
Kann also bei ihm nicht das Problem sein, wenn er mit Notepad testet.
Passt auch nicht zum Fehlerbild, nämlich dass der Fehler verschwindet, sobald er während seines Sleep(2000) mit der Maus in das andere Fenster reinklickt.
Heisst: das Problem ist ganz klar das Setzen des Fokus, und nicht das Generieren der Input-Events.
_________________ "Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KbdDrv
Unregistrierter
KbdDrv Unregistrierter
12:50:40 07.02.2012 Titel:
Zitieren
Ich hab die Lösung:
So funktioniert es.
Hier ist auch nochmal die Lösung: http://www.c-plusplus.de/forum/289087
Ich habs mal in beide Posts geschrieben unter 2 verschiedenen Namen. mhhm egal^^
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include <windows>
#include <iostream>
#define MAPVK_VK_TO_VSC 0 // Ich hab hier gerade eine veraltete Entwicklungsumgebung deswegen
// das define an der Stelle ^^
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++)
{
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
UINT HardwareScanCode ;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
HardwareScanCode = MapVirtualKey ( KeyInHex, MAPVK_VK_TO_VSC);
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.wScan = HardwareScanCode;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include <windows>
#include <iostream>
#define MAPVK_VK_TO_VSC 0 // Ich hab hier gerade eine veraltete Entwicklungsumgebung deswegen
// das define an der Stelle ^^
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++)
{
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
UINT HardwareScanCode ;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
HardwareScanCode = MapVirtualKey ( KeyInHex, MAPVK_VK_TO_VSC);
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.wScan = HardwareScanCode;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
C/C++ Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include <windows>
#include <iostream>
#define MAPVK_VK_TO_VSC 0 // Ich hab hier gerade eine veraltete Entwicklungsumgebung deswegen
// das define an der Stelle ^^
using namespace std;
void Simulate( HWND hwnd, unsigned KeyInHex );
int main(int argc, char * argv[])
{
Sleep(2000);
HWND hwnd = FindWindow(0,"Unbenannt - Editor ");
if ( hwnd == 0 )
{
cout<<"FindWindow error code: "<<GetLastError();
system("PAUSE ");
return 0;
}
for (int i=0;i<3;i++)
{
Simulate(hwnd,0x41);
Simulate(hwnd,0x42);
Simulate(hwnd,0x43);
}
system("PAUSE ");
}
void Simulate(HWND hwnd, unsigned KeyInHex)
{
bool detach = false ;
bool Attach = false ;
bool foreground = false ;
DWORD getThreadID;
DWORD getThreadProcessID;
UINT HardwareScanCode ;
getThreadID = GetCurrentThreadId();
getThreadProcessID = GetWindowThreadProcessId(hwnd,0);
Attach = AttachThreadInput( getThreadID , getThreadProcessID , true );
if ( Attach == 0){
cout<<"AttachThreadInput error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
hwnd = SetFocus( hwnd );
if (hwnd == 0 ){
cout<<"SetFocus error code: " << GetLastError()<<endl;
system("PAUSE ");
return ;
}
HardwareScanCode = MapVirtualKey ( KeyInHex, MAPVK_VK_TO_VSC);
INPUT data;
data.type = INPUT_KEYBOARD;
data.ki.wVk = KeyInHex;
data.ki.wScan = HardwareScanCode;
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
detach = AttachThreadInput( getThreadID , getThreadProcessID , false );
if ( Attach == 0){
cout<<"AttachThreadInput detach error code: "<<GetLastError()<<endl;
system("PAUSE ");
return ;
}
}
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.