using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using Lers;
using Lers.Poll;
namespace Vkt5_RemoteConsole
{
///
/// Делегат для события .
///
public delegate void WriteLogEventHandler(Importance importance, string message);
///
/// Контрол удалённого пульта ВКТ-5
///
public partial class Vkt5ConsoleControl : UserControl
{
///
/// Состояния контрола
///
private enum State
{
/// Начальное состояния
None,
/// Отключены от прибора
Disconnected,
/// Режим ожидания команд
Ready,
/// Чтение буфера экрана
ReadingScreenBuffer,
/// Отправка кода клавиши
SendingKeyCode,
/// Ожидание обновления буфера экрана
WaitingScreenBuffer
}
#region События и методы для протоколирования
public event WriteLogEventHandler WriteLog;
private void LogMessage(string msg)
{
if (this.WriteLog != null)
{
this.WriteLog(Importance.Info, msg);
}
}
private void LogWarning(string msg)
{
if (this.WriteLog != null)
{
this.WriteLog(Importance.Warn, msg);
}
}
private void LogError(string msg)
{
if (this.WriteLog != null)
{
this.WriteLog(Importance.Error, msg);
}
}
#endregion
///
/// Конструктор
///
public Vkt5ConsoleControl()
{
InitializeComponent();
SetState(State.Disconnected);
}
///
/// Инициализация контрола
///
///
///
public void Initialize(RemoteConsole remoteConsole, int networkAddress)
{
this.vktConsole = new Vkt5Console(remoteConsole);
this.vktConsole.WriteLog += this.WriteLog;
this.vktConsole.RequestError += new EventHandler(vktConsole_RequestError);
this.vktConsole.NetworkAddress = networkAddress;
}
///
/// Изменилось состояние подключения к удалённому устройству
///
///
public void ConnectionChanged(bool connected)
{
if (connected)
{
SetState(State.WaitingScreenBuffer);
this.vktConsole.Reset();
ReadScreenBuffer();
}
else
{
SetState(State.Disconnected);
}
}
#region Обработчики событий контролов
private void cursorTimer_Tick(object sender, EventArgs e)
{
this.displayCursor = !this.displayCursor;
RefreshCursor();
}
///
/// Таймер обновления содержимого экрана
///
///
///
private void refreshTimer_Tick(object sender, EventArgs e)
{
ReadScreenBuffer();
}
void vktConsole_RequestError(object sender, EventArgs e)
{
// Отменяем чтение
SetState(State.Ready);
}
private void btnUp_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Up);
}
private void btnDown_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Down);
}
private void btnTab_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Tab);
}
private void btnBack_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Back);
}
private void btnRight_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Right);
}
private void btnLeft_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Left);
}
private void btnEnter_Click(object sender, EventArgs e)
{
SendKeyCode(Vkt5Key.Enter);
}
private void btnMenu_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!this.btnMenu.Enabled)
{
return;
}
this.isMenuBtnDown = true;
this.menuBtnPressTime = DateTime.Now;
}
private void btnMenu_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!this.btnMenu.Enabled)
{
return;
}
if (this.isMenuBtnDown)
{
this.isMenuBtnDown = false;
DateTime now = DateTime.Now;
int totalMs = (int)(now - this.menuBtnPressTime).TotalMilliseconds;
if (totalMs >= 3000)
{
SendKeyCode(Vkt5Key.LongMenuPress);
}
else
{
SendKeyCode(Vkt5Key.Menu);
}
}
}
#endregion
private void ReadScreenBuffer()
{
if (this.state == State.Ready || this.state == State.WaitingScreenBuffer)
{
SetState(State.ReadingScreenBuffer);
this.vktConsole.ReadScreenBuffer(this.ReadScreenBufferCallback);
}
}
private void ReadScreenBufferCallback(byte[] data)
{
if (this.state != State.SendingKeyCode)
{
// Буфер экрана считан. Выставим состояние "Ready", если он пришёл не во время отправки кода клавиши.
SetState(State.Ready);
}
this.displayLine = Encoding.GetEncoding(866).GetString(data, 0, data.Length - 1);
this.cursorPos = data[data.Length - 1];
RefreshCursor();
if (!this.cursorTimer.Enabled)
{
this.cursorTimer.Start();
}
if (!this.refreshTimer.Enabled)
{
this.refreshTimer.Start();
}
}
private void SendKeyCode(Vkt5Key keyCode)
{
if (this.state == State.Disconnected || this.state == State.SendingKeyCode)
{
return;
}
SetState(State.SendingKeyCode);
this.vktConsole.SendKeyCode(keyCode, SendKeyCodeCallback);
}
private void SendKeyCodeCallback(byte[] data)
{
SetState(State.WaitingScreenBuffer);
ReadScreenBuffer();
}
///
/// Устанавливает новое состояние контрола
///
///
private void SetState(State newState)
{
if (newState == this.state)
{
return;
}
switch (newState)
{
case State.Ready:
SetReady();
break;
case State.Disconnected:
SetDisconnected();
break;
case State.SendingKeyCode:
case State.WaitingScreenBuffer:
EnableButtons(false);
break;
case State.ReadingScreenBuffer:
break;
}
this.state = newState;
}
private void SetReady()
{
EnableButtons(true);
}
private void SetDisconnected()
{
this.cursorTimer.Stop();
this.displayLine = "";
this.cursorPos = 0;
}
private void RefreshCursor()
{
if (string.IsNullOrEmpty(this.displayLine))
{
return;
}
string cursorChar = "\u2588";
string showLine = this.displayLine;
if (showLine.Length > 0 && cursorPos < showLine.Length && this.displayCursor)
{
showLine = showLine
.Remove(this.cursorPos, 1)
.Insert(this.cursorPos, cursorChar);
}
this.txtLine1.Text = showLine.Substring(0, 16);
this.txtLine2.Text = showLine.Substring(16, 16);
}
private void EnableButtons(bool enable)
{
this.btnUp.Enabled = enable;
this.btnDown.Enabled = enable;
this.btnLeft.Enabled = enable;
this.btnRight.Enabled = enable;
this.btnEnter.Enabled = enable;
this.btnBack.Enabled = enable;
this.btnMenu.Enabled = enable;
this.btnTab.Enabled = enable;
}
///
/// Объект для работы с подключенным ECL 300
///
private Vkt5Console vktConsole = null;
///
/// Текущее состояние контрола
///
private State state = State.None;
private string displayLine = "";
private int cursorPos = 0;
private bool displayCursor = false;
private bool isMenuBtnDown = false;
private DateTime menuBtnPressTime = DateTime.MinValue;
}
}