PDA

Ver la Versión Completa : ¿Cómo detecto CTRL+C en consola?


Mastropiero
08-11-2005, 11:10:49
Hola,

pues eso. Estoy haciendo un programa en modo consola y necesito que cuando el usuario pulse CTRL+C o CTRL+Break, en lugar de salir del programa, llame a una función.

Conozco la forma tradicional escaneando el teclado con la INT16h, pero me gustaría saber si hay alguna forma más de alto nivel para hacerlo (capturando algún mensaje o algo así).


Gracias y un saludo.

OSKR
08-11-2005, 16:45:35
MMMMMMMMmmmmmmhhhhhhh......bueno............!!! yo recuerdo q cuando usaba Turbo C o Turbo C++ habia una función llamada CtrlBrk si mas no recuerdo, y modificaba el vector de interrupciones para esa interrupcion valga la redundancia capturandola y ejecutando la función señalada y definida por nosotros, pero creo q para Win32 ya no exista, la otra q veo es q mantengas el uso de interrupciones. Tal vez no te pude ayudar pero al menos tienes un indicio de por donde buscar.

Mastropiero
08-11-2005, 17:22:02
¡Gracias!

Parece que es algo del DOS puro, pero miraré a ver si existe algo equivalente.

Realmente desconocía esa función ya que en aquella época yo llamaba a la INT a "caraperro".

Investigaré por esa línea.

Gracias y un saludo.

Mastropiero
05-02-2008, 10:00:40
Buenas, han pasado dos años y me olvidé de este hilo, pero como creo que puede ser útil para alguien, posteo la solución que encontré en su momento:

Cualquier aplicación (sea consola o gui) que use la unidad SysUtils, levanta una excepción llamada EControlC cuando CTRL+C es pulsado.

Así que lo único que hay que hacer es capturar excepciones en la parte del programa que queremos detectar la interrupción por CTRL+C, y manejar la excepción EControlC a nuestro antojo.

Saludos!

Ñuño Martínez
06-02-2008, 11:03:07
Wenas.

Sólo decir que he estado haciendo pruebas en Linux (Free Pascal) y no funciona. Compila y ejecuta, pero al pulsar [Ctrl+C] cierra el programa y ya está. El programa que he utilizado es este:PROGRAM EjemploControlC;
(* Un ejemplo de cómo capturar [Ctrl+C] con Object Pascal. *)

{ FPC no necesita saber si es o no de consola. }
USES
SysUtils; { EControlC es declarada aquí. }

VAR
VariableTonta: STRING;
BEGIN
TRY
WriteLN ('Para terminar puedes pulsar [Enter] o [Ctrl+C]. El resultado será diferente en cada caso');
ReadLN (VariableTonta);
WriteLN ('Has pulsado [Enter].');
EXCEPT
ON EControlC DO WriteLN ('Has pulsado [Ctrl+C].');
END;
WriteLN ('Que tengas un buen día.');
END.
Sólo lo digo para que conste, no porque crea que esté mal que no es el caso.

Mastropiero
06-02-2008, 13:40:53
Wenas.

Sólo decir que he estado haciendo pruebas en Linux (Free Pascal) y no funciona. Compila y ejecuta, pero al pulsar [Ctrl+C] cierra el programa y ya está. El programa que he utilizado es este:

¿Lo has probado abriendo el ejecutable ya compilado, o sólo desde el IDE?

Lo digo por si en las opciones del debugger o de projecto hay alguna opción que esté inhibiendo el manejo de excepciones del OS.

Yo en su momento lo hice funcionar (Delphi 7 sobre Windows 98), aunque no lo he vuelto a probar desde entonces en XP.

Saludos.

Ñuño Martínez
06-02-2008, 14:04:10
¿Lo has probado abriendo el ejecutable ya compilado, o sólo desde el IDE? Lo he probado de varias formas.

Por cierto, que lo he consultado en la lista de correos de Free Pascal y me han dicho que en Linux no funciona. Para ello hay que utilizar un "signal handler" :(. No lo tengo claro porque el mensaje ha llegado corrupto y no lo he podido leer bien.

cHackAll
06-02-2008, 19:29:49
Debes revisar la API SetConsoleCtrlHandler

uses SysUtils, Windows; {$apptype console}

function HandlerRoutine(dwCtrlType: Cardinal): LongBool;
begin
if dwCtrlType = CTRL_C_EVENT then Halt;
end;

begin
SetConsoleCtrlHandler(@HandlerRoutine, True);
WriteLn('Pulsa Ctrl+C para salir');
while True do ReadLn;
end.

Ñuño Martínez
07-02-2008, 10:43:45
Gracias [ChackAll]