2.1添加“假通道” 概述:完成一些列初始化登陆之后,EventHandle 会被触发从而使用委托的方式,完成一系列的动作。对于委托,可以这样理解(见下面的标注):
EventHandle.cs 的代码,以下均是:
public EventHandler()
{
//dialog_OnDialogEvent,我 EventHandle 把下述职责委托于你,使得你负责处理 BVCU_Dialog_OnDialogEvent的所有事件,处理好了向某个人交代。某个人指的是,真正需要处理该事件的方法,处理好了只有在运行时才能决定。
……略过原有代码
//该处是我添加的用于处理串口事件、接收数据的两个委托
BVCU_TspDialog_OnEvent(TspDialog_OnEvent);
tspDialog_OnData = new BVCU_TspDialog_OnData(TspDialog_OnData);
……略过原有代码
//该处是原有代码,但是在委托给 Cmd_OnGetPuList之后,被委托方使用 Cmd_OnGetPuList(注意区分大小写)的过程中是我修改的代码,添加了“假通道”
cmd_OnGetPuList = new BVCU_Cmd_OnGetPuList(Cmd_OnGetPuList);
……略过原有代码
}
Cmd_OnGetPuList 如何添加“假通道”的(因为我只判断了小写的“gps”,所以 PU 列表中只有包含小写的“gps”通道才会被添加“TSP”通道):
/*
* Get Pu List
*/
public BVCU_Cmd_OnGetPuList cmd_OnGetPuList;
voidCmd_OnGetPuList(IntPtr session, IntPtr ptPuId, IntPtrptPuName, int iStatus, refBVCU_PUOneChannelInfo channel, int iFinished)
{
stringpuId = Marshal.PtrToStringAnsi(ptPuId, BVCU.BVCU_MAX_ID_LEN + 1).Split('\0')[0];
stringpuName = Marshal.PtrToStringAnsi(ptPuName, BVCU.BVCU_MAX_NAME_LEN + 1).Split('\0')[0];
if(BVCU.TRUE(iFinished))
{
m_session.OnGetPuListFinished();
}
Session.Channel chnl = newSession.Channel();
if(iStatus == BVCU.BVCU_ONLINE_STATUS_OFFLINE)
{
chnl.online = false;
}
else
{
chnl.online = true;
}
getChannel(chnl, channel);
m_session.OnGetPu(puName, puId,chnl);
if(channel.szName.Equals("gps"))
{
// 假通道,用于串口测试,这里我只判断了小写的 gps,因为 PU_2740 底下的 gps 是小写的,我所要测试的透明串口就是 PU_2740,如果有变更需要,只需手动修改 if 条件即可
chnl = newSession.Channel();
channel.szName = "TSP";
channel.iPTZIndex = 15;
channel.iMediaDir = 32;
channel.iChannelIndex = 65792;
if(iStatus == BVCU.BVCU_ONLINE_STATUS_OFFLINE)
{
chnl.online = false;
}
else
{
chnl.online = true;
}
getChannel(chnl, channel);
m_session.OnGetPu(puName, puId,chnl);
}
}
2.2分别打开 GPS 或TSP该代码位于Form1.cs中,其中 m_sdkOperator.Dialog.openTspDialog(pu,channelNo) 语句用到的 openTspDialog里面调用了 BVCU.cs 中的 DllImport 的 ManagedLayer_CuOpenTspDialog,参见BVCU.cs:
[DllImport("ManagedLayer.dll", CallingConvention = CallingConvention.Cdecl)]publicstatic extern int ManagedLayer_CuOpenTspDialog(IntPtr handle, refIntPtr dialog, IntPtrsession, Byte[] puId, int channelNo,
EventHandler.BVCU_TspDialog_OnEvent onDlgEvent, EventHandler.BVCU_TspDialog_OnDataonDlgData);
以下代码位于Form1.cs中:
/*
* 双击界面上的资源树打开对话
*/
const int TREE_LEVEL_SESSION = 0;
const int TREE_LEVEL_PU = 1;
const int TREE_LEVEL_CHANNEL = 2;
privatevoid treeViewResList_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgse)
{
……略过已有代码,else if 是修改的代码,只修改了 if 条件
elseif (channelNo >= BVCU.BVCU_SUBDEV_INDEXMAJOR_MIN_GPS&& channelNo < BVCU.BVCU_SUBDEV_INDEXMAJOR_MAX_GPS)
{
……未修改
}
//此处为添加的代码
else
{
if(m_sdkOperator.Dialog.openTspDialog(pu, channelNo) == 0)
{
ListViewItem item = new ListViewItem();
item.Text = pu.id;
item.Tag = channelNo;
ListViewItem.ListViewSubItemTspData = new ListViewItem.ListViewSubItem();
ListViewItem.ListViewSubItemlen = new ListViewItem.ListViewSubItem();
item.SubItems.AddRange(new ListViewItem.ListViewSubItem[] { TspData, len });
listViewGPSData.Items.Add(item);
}
}
}
}
openTspDialog 位于 Dialog.cs 中:
ArrayList m_tspDialogs;
public int openTspDialog(Session.Pu pu, intchannelNo)
{
foreach(OneDialog dlg inm_tspDialogs)
{
if(dlg.pu.id.Equals(pu.id, StringComparison.CurrentCultureIgnoreCase)
&& dlg.channelNo ==channelNo)
{
return-1;
}
}
IntPtrdialog = IntPtr.Zero;
//此处为调用的 ManagedLayer_CuOpenTspDialog
if(BVCU.ManagedLayer_CuOpenTspDialog(m_bvsdkHandle,ref dialog, m_session.Handle, Encoding.UTF8.GetBytes(pu.id),
channelNo,m_bvsdkEventHandler.tspDialog_OnEvent, m_bvsdkEventHandler.tspDialog_OnData)
== BVCU.BVCU_RESULT_S_OK)
{
OneDialogdlg = new OneDialog();
dlg.dialogHandle = dialog;
dlg.channelNo = channelNo;
dlg.pu = pu;
m_tspDialogs.Add(dlg);
return0;
}
return-1;
}
2.3 m_bvsdkEventHandler.tspDialog_OnEvent/ tspDialog_OnData回调 EventHandle.cs中:
public delegate void BVCU_TspDialog_OnEvent(IntPtrdialog, int eventCode, Int32errorCode);
public delegate void BVCU_TspDialog_OnData(IntPtrdialog, string pTspData, int len);
public BVCU_TspDialog_OnData tspDialog_OnData;
public BVCU_TspDialog_OnEvent tspDialog_OnEvent;
voidTspDialog_OnEvent(IntPtr dialog, int eventCode, Int32errorCode)
{
if(errorCode != BVCU.BVCU_RESULT_S_OK)
{
m_dialog.onTspDialogOpenFailed(dialog);
}
}
voidTspDialog_OnData(IntPtr dialog, string pTspData, intlen)
{
//以下在 Dialog.cs 中
m_dialog.onTspData(dialog,pTspData, len);
}
Dialog.cs 中:
delegate void OnGetTspData(IntPtr dialog, stringpTspData, int len);
OnGetTspDatadeleGetTspData;
public void onTspData(IntPtrdialog, string pTspData, int len)
{
if(null == deleGetTspData)
{
deleGetTspData = new OnGetTspData(procGetTspData);
}
m_mainForm.BeginInvoke(deleGetTspData, newobject[] { dialog, pTspData, len });
}
voidprocGetTspData(IntPtr dialog, string pTspData, intlen)
{
foreach (OneDialog dlg inm_tspDialogs)
{
if(dlg.dialogHandle == dialog)
{
m_mainForm.onGetTspData(dlg.pu.id, pTspData, len);
return;
}
}
}
2.4显示 TSPForm1.cs中:
public void onGetTspData(string puId, string pTspData, int len)
{
foreach(ListViewItem item inlistViewGPSData.Items)
{
if(item.Text.Equals(puId, StringComparison.CurrentCultureIgnoreCase))
{
ListViewItem.ListViewSubItem TspData = newListViewItem.ListViewSubItem();
TspData.Text = pTspData;
item.SubItems[1] = TspData;
ListViewItem.ListViewSubItem length = newListViewItem.ListViewSubItem();
length.Text =len.ToString();
item.SubItems[2] = length;
return;
}
}
}
2.5底层支持载入的 ManagedLayer_CuOpenTspDialog 位于工程 ManagedLayer.cpp 中,我在里面添加了这个函数,具体请参考工程代码,ManagedLayer_CuOpenTspDialog 调用了 CBVCU.cpp 中的 openTspDialog,openTspDialog 指定了 dlgParam.OnEvent = tspDialog_OnEvent; 和 dlgParam.afterDecode = tspDialog_OnData; 作为 Tsp 的事件回调和解码回调,这两个回调定义于 CBVCU.cpp 中。
intCBVCU:penTspDialog(BVCU_HDialog* dlg, BVCU_HSession session, char* puId, intchannelNo, BVCU_TspDialog_OnEventonDlgEvent, BVCU_TspDialog_OnData onDlgData)
{
BVCU_DialogParamdlgParam;
BVCU_DialogControlParamdlgCtlParam;
memset(&dlgParam,0, sizeof(dlgParam));
memset(&dlgCtlParam,0, sizeof(dlgCtlParam));
dlgParam.iSize= sizeof(dlgParam);
dlgCtlParam.iSize= sizeof(dlgCtlParam);
dlgParam.hSession= session;
BVCU_DialogTargettarget;
strncpy_s(target.szID,BVCU_MAX_ID_LEN+1,puId,_TRUNCATE);
// memset(&target,0, sizeof(BVCU_DialogTarget));
target.iIndexMajor= channelNo;
// strcpy_s(target.szID,BVCU_MAX_ID_LEN + 1, puId);
target.iIndexMinor= -1;
dlgParam.iTargetCount= 1;
dlgParam.pTarget= ⌖
dlgParam.iAVStreamDir= BVCU_MEDIADIR_DATARECV;
dlgParam.OnEvent= tspDialog_OnEvent;
dlgParam.afterDecode= tspDialog_OnData;
if (NULL == m_procGpsDialogEvent)
{
m_procTspDialogEvent= onDlgEvent;
}
if (NULL == m_procGpsDialogOnData)
{
m_procTspDialogOnData= onDlgData;
}
// <TODO>: 参考MLibBVCU.cpp
return BVCU_Dialog_Open(dlg, &dlgParam,&dlgCtlParam);
}
总结:有了MFCDemo例程,其他的都不是很难,只需仿照就行了。