Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Capturar F7 en unidad sin formulario

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Capturar F7 en unidad sin formulario Responder citando

Hola.

Digamos que tengo un formulario con un TMemo que muestra las operaciones realizadas por un unit sin formulario.
Quiero crear la función "paso a paso" de manera que mientras el operario no pulse F7, el programa no realice la siguiente operación y se quede parado.
Como puedo capturar F7 sin usar "onKeyPress" si no tengo formulario?
También he intentado desde la unidad sin formulario que ejecute el evento OnKeyDown del TMemo, pero no se como hacerlo.

Salu2.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

No entiendo muy bien lo que haces... pero si quieres capturar el mensaje antes de que sea enviado a algún form de forma centralizada puedes usar algo como el siguiente código en el evento "OnMessage" del componente "TApplicationEvents" (pestaña: Additional):
Código:
    if (Msg.message == WM_KEYDOWN && Msg.wParam == VK_F7)
    {
        ShowMessage("F7 Pulsada");
        Handled = true;
    }
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola Leo.
Voy a explicarlo un poco mejor.
En una unidad sin formulario tengo una función que se encarga de leer las lineas de un fichero de texto. Cada linea es una función de un sub-lenguaje creado especialmente para los procesos de la empresa.
Pues lo dicho, esa unidad sin formulario se encarga de leer una po una las lineas del fichero, ejecutarlas, y mostrar en un formulario, con un TMemo la función, y el resultado obtenido.
Los ingenieros que realizan el algoritmo (fichero de texto realizado con el sub-lenguaje) necesitan en algún momento poder ejecutar "paso a paso" (linea por linea) dicho algoritmo para estudiar que sucede en cada momento ya que una vez finalizado, ese algoritmo pasa a los procesos de producción, dónde no puede haber ningún error.

Me comentas que ponga un objeto ApplicationEvent en el formulario con el TMemo, pero no se como puede parar la ejecución de la lectura de lineas hasta que el ingeniero pulse F7.

Salu2.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Habría que ver como tienes el intérprete implementado.. pero una vez capturada la tecla F7 podrías o bien usar una variable global que indique que se ha pulsado y comprobar su valor desde el modulo que interpreta esas líneas. O bien si tienes el interprete creado como un objeto hacer llamadas a algún método llamado por ejemplo "Paso()" por cada pulsación cuando está en ese modo, etc... No se si me entiendes, para el caso da realmente igual donde captures la tecla.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola Leo.
Ésta es la función que lee el fichero de algoritmo. Para ser más concreto te diré que el algoritmo se lee previamente y se introducen los datos compilados en un vector. Lo que hace realmente ésta función es leer linea por linea el vector dónde está compilado el algoritmo.

Cita:
//-------------------------------------------------------------------------------
void TCtlAlg::Run (void)
{
TInstruc *i = new TInstruc;

// bucle que procesa el array de instrucciones
while (ptrInstruc < Instruc.end() && processa)
{
// restet errores anteriores
CtlError.InitCtlError();
// prepara los datos compilados de la instrucción a ejecutar.
*i = *ptrInstruc;
// ejecuta instrucción.
numInstruc++;
//RunComana es la función que ejecuta cada función del algoritmo.
//La función interna correspondiente en C++ se encarga además
//de escribir en el TMemo el resultado
if ((Comana.RunComana(i) <0>ProcessMessages();
};

Comana.Parada();
DocStop();
delete i;
};


La idea es poner antes de RunComana la llamada a otra función que dentro tenga un WHILE ejecutandose indefinidamente hasta que el usuario pulse F7.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Niteman escribió:
La idea es poner antes de RunComana la llamada a otra función que dentro tenga un WHILE ejecutandose indefinidamente hasta que el usuario pulse F7

Pues la forma más simple para detenerlo al pulsar F7 es lo que he puesto antes, le añades alguna variable global la cual cambias su valor donde se captura la tecla F7 y esta variable a su vez la vas comprobando dentro del while antes de cada "RunComana".
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

No se que pasa pero no funciona.
Finalmente he decidido que pulsando cualquier tecla se ejecute la siguiente función.

Delante de la función RunComana he puesto la llamada a la función DetectaKey().
Cita:
int TCtlAlg::DetectaKey(void)
{
while (kbhit()==0); /* do nothing */
return 1;
};

Con kbhit se deberia de detectar la pulsación de cualquier tecla, no? pero se queda clabado en el while y de alli no sale. Es que me falta algo?

Salu2.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Creo q debes seguir en la linea q te comenta Leo, no se si el ProcessMessages(); que utilizas tu es correcto, yo utilizaria antes del comana...
Código:
while (!Handled) {
  Sleep(200);
  Application->ProcessMessages();
}
// procesar...

Eso si, Handled debe ser global al proyecto, y tambien deberias preparar una salida voluntaria al algoritmo por si decides abortarlo.
Saludos
Juanma
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

"kbhit()" solo es válido en MSDOS o en modo consola.

En la ayuda pone claramente:
Note: Do not use this function in Win32 GUI applications.


Lo de usar una variable global que te proponía seria similar a lo que intentas hacer con kbhit, en el lugar que interceptas F7 le das el valor True y en el bucle donde necesitas parar la ejecución compruebas su valor.

De todas formas si te gusta más lo de "kbhit" también podrías hacerlo así secuencialmente más al estilo de MSDOS:
Código:
for (int i=0; i<1000000; i++)
{
    // Hacemos algo
    Caption = i;
    // Comprobamos si F7 esta pulsada
    //  si es así interrumpimos el bucle
    Application->ProcessMessages();
    if (GetAsyncKeyState(VK_F7) & 1)
        break;
}
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Es verdad lo de kbhit!! Lapsus mio.

No se porqué a veces no hago caso a los gurús de esto....así me va!!
Bueno, ahora con el GetAsyncKeyState me funciona más o menos. Grácias.

Leo, creo que tienes una pequea confusión respecto a lo que quiero. No se trata de que se pare el proceso al pulsar F7, sino que ejecute la siguiente instrucción al pulsarlo. Para parar el proceso de ejecución y entre el la detección de F7, utilizo un check box en el formulario principal.
En definitiva, lo mismo que hacemos con el Builder cuando queremos evaluar la corecta ejecución del programa.

Ahora solo me falta que solo actue en cada pulsación, es decir, que aunque el usuario tenga el dedo pegado a F7 pulsándolo, esté forzado a soltar F7 y volverlo a pulsar para que se ejecute la siguiente instrucción. Ahora, como la ejecución de comandos es más rápido que el dedo, se ejecutan varios comandos antes de pararse. Como lo hago?

Código:
int TCtlAlg::DetectaF7(void)
{
Application->ProcessMessages();
while (!(GetAsyncKeyState(VK_F7) && 1));
return 1;
}
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Prueba cambiando el && por &, veras que la repetición es más lenta, pruébalo así y dime si te vale.

Mas información: GetAsyncKeyState.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Cierto Leo. Se me habia ido el dedo al escribir el &.
Funciona a la perfección. Mil gracias.

Salu2.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.