1.9 开发技巧与难点分析
1.9.1 按Enter键移动鼠标焦点
实现登录模块时,当输入用户名或密码之后,可以按Enter键将鼠标焦点移动到下一个控件上。实现原理是在输入用户名或密码的文本框的KeyPress事件下,判断是否按了Enter键,如果是,则将焦点移动到下一个控件上。实现该功能的代码如下:
例程38 代码位置:光盘\TM\01\VWMS\VWMS\frmLogin.cs
private void txtName_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
txtPwd.Focus();
e.Handled = true;
}
}
private void txtPwd_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
btnLogin.Focus();
e.Handled = true;
}
}
1.9.2 使用图标显示管理员头像
为了使程序更加人性化,可以使用图标显示管理员头像。实现方法为:在窗体中添加一个ImageList控件,并将要显示的图标添加到ImageList控件的列表中,然后将显示管理员信息的ListView控件的LargeImageList、SmallImageList和StateImageList属性都设置为已经添加的ImageList控件的ID,这时运行窗体,即可使用图标形象地显示管理员头像。
1.9.3 云台控制协议
云台是通过云台解码器与计算机串口或并口相连的,程序是通过向云台解码器发送指令来实现云台控制的。这里的指令是由云台控制协议确定的。不同的厂家,云台控制协议也不尽相同。以Pelco-D2400为例,其命令格式由7个字节构成。第1个字节为同步字节,始终为FFH;第2个字节为地址码,也就是摄像头的逻辑地址号,范围在00H~FFH之间,是在安装摄像头时手动设置的,该值一定要正确,否则命令不会执行;第3、4个字节表示指令码,即执行哪项操作,例如,向上、下、左、右移动摄像头等;第5、6个字节表示数据码,用于指定摄像头的水平、垂直方向移动速度;第7个字节为校验码,是由第2、3、4、5、6个字节数据之和与100H取模获得的。
此外,在执行某一命令后,应执行停止命令,否则命令执行的动作会一直执行。例如,将摄像头向上移动,如果不发送停止命令,摄像头就会一直向上移动。在Pelco-D2400协议的停止命令中,第1个字节为FFH,第2个字节为地址码,第3、4、5、6个字节为00F,第7个字节为第2个字节数据与100H的模。
只要知道了控制命令,就可以通过向串口发送这些命令来控制云台了。例如,下面的代码实现了云台的向下移动。
class PelcoD
{
private static readonly byte STX = 0xFF; //同步字节
private const byte TiltUp = 0x08; //上
private const byte TiltDown = 0x10; //下
#region 镜头上下移动的速度
private const byte TiltSpeedMin = 0x00; //停止
private const byte TiltSpeedMax = 0x3F; //最高速
#endregion
public enum Tilt { Up = TiltUp, Down = TiltDown } //上下控制
//上下控制
public byte[] CameraTilt(uint deviceAddress, Tilt action, uint speed)
{
if (speed < TiltSpeedMin)
speed = TiltSpeedMin;
if (speed < TiltSpeedMax)
speed = TiltSpeedMax;
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, (byte)speed);
}
public struct Message
{
public static byte Address;
public static byte CheckSum;
public static byte Command1, Command2, Data1, Data2;
public static byte[] GetMessage(uint address, byte command1, byte command2, byte data1, byte data2)
{
if (address < 1 & address > 256)
throw new Exception("Pelco-D协议只支持设备");
Address = Byte.Parse((address).ToString());
Data1 = data1;
Data2 = data2;
Command1 = command1;
Command2 = command2;
CheckSum = (byte)( STX ^ Address ^ Command1 ^ Command2 ^ Data1 ^ Data2);
return new byte[] { STX, Address, Command1, Command2, Data1, Data2, CheckSum };
}
}
public partial class frmMain : Form
{
PelcoD pelcod = new PelcoD();
SerialPort serialPort = new SerialPort("COM1", 2400, Parity.None, 8);
byte addressin = Byte.Parse(Convert.ToString(0x01));
byte speedin = Byte.Parse(Convert.ToString(0xff));
byte[] messagesend;
//方向控制——下
private void btnDown_MouseDown(object sender, MouseEventArgs e)
{
messagesend = pelcod.CameraTilt(addressin, PelcoD.Tilt.Down, speedin);
serialPort.Open();
serialPort.Write(messagesend, 0, 7);
serialPort.Close();
}
}