1.9 開(kāi)發(fā)技巧與難點(diǎn)分析
1.9.1 按Enter鍵移動(dòng)鼠標(biāo)焦點(diǎn)
實(shí)現(xiàn)登錄模塊時(shí),當(dāng)輸入用戶名或密碼之后,可以按Enter鍵將鼠標(biāo)焦點(diǎn)移動(dòng)到下一個(gè)控件上。實(shí)現(xiàn)原理是在輸入用戶名或密碼的文本框的KeyPress事件下,判斷是否按了Enter鍵,如果是,則將焦點(diǎn)移動(dòng)到下一個(gè)控件上。實(shí)現(xiàn)該功能的代碼如下:
例程38 代碼位置:光盤(pán)\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 使用圖標(biāo)顯示管理員頭像
為了使程序更加人性化,可以使用圖標(biāo)顯示管理員頭像。實(shí)現(xiàn)方法為:在窗體中添加一個(gè)ImageList控件,并將要顯示的圖標(biāo)添加到ImageList控件的列表中,然后將顯示管理員信息的ListView控件的LargeImageList、SmallImageList和StateImageList屬性都設(shè)置為已經(jīng)添加的ImageList控件的ID,這時(shí)運(yùn)行窗體,即可使用圖標(biāo)形象地顯示管理員頭像。
1.9.3 云臺(tái)控制協(xié)議
云臺(tái)是通過(guò)云臺(tái)解碼器與計(jì)算機(jī)串口或并口相連的,程序是通過(guò)向云臺(tái)解碼器發(fā)送指令來(lái)實(shí)現(xiàn)云臺(tái)控制的。這里的指令是由云臺(tái)控制協(xié)議確定的。不同的廠家,云臺(tái)控制協(xié)議也不盡相同。以Pelco-D2400為例,其命令格式由7個(gè)字節(jié)構(gòu)成。第1個(gè)字節(jié)為同步字節(jié),始終為FFH;第2個(gè)字節(jié)為地址碼,也就是攝像頭的邏輯地址號(hào),范圍在00H~FFH之間,是在安裝攝像頭時(shí)手動(dòng)設(shè)置的,該值一定要正確,否則命令不會(huì)執(zhí)行;第3、4個(gè)字節(jié)表示指令碼,即執(zhí)行哪項(xiàng)操作,例如,向上、下、左、右移動(dòng)攝像頭等;第5、6個(gè)字節(jié)表示數(shù)據(jù)碼,用于指定攝像頭的水平、垂直方向移動(dòng)速度;第7個(gè)字節(jié)為校驗(yàn)碼,是由第2、3、4、5、6個(gè)字節(jié)數(shù)據(jù)之和與100H取模獲得的。
此外,在執(zhí)行某一命令后,應(yīng)執(zhí)行停止命令,否則命令執(zhí)行的動(dòng)作會(huì)一直執(zhí)行。例如,將攝像頭向上移動(dòng),如果不發(fā)送停止命令,攝像頭就會(huì)一直向上移動(dòng)。在Pelco-D2400協(xié)議的停止命令中,第1個(gè)字節(jié)為FFH,第2個(gè)字節(jié)為地址碼,第3、4、5、6個(gè)字節(jié)為00F,第7個(gè)字節(jié)為第2個(gè)字節(jié)數(shù)據(jù)與100H的模。
只要知道了控制命令,就可以通過(guò)向串口發(fā)送這些命令來(lái)控制云臺(tái)了。例如,下面的代碼實(shí)現(xiàn)了云臺(tái)的向下移動(dòng)。
class PelcoD
{
private static readonly byte STX = 0xFF; //同步字節(jié)
private const byte TiltUp = 0x08; //上
private const byte TiltDown = 0x10; //下
#region 鏡頭上下移動(dòng)的速度
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協(xié)議只支持設(shè)備");
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();
}
}