Ayuda timer en C#

Iniciado por KiddKeo, 1 Julio 2018, 12:38 PM

0 Miembros y 1 Visitante están viendo este tema.

KiddKeo

Hola buenas, tengo tres timers, uno en false y los otros dos en true.
Estoy intentando hacer para que cuando presione el F1 el timer1 se active, y al soltar la tecla este se desactive.
He logrado hacer que se active y desactive pero tengo que pulsar dos veces el F1, esa no es la idea.
Aquí adjunto el código.
        private void timer3_Tick(object sender, EventArgs e)
        {
            if (GetAsyncKeyState(Keys.F1) == -32767)
            {
                if(timer1.Enabled == false)
                {
                    timer1.Start();
                }
                else
                {
                    timer1.Enabled = false;
                    timer1.Stop();
                }
            }
        }

Eleкtro

#1
Imagino que quieres poder pulsar la tecla F1 fuera de la aplicación y que se procese en tu programa, de lo contrario si solo quieres que la tecla se procese cuando haces click en la interfaz de usuario de la aplicación entonces es más que suficiente con suscribirse a los eventos Form.KeyDown y Form.KeyUp.

En cualquier caso es innecesario el uso directo de código nativo / llamar a las funciones de la API de Windows, en su lugar puedes usar código administrado expuesto en los miembros la librería de clases de WPF, y aunque estés en Windows Forms (como parece ser el caso). Aquí te muestro la solución:

Código (csharp) [Seleccionar]
using System;
using System.Windows.Forms;

using System.Windows.Input;
using WpfKey = System.Windows.Input.Key;

namespace WindowsFormsApp1 {

   public partial class Form1 : Form {

       public Form1() {
           this.InitializeComponent();
       }

       private void Timer1_Tick(object sender, EventArgs e) {
           Console.WriteLine("timer1 has ticked...");
       }

       private void Timer3_Tick(object sender, EventArgs e) {

           KeyStates keyState = Keyboard.GetKeyStates(WpfKey.F1);

           if (keyState.HasFlag(KeyStates.Down)) {
               if (!(this.Timer1.Enabled)) {
                   this.Timer1.Enabled = true;
                   this.Timer1.Start();
               }

           } else {
               if (this.Timer1.Enabled) {
                   this.Timer1.Stop();
                   this.Timer1.Enabled = false;
               }

           }

       }

   }

}


PD: en tu proyecto debes añadir una referencia al ensamblado WindowsBase.dll y PresentationCore.dll para poder importar y usar los namespaces de WPF.

Espero que te haya servido de ayuda.

Saludos!








KiddKeo

Cita de: Eleкtro en  1 Julio 2018, 14:10 PM
Imagino que quieres poder pulsar la tecla F1 fuera de la aplicación y que se procese en tu programa, de lo contrario si solo quieres que la tecla se procese cuando haces click en la interfaz de usuario de la aplicación entonces es más que suficiente con suscribirse a los eventos Form.KeyDown y Form.KeyUp.

En cualquier caso es innecesario el uso directo de código nativo / llamar a las funciones de la API de Windows, en su lugar puedes usar código administrado expuesto en los miembros la librería de clases de WPF, y aunque estés en Windows Forms (como parece ser el caso). Aquí te muestro la solución:

Código (csharp) [Seleccionar]
using System;
using System.Windows.Forms;

using System.Windows.Input;
using WpfKey = System.Windows.Input.Key;

namespace WindowsFormsApp1 {

   public partial class Form1 : Form {

       public Form1() {
           this.InitializeComponent();
       }

       private void Timer1_Tick(object sender, EventArgs e) {
           Console.WriteLine("timer1 has ticked...");
       }

       private void Timer3_Tick(object sender, EventArgs e) {

           KeyStates keyState = Keyboard.GetKeyStates(WpfKey.F1);

           if (keyState.HasFlag(KeyStates.Down)) {
               if (!(this.Timer1.Enabled)) {
                   this.Timer1.Enabled = true;
                   this.Timer1.Start();
               }

           } else {
               if (this.Timer1.Enabled) {
                   this.Timer1.Stop();
                   this.Timer1.Enabled = false;
               }

           }

       }

   }

}


PD: en tu proyecto debes añadir una referencia al ensamblado WindowsBase.dll y PresentationCore.dll para poder importar y usar los namespaces de WPF.

Espero que te haya servido de ayuda.

Saludos!

Muchas gracias, por tu ayuda.
He añadido las referencias que nombraste y las librerías se han añadido correctamente, el problema es que me muestra errores de compilación. Aquí la lista:

Aquí el código que estoy intentando compilar:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows.Input;
using WpfKey = System.Windows.Input.Key;


namespace TestClic
{
    public partial class Form1 : Form
    {

        private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const int MOUSEEVENTF_LEFTUP = 0x0004;
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(int dwflags, int dx, int dy, int cbuttons, int dwExtraInfo);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetCursorPos(out Point lpPoint);
        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Keys vkeys);
        public static int xPos, yPos;

        public Form1()
        {
            this.InitializeComponent();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (GetAsyncKeyState(Keys.F3) == -32767)
            {
                Point cursor = new Point();
                GetCursorPos(out cursor);
                xPos = cursor.X;
                yPos = cursor.Y;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Point newPoint = new Point();
            GetCursorPos(out newPoint);
            int x = newPoint.X;
            int y = newPoint.Y;
            Cursor.Position = new Point(xPos, yPos);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            Cursor.Position = new Point(x, y);
        }

        private void timer3_Tick(object sender, EventArgs e)
        {
            KeyStates state = Keyboard.GetKeyStates(WpfKey.F1);

            if (state.HasFlag(KeyStates.Down))
            {
                if (!(this.timer1.Enabled))
                {
                    this.timer1.Enabled = true;
                    this.timer1.Start();
                }

            }
            else
            {
                if (this.timer1.Enabled)
                {
                    this.timer1.Stop();
                    this.timer1.Enabled = false;
                }
            }
        }
    }
}

Eleкtro

#3
Los errores que mencionas no tienen que ver con el código que te mostré...

Para solucionar el primer y segundo error:
Código (csharp) [Seleccionar]
using Cursor = System.Windows.Forms.Cursor;
( o bien escribe el namespace completo en las lineas donde se te marca el error )

El tercer (y último) error directamente no te debería ocurrir, asegúrate de que tienes una referencia añadida el ensamblado System.dll (que es la libreria que contiene la función Enum.HasFlag) aunque por supuesto debes tenerla añadida por que de lo contrario tendrías gran cantidad de errores de definiciones de tipos no encontrados... como ya digo ese error en principio no te debería estar ocurriendo, revisa que todas las referencias estén bien.

Saludos