elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Comparar eventos de teclado con strings (C#)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Comparar eventos de teclado con strings (C#)  (Leído 2,908 veces)
Alejovsq

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Comparar eventos de teclado con strings (C#)
« en: 7 Agosto 2019, 04:23 am »

Saludos, amigos!

Estoy intentando realizar un pequeño programa que genera letras aleatorias y con el teclado debo presionar las teclas correspondientes. Esto debe hacerse en un rango de tres (3) segundos, si no, la letra cambiará por otra.

Si la tecla presionada es igual a la letra generada, el texto debe cambiar a color verde, de lo contrario debe cambiar a color rojo.

El problema es que no se capturar muy bien los eventos del teclado para compararlos.

Código:
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

//tmr.Temporizador.Start();

         private void tmrTemporizador_Tick(object sender, EventArgs e)
        {
            string letra= GeneradorLetra();
            lblEtiqueta.Text = letra;   //---------- Cómo llamar un evento de teclado desde aquí, para luego compararlo?
           
        }

        private string GeneradorLetra()
        {
            Random numero = new Random();
            int i = numero.Next(0, 7);

            string[] cadenaDeLetras = { "A", "B", "C", "D", "E", "F", "G" };

            return cadenaDeLetras[i];
        }
    }
}



En línea

Alejovsq

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Comparar eventos de teclado con strings (C#)
« Respuesta #1 en: 7 Agosto 2019, 22:06 pm »

Empecé nuevamente desde cero, quité el ¨Timer¨para ir resolviendo el problema de a poco.

Así va quedando el nuevo código...

Código
  1. public partial class Form1 : Form
  2.    {
  3.        public Form1()
  4.        {
  5.            InitializeComponent();
  6.        }
  7.  
  8.        private void btnIniciar_Click(object sender, EventArgs e)
  9.        {
  10.            letra = GeneradorLetra();
  11.            lblEtiqueta.Text = letra;
  12.  
  13.            /*
  14.              * Como puedo llamar al metodo Form1_Keypress(object, KeyPressEventArgs) desde aqui??
  15.              * Me pide dos argumentos y no se como pasarlos desde este punto.
  16.              */
  17.        }
  18.  
  19.        private string GeneradorLetra()
  20.        {
  21.            Random aleatorio = new Random();
  22.            int i = aleatorio.Next(0, 7);
  23.            string[] seleccion = { "A", "B", "C", "D", "E", "F", "G" };
  24.  
  25.            return seleccion[i];
  26.        }
  27.  
  28.        private void Form1_KeyPress(object sender, KeyPressEventArgs e) //Aun sin funcionar
  29.        {
  30.  
  31.            string teclaOprimida = e.KeyChar.ToString();
  32.  
  33.            if (letra == teclaOprimida)
  34.            {
  35.                lblEtiqueta.ForeColor = Color.Green;
  36.            }
  37.            else
  38.            {
  39.                lblEtiqueta.ForeColor = Color.Red;
  40.            }
  41.        }
  42.  
  43.        string letra;
  44.    }
  45.  

Me gustaría llamar al método Form1_KeyPress() desde el método btnIniciar_Click(), no entiendo como podría pasar los argumentos (creo que se les denomina de ¨Control¨) desde ese punto.  Supongo que la solución sería parecida para implementar los métodos del Timer.


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: Comparar eventos de teclado con strings (C#)
« Respuesta #2 en: 8 Agosto 2019, 17:39 pm »

Me gustaría llamar al método Form1_KeyPress() desde el método btnIniciar_Click(), no entiendo como podría pasar los argumentos (creo que se les denomina de ¨Control¨) desde ese punto.

Hacer eso carecería de sentido, puesto que estarías llamando a un controlador de evento (método Form1_KeyPress) con datos de evento (clase KeyPressEventArgs) artificiales. Dicho de otra forma, estarías simulando una pulsación del teclado artificial en el Form, y no creo que realmente desees hacer eso...

Supongo que la solución sería parecida para implementar los métodos del Timer.

En realidad, la solución óptima y sofisticada sería utilizar la clase/componente BackgroundWorker para aplicar el método de invocación asincrónica en los controles de la interfaz de usuario. Pero como te veo con poca experiencia, y como tampoco se si esto que pides es para un trabajo de clase donde te pidan aplicar cosas más basicas, pues aquí tienes un ejemplo donde utilizo prácticas más básicas:



Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Threading;
  8. using System.Windows.Forms;
  9.  
  10. namespace WindowsFormsApp1 {
  11.  
  12.    public partial class Form1 : Form {
  13.  
  14.        private Random RNG = new Random(Environment.TickCount);
  15.  
  16.        private char nextChar;
  17.  
  18.        private bool isSuccess;
  19.        private int successCount;
  20.        private int failCount;
  21.  
  22.        public Form1() {
  23.           this.InitializeComponent();
  24.        }
  25.  
  26.        private void Form1_Load(object sender, EventArgs e) {
  27.            this.KeyPreview = true;
  28.        }
  29.  
  30.        private void btnIniciar_Click(object sender, EventArgs e) {
  31.  
  32.            this.Reset();
  33.  
  34.            Stopwatch watch = new Stopwatch();
  35.            watch.Start();
  36.  
  37.            while (watch.Elapsed <= TimeSpan.FromSeconds(3)) {
  38.                this.nextChar = this.GeneradorLetra("ABCDEFG".ToCharArray(), this.nextChar);
  39.                this.lblEtiqueta.Text = this.nextChar.ToString();
  40.  
  41.                while (!((this.isSuccess) || (watch.Elapsed >= TimeSpan.FromSeconds(3)))) {
  42.                    this.LabelStopWatch.Text = (3 - watch.Elapsed.Seconds).ToString();
  43.                    Application.DoEvents();
  44.                }
  45.  
  46.                if (this.isSuccess) {
  47.                    Thread.Sleep(500);
  48.                    this.successCount += 1;
  49.                } else {
  50.                    this.failCount += 1;
  51.                }
  52.                this.isSuccess = false;
  53.  
  54.                this.lblEtiqueta.ForeColor = Label.DefaultForeColor;
  55.                this.LabelSuccessful.Text = this.successCount.ToString();
  56.                this.LabelFailed.Text = this.failCount.ToString();
  57.  
  58.                watch.Restart();
  59.                Thread.CurrentThread.Join(0);
  60.            }
  61.  
  62.        }
  63.  
  64.        private void Form1_KeyPress(object sender, KeyPressEventArgs e) {
  65.  
  66.            if (!(this.isSuccess) && (char.ToLower(this.nextChar) == char.ToLower(e.KeyChar))) {
  67.                this.lblEtiqueta.ForeColor = Color.Green;
  68.                this.isSuccess = true;
  69.  
  70.            } else {
  71.                this.lblEtiqueta.ForeColor = Color.Red;
  72.  
  73.            }
  74.  
  75.        }
  76.  
  77.        private char GeneradorLetra(char[] charSet, char previousChar) {
  78.            IEnumerable<char> tmpCol = from char c in charSet
  79.                                       where (c != previousChar)
  80.                                       select c;
  81.            return tmpCol.ElementAtOrDefault(this.RNG.Next(0, tmpCol.Count()));
  82.        }
  83.  
  84.        private void Reset() {
  85.            this.successCount = 0;
  86.            this.failCount = 0;
  87.            this.LabelSuccessful.Text = this.successCount.ToString();
  88.            this.LabelFailed.Text = this.failCount.ToString();
  89.        }
  90.  
  91.    }
  92. }
  93.  

Código original escrito en VB.NET:
Código
  1. Imports System.Threading
  2.  
  3. Public Class Form1
  4.  
  5.    Private RNG As New Random(Environment.TickCount)
  6.  
  7.    Private nextChar As Char
  8.  
  9.    Private isSuccess As Boolean
  10.    Private successCount As Integer
  11.    Private failCount As Integer
  12.  
  13.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  14.        Me.KeyPreview = True
  15.    End Sub
  16.  
  17.    Private Sub btnIniciar_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnIniciar.Click
  18.  
  19.        Me.Reset()
  20.  
  21.        Dim watch As New Stopwatch()
  22.        watch.Start()
  23.  
  24.        Do While (watch.Elapsed <= TimeSpan.FromSeconds(3))
  25.            Me.nextChar = Me.GeneradorLetra("ABCDEFG".ToCharArray(), Me.nextChar)
  26.            Me.lblEtiqueta.Text = Me.nextChar
  27.  
  28.            Do Until (Me.isSuccess) OrElse (watch.Elapsed >= TimeSpan.FromSeconds(3))
  29.                Me.LabelStopWatch.Text = CStr(3 - watch.Elapsed.Seconds)
  30.                Application.DoEvents()
  31.            Loop
  32.  
  33.            If (Me.isSuccess) Then
  34.                Thread.Sleep(500)
  35.                Me.successCount += 1
  36.            Else
  37.                Me.failCount += 1
  38.            End If
  39.            Me.isSuccess = False
  40.  
  41.            Me.lblEtiqueta.ForeColor = Label.DefaultForeColor
  42.            Me.LabelSuccessful.Text = CStr(Me.successCount)
  43.            Me.LabelFailed.Text = CStr(Me.failCount)
  44.  
  45.            watch.Restart()
  46.            Thread.CurrentThread.Join(0)
  47.        Loop
  48.  
  49.    End Sub
  50.  
  51.    Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
  52.  
  53.        If Not (Me.isSuccess) AndAlso (Char.ToLower(Me.nextChar) = Char.ToLower(e.KeyChar)) Then
  54.            Me.lblEtiqueta.ForeColor = Color.Green
  55.            Me.isSuccess = True
  56.  
  57.        Else
  58.            Me.lblEtiqueta.ForeColor = Color.Red
  59.  
  60.        End If
  61.  
  62.    End Sub
  63.  
  64.    Private Function GeneradorLetra(charSet As Char(), previousChar As Char) As Char
  65.        Dim tmpCol As IEnumerable(Of Char) = From c As Char In charSet Where (c <> previousChar)
  66.        Return tmpCol(Me.RNG.Next(0, tmpCol.Count))
  67.    End Function
  68.  
  69.    Private Sub Reset()
  70.  
  71.        Me.successCount = 0
  72.        Me.failCount = 0
  73.        Me.LabelSuccessful.Text = CStr(Me.successCount)
  74.        Me.LabelFailed.Text = CStr(Me.failCount)
  75.  
  76.    End Sub
  77.  
  78. End Class

Puedes trasladar parte del código a un Timer si lo prefieres para evitar el búcle o llamada bloqueante junto a la llamada Application.DoEvents(), pero para ponerte a usar un Timer sería más eficiente que apliques el uso de la clase BackgroundWorker como ya mencioné.

Caracterísiticas del código/programa de arriba:
- Cuando el usuario presiona la tecla que imprime el caracter correcto, se visualiza en verde durante 500 ms y seguidamente se muestra el siguiente caracter.
- Se considera un fallo solamente si la cuenta atrás llega a 0 sin que el usuario haya conseguido presionar la tecla que imprime el caracter correcto, indiferentemente de la cantidad de fallos que el usuario haya tenido durante la cuenta atrás. Dicho de otra forma, se permiten fallos "infinitos" de pulsación de tecla durante la cuenta atrás.
- La aleatoriedad de muestra de caracteres consiste en que el caracter actual nunca se repetirá en la siguiente "prueba", pero si que podrá volver a mostrarse en las "pruebas" posteriores a esta.

Todo esto es así, por que tampoco especificaste como se supone que debe funcionar exactamente el programa. Pero ya con ese código puedes modificarlo para tus requisitos.

Saludos.
« Última modificación: 8 Agosto 2019, 21:52 pm por Eleкtro » En línea



Alejovsq

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Comparar eventos de teclado con strings (C#)
« Respuesta #3 en: 9 Agosto 2019, 01:34 am »

Es exactamente el funcionamiento que deseaba!!

No es para un trabajo de clase. Soy principiante y son ideas propias para ir practicando lo que ya he aprendido del lenguaje.

Tu respuesta ha sido excelente, tengo muchas cosas que estudiar y aprender de ella. Investigaré sobre la clase/componente BackgroundWorker.

Muchas gracias, Elektro!!!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Keylogger sin Eventos del teclado
Programación Visual Basic
hackper 1 2,198 Último mensaje 14 Diciembre 2005, 21:48 pm
por Slasher-K
comparar strings
Java
alexkof158 2 6,389 Último mensaje 7 Mayo 2008, 19:10 pm
por alexkof158
Como comparar cadenas de textos o Strings en Java
Java
soy_nicanor 2 2,316 Último mensaje 15 Febrero 2015, 23:02 pm
por Usuario Invitado
Diferenciar eventos según teclado C#
.NET (C#, VB.NET, ASP)
kondrag_X1 3 3,437 Último mensaje 22 Abril 2015, 15:50 pm
por kondrag_X1
Ayuda con eventos del teclado
Java
sebast345 3 2,542 Último mensaje 18 Noviembre 2016, 13:22 pm
por Orubatosu
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines