Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: WinAPI ::  Frage zu Simulation von Tastatureingaben  
Gehen Sie zu Seite Zurück  1, 2
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag 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
Beitrag 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




Beitrag 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
Beitrag 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
Beitrag 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




Beitrag 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. :confused: 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 ;
       }


 }
C/C++ Forum :: WinAPI ::  Frage zu Simulation von Tastatureingaben  
Gehen Sie zu Seite Zurück  1, 2
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




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.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.