-2

I have a Main_Form_Keydown and Keyup function to control a robot with my keyboard. The problem is that if I lose focus of the mainform window I cannot control the robot anymore unless I focus it again and it's a problem because I might crash the robot while doing it.

Any ideas how I can improve my code?

      public void Main_Form_KeyDown(object sender, KeyEventArgs e) //Controlo do drone com o teclado
    {
        switch (e.KeyCode) //Controlo pelo Teclado
        {
            case Keys.F:
                _droneClient.FlatTrim();
                break;
            case Keys.Back:
                if (!isSensitiveMode)
                {
                    flightSensitivityConst = 0.25f;
                    isSensitiveMode = true;
                }
                else
                {
                    flightSensitivityConst = 0.9f;
                    isSensitiveMode = false;
                }
                break;
            case Keys.W:
                _droneClient.Progress(FlightMode.Progressive, pitch: -flightSensitivityConst);
                break;
            case Keys.S:
                _droneClient.Progress(FlightMode.Progressive, pitch: +flightSensitivityConst);
                break;
            case Keys.A:
                _droneClient.Progress(FlightMode.Progressive, roll: -flightSensitivityConst);
                break;
            case Keys.D:
                _droneClient.Progress(FlightMode.Progressive, roll: +flightSensitivityConst);
                break;
            case Keys.I:
                _droneClient.Progress(FlightMode.Progressive, gaz: +flightSensitivityConst);
                break;
            case Keys.K:
                _droneClient.Progress(FlightMode.Progressive, gaz: -flightSensitivityConst);
                break;
            case Keys.J:
                _droneClient.Progress(FlightMode.Progressive, yaw: -flightSensitivityConst);
                break;
            case Keys.L:
                _droneClient.Progress(FlightMode.Progressive, yaw: +flightSensitivityConst);
                break;
            case Keys.E:
                _droneClient.Takeoff();
                break;
            case Keys.Q:
                _droneClient.Emergency();
                break;
            case Keys.Space:
                _droneClient.Land();
                break;
            //FLIPS
            case Keys.P:
                _settings.Control.FlightAnimation = new FlightAnimation(FlightAnimationType.FlipLeft);
                _droneClient.Send(_settings);
                //FLIP
                break;
            case Keys.O:
                _settings.Control.FlightAnimation = new FlightAnimation(FlightAnimationType.FlipRight);
                _droneClient.Send(_settings);
                //FLIP
                break;
            case Keys.Y:
                _settings.Control.FlightAnimation = new FlightAnimation(FlightAnimationType.FlipBehind);
                _droneClient.Send(_settings);
                break;
            case Keys.U:
                _settings.Control.FlightAnimation = new FlightAnimation(FlightAnimationType.FlipAhead);
                _droneClient.Send(_settings);
                break;
            case Keys.C:
                var configuration = new Settings();
                configuration.Video.Channel = VideoChannelType.Next;
                _droneClient.Send(configuration);
                break;
            case Keys.R:
                string path = string.Format("ttu_flight_{0:yyyy_MM_dd_HH_mm}" + ARDroneTrackFileExt, DateTime.Now);
                using (var dialog = new SaveFileDialog { DefaultExt = ARDroneTrackFileExt, Filter = ARDroneTrackFilesFilter, FileName = path })
                {
                    if (dialog.ShowDialog(this) == DialogResult.OK)
                    {
                        StopRecording();

                        _recorderStream = new FileStream(dialog.FileName, FileMode.OpenOrCreate);
                        _packetRecorderWorker = new PacketRecorder(_recorderStream);
                        _packetRecorderWorker.Start();
                    }
                }
                break;
        }
    } //Controlo do drone através do teclado

    private void Main_Form_KeyUp(object sender, KeyEventArgs e) //Se nao estiver a ser comandado pelo teclado
    {
        _droneClient.Hover(); //Fica pairado
    }

I was thinking to use a normal function on a timer but it will be missing KeyEventArgs e

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • Handle the `LostFocus` event and stop the robot from moving? Or make your form modal. – Broots Waymb Nov 22 '16 at 17:40
  • That's what keyup is doing. If I press it it changes the command to the robot. If I let it go the robot stops. The problem is that I want to control the robot all the time without losing focus. – Maurício Vilarinho Nov 22 '16 at 17:41
  • If you don't want to lose focus, make it modal. And your KeyIUp will not save you if you lose focus before you can trigger it. – Broots Waymb Nov 22 '16 at 17:43
  • It is almost impossible to guarantee you won't lost the focus... if there is any chance that the user or the system bring up another application. Thus, you cannot rely that you would always get a key-up if while the key is down you start another application with the mouse for example. – Phil1970 Dec 13 '16 at 20:29

1 Answers1

0

Use a global key hook. This will also capture the keys when your window does not have the focus (see: http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook or Global keyboard capture in C# application).

Alternatively, you could capture the LostFocus event of your form and then interrupt the program until the form gets focused again.

Community
  • 1
  • 1
NikxDa
  • 4,137
  • 1
  • 26
  • 48