Also,
nachdem ich mich weiter damit beschäftigt habe sind mir ein paar Sachen klar geworden. Mit dem CTRL-C Handler lässt sich das nicht lösen und in der Handlerfunktion auf Benutzereingaben zu warten ist eine blöde Idee. Das Drücken von CTRL-C unterbricht auch die Eingaben über std::in, was in meinem Programm oben passiert ist Folgendes:
CTRL-C drücken: Handler wird angesprungen und bleibt in Zeile 26 stehen, um die Benutzereingabe zu lesen
CTRL-C drücken: Die Benutzereingabe wird abgebrochen und der Handler erneut angesprungen. Aus irgendwelchen Gründen kann der Benutzer jetzt aber nichts mehr eingeben.
nächstes Drücken von CTRL-C: goto 2)
Meine Lösung sieht jetzt so aus, dass ich die Konsole in den Raw-Modus versetze, in dem CTRL-C nicht mehr gefangen wird und auch keinen Handler mehr anspringt. Stattdessen landet das Event als 0x03 im Eingabestrom der Konsole. Den kann ich über ReadFile lesen und entsprechend reagieren. Dazu muss ich noch ein paar Konsolenflags bei Bedarf ein- und ausschalten, aber jetzt funktioniert´s genau so, wie ich es haben will:
#include <cctype>
#include <iostream>
#include <windows.h>
void enable_console_flag( HANDLE console, DWORD flag )
{
DWORD mode = 0;
BOOL const r1 = ::GetConsoleMode( console, &mode );
mode |= flag;
BOOL const r2 = ::SetConsoleMode( console, mode );
}
void disable_console_flag( HANDLE console, DWORD flag )
{
DWORD mode = 0;
BOOL const r1 = ::GetConsoleMode( console, &mode );
mode &= ~flag;
BOOL const r2 = ::SetConsoleMode( console, mode );
}
int main()
{
HANDLE console_in = ::GetStdHandle( STD_INPUT_HANDLE );
HANDLE console_out = ::GetStdHandle( STD_OUTPUT_HANDLE );
disable_console_flag( console_in, ENABLE_PROCESSED_INPUT ); // Konsole in Raw Modus versetzen
disable_console_flag( console_in, ENABLE_LINE_INPUT); // Eingaben direkt verarbeiten, ohne auf CR zu warten
for( ;; )
{
char input_buffer[16];
DWORD bytes_read = 0;
::ReadFile( console_in, input_buffer, sizeof( input_buffer ), &bytes_read, nullptr );
// alle Eingaben außer CTRL-C verwerfen
if( bytes_read == 1 && input_buffer[0] == 0x03 )
{
std::cout << "Anwendung beenden (J/N)? ";
enable_console_flag( console_in, ENABLE_LINE_INPUT ); // Eingabe erst bei CR bearbeiten, aktiviert automatisch ECHO
::ReadFile( console_in, input_buffer, sizeof( input_buffer ), &bytes_read, nullptr );
::FlushConsoleInputBuffer( console_in );
disable_console_flag( console_in, ENABLE_LINE_INPUT); // zurück zum direkten Eingabemodus
std::cout << "\r\n";
if( bytes_read == 2 )
{
// nur abbrechen, wenn die beiden Tasten 'j' und <CR> gedrückt wurden
char const key1 = std::tolower( input_buffer[0] );
char const key2 = input_buffer[1];
if( key1 == 'j' && key2 == '\r' )
{
break;
}
}
}
}
return 0;
}
Danke für eure Hilfe.