📄 tvcdemodlg.cpp
字号:
// TvcDemoDlg.cpp : implementation file
//
#include "stdafx.h"
#include "TvcDemo.h"
#include "TvcDemoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTvcDemoDlg dialog
CTvcDemoDlg::CTvcDemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTvcDemoDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTvcDemoDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTvcDemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTvcDemoDlg)
DDX_Control(pDX, IDC_LIST_Channel, m_wndList);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTvcDemoDlg, CDialog)
//{{AFX_MSG_MAP(CTvcDemoDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_BN_CLICKED(ID_BUTTON_LoadDrv, OnBUTTONLoadDrv)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTvcDemoDlg message handlers
BOOL CTvcDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_wndList.SetExtendedStyle(m_wndList.GetExtendedStyle() | LVS_EX_FULLROWSELECT|LVS_SORTASCENDING|LVS_TYPEMASK);
m_wndList.InsertColumn(COL_CHANNEL, "通道", LVCFMT_RIGHT, 20);
m_wndList.InsertColumn(COL_MODULE, "类型", LVCFMT_LEFT, 60);
m_wndList.InsertColumn(COL_CALLCODE, "分机号", LVCFMT_LEFT, 40);
m_wndList.InsertColumn(COL_STATUE, "状态", LVCFMT_LEFT, 120);
m_wndList.InsertColumn(COL_DTMFSTR, "Dtmf接收", LVCFMT_LEFT, 100);
m_wndList.InsertColumn(COL_POLVOL, "电压", LVCFMT_LEFT, 38);
m_wndList.InsertColumn(COL_CALLER, "主叫", LVCFMT_LEFT, 100);
m_wndList.InsertColumn(COL_RECTIME, "录音时间", LVCFMT_LEFT, 60);
m_wndList.InsertColumn(COL_RECBYTE, "录音字节", LVCFMT_LEFT, 60);
m_wndList.InsertColumn(COL_PLYTIME, "放音时间", LVCFMT_LEFT, 60);
m_wndList.InsertColumn(COL_PLYBYTE, "放音字节", LVCFMT_LEFT, 60);
m_bOnLoad=FALSE;
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CTvcDemoDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTvcDemoDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTvcDemoDlg::OnTimer(UINT nIDEvent)
{
UpdateListView();
ScanChannel();
CDialog::OnTimer(nIDEvent);
}
void CTvcDemoDlg::OnBUTTONLoadDrv()
{
m_bOnLoad=TRUE;
char szPath[MAX_PATH];
DWORD dwLen = GetModuleFileName(NULL, szPath, sizeof(szPath));
for(DWORD offset=dwLen; offset>=0; offset--)
{
if(szPath[offset] == '\\')
{
szPath[offset] = 0;
break;
}
}
m_szBasePath = szPath;
::SetCurrentDirectory(m_szBasePath);
ZeroMemory(m_nTruckList,256);
ZeroMemory(m_nUserList,256);
m_nTruckNum=0;
m_nUserNum=0;
if(TvcLoadDrv("","")!=0)
{
char ErrMsg[128];
TvcGetLastErrMsg(ErrMsg,128);
AfxMessageBox(ErrMsg);
return;
}
TvcGetDrvInfo(&SysInfo);
if(SysInfo.wTotalCh>256)
SysInfo.wTotalCh = 256;
int nCode=2000;
for(int ch=0;ch<SysInfo.wTotalCh;ch++)
{
char szstr[32],szCall[32];
wsprintf(szstr,"%d",ch);
m_wndList.InsertItem(ch,szstr);
ChInfo[ch].wModule=TvcGetChType(ch);
switch(ChInfo[ch].wModule)
{
case ANALOG_REC:
wsprintf(szstr,"模拟录音");
break;
case ANALOG_USER:
wsprintf(szstr,"模拟坐席");
ChInfo[ch].wCallCode=nCode++;
wsprintf(szCall,"%d",ChInfo[ch].wCallCode);
m_wndList.SetItemText(ch,COL_CALLCODE,szCall);
//对内线通道设置摘机时自动送拨号音和检测到DTMF操作停止送信号音的属性
TvcSetChFlag(ch,CH_FLAG_AUTOSENDDIALTONE|CH_FLAG_DTMFSTOPSENDTONE);
//将所有的内线通道号存入m_nUserList表,这样在找内线通道时不用搜索所有通道
m_nUserList[m_nUserNum++]=ch;
ChInfo[ch].wStatus=US_IDLE;
break;
// case
case DIGITAL_SS1:
case DIGITAL_ISDNU:
case DIGITAL_ISDNN:
case DIGITAL_SS7TUP:
case DIGITAL_SS7ISUP:
wsprintf(szstr,"数字通道");
//将所有的外线通道号存入m_nTruckList表,这样在找外线通道时不用搜索所有通道
m_nTruckList[m_nTruckNum++]=ch;
ChInfo[ch].wStatus=TK_IDLE;
break;
case ANALOG_TRK:
wsprintf(szstr,"模拟外线");
//将所有的外线通道号存入m_nTruckList表,这样在找外线通道时不用搜索所有通道
m_nTruckList[m_nTruckNum++]=ch;
ChInfo[ch].wStatus=TK_IDLE;
break;
case CH_NULL:
wsprintf(szstr,"没有安装");
break;
default:
wsprintf(szstr,"未知");
break;
}
m_wndList.SetItemText(ch,COL_MODULE,szstr);
TvcClrRxDtmfBuf(ch);
ChInfo[ch].wBusyCount = 0;
ChInfo[ch].wEchoCount = 0;
ChInfo[ch].wCallStep = -1;
ChInfo[ch].wRingCount = 0;
ChInfo[ch].wLineVoltage = 0;
ChInfo[ch].isRecording = false;
ChInfo[ch].isPlaying=false;
ChInfo[ch].bJoinedConf = false;
ChInfo[ch].ctPrev=0;
ChInfo[ch].szSndDtmf="";
ChInfo[ch].szRxDtmf="";
ChInfo[ch].szCallerID="";
ChInfo[ch].nLinkCh=-1;
//TvcDtmfVocMuteOnBus(ch,1);
TvcSetDefaultPlayFormat(ch,voc_alaw);
TvcSetHangupStopPlay(ch,TRUE);
}
TvcSetPlayVolume(0,7);
CButton *pBtn;
pBtn=(CButton *)GetDlgItem(ID_BUTTON_LoadDrv);
pBtn->EnableWindow(false);
SetTimer(1,100,NULL);
}
void CTvcDemoDlg::UpdateListView()
{
CString state,szStr;
int tmp,tmp1;
UCHAR ucDtmf[33];
for(int ch=0;ch<SysInfo.wTotalCh;ch++)
{
if(ChInfo[ch].wModule==ANALOG_REC ||ChInfo[ch].wModule==CH_NULL)
continue;
switch( ChInfo[ch].wStatus )
{
case TK_IDLE: state = "空闲"; break ;
case TK_EMPTY: state = "断线"; break ;
case TK_PLYWELCOME: state = "播放欢迎词"; break ;
case TK_PLYSELECT: state = "播放提示音"; break ;
case TK_CHKPLYSELECT: state = "等待按键选择"; break ;
case TK_CHKRECSTART: state = "等待录音开始"; break ;
case TK_CHKRECEND: state = "录制留言"; break ;
case TK_CHKPLYREC: state = "播放留言"; break ;
case TK_CHKPLYBYE: state = "播放结束语"; break ;
case TK_LINKING: state = "外线通话中"; break ;
case TK_ECHOING: state = "外线回铃"; break ;
case US_IDLE: state = "空闲"; break ;
case US_DIALING: state = "内线外拨中"; break ;
case US_OUTDIAL: state = "拨打外线中"; break ;
case US_INCALLING: state = "内线拨打分机"; break ;
case US_PENDING: state = "内线挂起"; break ;
case US_RINGING: state = "内线振铃"; break ;
case US_TALKING: state = "内线通话中"; break ;
case US_ECHOING: state = "内线回铃"; break ;
case TK_SENDCODE: state = "拨分机号"; break ;
case TK_WAITANS: state = "等待分机应答"; break ;
default: state = "未定义"; break ;
}
szStr=m_wndList.GetItemText(ch,COL_STATUE);
if(szStr.Compare(state)!=0)
{
m_wndList.SetItemText(ch,COL_STATUE,state);
if(ChInfo[ch].wStatus==TK_IDLE || ChInfo[ch].wStatus==US_IDLE)
{
m_wndList.SetItemText(ch,COL_CALLER,"");
m_wndList.SetItemText(ch,COL_DTMFSTR,"");
m_wndList.SetItemText(ch,COL_PLYTIME,"");
m_wndList.SetItemText(ch,COL_PLYBYTE,"");
m_wndList.SetItemText(ch,COL_RECTIME,"");
m_wndList.SetItemText(ch,COL_RECBYTE,"");
}
}
ZeroMemory(ucDtmf,sizeof(ucDtmf));
szStr=m_wndList.GetItemText(ch,COL_DTMFSTR);
if(ChInfo[ch].szRxDtmf.Compare(szStr)!=0)
m_wndList.SetItemText(ch,COL_DTMFSTR,ChInfo[ch].szRxDtmf);
if(ChInfo[ch].wCallStep==ch_ringing)
{
szStr=m_wndList.GetItemText(ch,COL_CALLER);
if(szStr.IsEmpty())
{
if(TvcGetCallerId(ch,(char *)ucDtmf,32))
{
m_wndList.SetItemText(ch,COL_CALLER,(char *)ucDtmf);
}
}
}
tmp=TvcGetLineVoltage(ch);
if(ChInfo[ch].wLineVoltage !=tmp)
{
ChInfo[ch].wLineVoltage =(WORD)tmp;
szStr.Format("%d",tmp);
m_wndList.SetItemText(ch,COL_POLVOL,szStr);
}
if(TvcCheckRecord(ch))
{
tmp = TvcGetRecordTime(ch);
tmp1 = TvcGetRecordBytes(ch);
szStr=m_wndList.GetItemText(ch,COL_RECTIME);
if(atoi(szStr)!=tmp)
{
szStr.Format("%d",tmp);
m_wndList.SetItemText(ch,COL_RECTIME,szStr);
}
szStr=m_wndList.GetItemText(ch,COL_RECBYTE);
if(atoi(szStr)!=tmp1)
{
szStr.Format("%d",tmp1);
m_wndList.SetItemText(ch,COL_RECBYTE,szStr);
}
}
if(TvcGetPlayStat(ch))
{
tmp = TvcGetPlayBytes(ch);
tmp1 = TvcGetPlayTime(ch);
szStr=m_wndList.GetItemText(ch,COL_PLYBYTE);
if(atoi(szStr)!=tmp)
{
szStr.Format("%d",tmp);
m_wndList.SetItemText(ch,COL_PLYBYTE,szStr);
}
szStr=m_wndList.GetItemText(ch,COL_PLYTIME);
if(atoi(szStr)!=tmp1)
{
szStr.Format("%d",tmp1);
m_wndList.SetItemText(ch,COL_PLYTIME,szStr);
}
}
}
}
void CTvcDemoDlg::DetectBusyHangUp(int ch)
{
if(TvcGetBusyCount(ch)>=2)
{
if(TvcGetPlayStat(ch)>0)
TvcStopPlay(ch);
if(TvcCheckRecord(ch)>0)
TvcStopRecord(ch);
TvcHangUp(ch);
ChInfo[ch].wStatus=TK_IDLE;
ChInfo[ch].nLinkCh=-1;
ChInfo[ch].szRxDtmf="";
ChInfo[ch].szSndDtmf="";
}
}
void CTvcDemoDlg::ScanChannel()
{
UCHAR szDtmf[33]={0},tmpfile[50]={0};
CString szStr;
CTimeSpan ctSp;
int ret;
BOOL bFindTrk=FALSE;
for(int ch=0;ch<SysInfo.wTotalCh;ch++)
{
if(ChInfo[ch].wModule==ANALOG_REC ||ChInfo[ch].wModule==CH_NULL)
continue;
ChInfo[ch].wCallStep=TvcGetChState(ch);
if(ChInfo[ch].wCallStep==ch_empty) ChInfo[ch].wStatus=TK_EMPTY;
switch(ChInfo[ch].wStatus)
{
case TK_IDLE:
if(ChInfo[ch].wCallStep==ch_ringing)
{
if(TvcGetCallerId(ch,(char *)szDtmf,32))
ChInfo[ch].szCallerID.Format("%s",szDtmf);
TvcPickUp(ch);
ChInfo[ch].wStatus=TK_PLYWELCOME;
}
break;
case TK_PLYWELCOME:
if(ChInfo[ch].wCallStep==ch_talking)
{
//播放欢迎词
TvcStartPlayFile(ch,"..\\..\\demowav\\welcome.wav",-1,0,0);
ChInfo[ch].wStatus=TK_PLYSELECT;
TvcSetDtmfStopPlay(ch,1);
}
DetectBusyHangUp(ch);
break;
case TK_PLYSELECT:
if(ChInfo[ch].wCallStep==ch_talking)
{
TvcClrRxDtmfBuf(ch);
if(!TvcGetPlayStat(ch))
{
//播放主菜单提示音
TvcStartPlayFile(ch,"..\\..\\demowav\\select.wav",-1,0,0);
ChInfo[ch].wStatus=TK_CHKPLYSELECT;
ChInfo[ch].ctPrev=CTime::GetCurrentTime();
}
}
DetectBusyHangUp(ch);
break;
case TK_CHKPLYSELECT:
ZeroMemory(szDtmf,33);
if(TvcGetDtmfStr(ch, szDtmf,1,true)>=1)
{
szStr=ChInfo[ch].szRxDtmf;
ChInfo[ch].szRxDtmf.Format("%s%s",szStr,szDtmf);
TvcClrRxDtmfBuf(ch);
if(!TvcGetPlayStat(ch))
{
switch(szDtmf[0])
{
case '1': //DTMF=1: record to file "test.voc"
TvcStartPlayFile(ch,"..\\..\\demowav\\reclvword.wav",-1,0,0);
ChInfo[ch].wStatus=TK_CHKRECSTART;
ChInfo[ch].ctPrev=CTime::GetCurrentTime();
break;
case '2': //DTMF=2: play recorded file "test.voc"
TvcStartPlayFile(ch,".\\test.voc",-1,0,0);
ChInfo[ch].wStatus=TK_CHKPLYREC;
ChInfo[ch].ctPrev=CTime::GetCurrentTime();
break ;
case '9': //DTMF=9: 转接内线的分机号
TvcStartPlayFile(ch,"..\\..\\demowav\\entercode.wav",-1,0,0);
ChInfo[ch].wStatus=TK_SENDCODE;
ChInfo[ch].ctPrev=CTime::GetCurrentTime();
break;
case '0': //DTMF='0': end of service,play "Byebye"
TvcStartPlayFile(ch,"..\\..\\demowav\\Byebye.voc",-1,0,0);
ChInfo[ch].wStatus=TK_CHKPLYBYE;
break;
default:
break;
}
}
}
else if(TvcGetPlayStat(ch)==0 && TvcGetPlayStopReason(ch)<2) // end of playing "Select"
{
ctSp=CTime::GetCurrentTime()-ChInfo[ch].ctPrev;
if(ctSp.GetTotalSeconds()>=15) // wait DTMF key for maximum 10 seconds
{
//操作超时退出
TvcStopPlay(ch);
TvcClearFileList(ch);
TvcAppendFileToList(ch,"..\\..\\demowav\\timeout.wav",-1,0);
TvcAppendFileToList(ch,"..\\..\\demowav\\Byebye.voc",-1,0);
TvcStartPlayFileList(ch);
ChInfo[ch].wStatus=TK_CHKPLYBYE;
}
}
DetectBusyHangUp(ch);
break;
case TK_CHKRECSTART:
ZeroMemory(szDtmf,33);
ctSp=CTime::GetCurrentTime()-ChInfo[ch].ctPrev;
if(TvcGetDtmfStr(ch, szDtmf,1,true)>= 1||TvcGetPlayStat(ch)==0)
{
szStr=ChInfo[ch].szRxDtmf;
ChInfo[ch].szRxDtmf.Format("%s%s",szStr,szDtmf);
TvcClrRxDtmfBuf(ch);
TvcStartFileRecordA(ch,".\\test.voc","",voc_alaw,0,0,0);
ChInfo[ch].wStatus=TK_CHKRECEND;
}
else if(ctSp.GetTotalSeconds()>=15) //wait 15 seconds for DTMF-key
{
//操作超时退出
TvcClearFileList(ch);
TvcAppendFileToList(ch,"..\\..\\demowav\\timeout.wav",-1,0);
TvcAppendFileToList(ch,"..\\..\\demowav\\Byebye.voc",-1,0);
TvcStartPlayFileList(ch);
ChInfo[ch].wStatus=TK_CHKPLYBYE;
}
DetectBusyHangUp(ch);
break ;
case TK_CHKRECEND:
ZeroMemory(szDtmf,33);
if(TvcGetDtmfStr(ch, szDtmf,1,true)>= 1 || TvcCheckRecord(ch)==0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -