⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialdlg.cpp

📁 三汇CTI示例程序源码
💻 CPP
字号:
// DialDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Dial.h"
#include "DialDlg.h"
#include "string.h"
#include "../../../../../api/vc6.0/inc/Shpa3api.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDialDlg dialog

CDialDlg::CDialDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDialDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDialDlg)
	m_PhoNumLen = 8;
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDialDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDialDlg)
	DDX_Control(pDX, IDC_LIST_USER_CH, m_UserChList);
	DDX_Control(pDX, IDC_LIST_TRK_CH, m_TrkChList);
	DDX_Text(pDX, IDC_PHONE_NUM_LEN, m_PhoNumLen);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDialDlg, CDialog)
	//{{AFX_MSG_MAP(CDialDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_EN_CHANGE(IDC_PHONE_NUM_LEN, OnChangePhoneNumLen)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDialDlg message handlers

BOOL CDialDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	if(!InitCtiBoard())  return false; 
	
	InitTrunkChList();	
	InitUserChList();

	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 CDialDlg::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();
	}
}

HCURSOR CDialDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CDialDlg::OnChangePhoneNumLen() 
{
	UpdateData(true);
}

BOOL CDialDlg::InitCtiBoard()
{
	//Initialization of CTI driver
	char CurPath[260],ShIndex[260],ShConfig[260];
	GetCurrentDirectory(200,CurPath);
	strcpy(ShConfig,CurPath);
	strcpy(ShIndex,CurPath);
	strcat(ShConfig,"\\ShConfig.ini");
	strcat(ShIndex,"\\ShIndex.ini");
	if( SsmStartCti(ShConfig,ShIndex) != 0) 
	{
		CString str1;
		SsmGetLastErrMsg(str1.GetBuffer(200));
		AfxMessageBox(str1, MB_OK) ;
		PostQuitMessage(0);
		return false;
    }

	//Initialization of channels on trunk-board

	nTotalCh = SsmGetMaxCh(); 
	for(int i=0; i<nTotalCh; i++)
	{
		ChInfo[i].EnCalled = false;

		if(SsmGetChType(i) == 2 ) // user channel
		{
			SsmSetASDT(i, 1);
			strcpy(ChInfo[i].pPhoNumBuf,"");
			ChInfo[i].nStep = USER_IDLE;
		}
		else
		{
			
			int nDirection;
			if( SsmGetAutoCallDirection(i,&nDirection) == 1 ) //auto connection is supported
			{
				if( nDirection == 1 || nDirection == 2 ) //enable dial
				{
					  ChInfo[i].InUse = 0;
					  strcpy(ChInfo[i].DtmfBuf,"");
					  SsmSetMinVocDtrEnergy( i, 30000);					  
					  ChInfo[i].EnCalled = true;
					  ChInfo[i].nStep = TRK_IDLE;
				}
			}
		}		
	}

	// set event callback handle.
	EVENT_SET_INFO EventSet;
	EventSet.dwWorkMode = EVENT_MESSAGE;	
	EventSet.lpHandlerParam = this->GetSafeHwnd();	
	SsmSetEvent(-1, -1, TRUE, &EventSet);
	nTimer = SsmStartTimer(200, 1);

	return true;
}

void CDialDlg::InitTrunkChList()
{
	//Initialization of trunk-channel-state list control
	int ColumnWidth[4] = {40, 85, 60};
	LV_COLUMN lvc;
	lvc.mask =  LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
	
	lvc.iSubItem = 0;
	lvc.pszText = "ChannelId" ;
	lvc.cx = ColumnWidth[0];
	m_TrkChList.InsertColumn(0,&lvc);

	lvc.iSubItem = 1;
	lvc.pszText = "State of Trunk Channel";
	lvc.cx = ColumnWidth[1];
	m_TrkChList.InsertColumn(1,&lvc);

	lvc.iSubItem = 2;
	lvc.pszText = "DTMF";
	lvc.cx = ColumnWidth[2];
	m_TrkChList.InsertColumn(2,&lvc);

	char dig[3];
	for(int i=0; i<nTotalCh; i++)	
		if (ChInfo[i].EnCalled) m_TrkChList.InsertItem(i,_itoa(i,dig,10));
}

void CDialDlg::InitUserChList()
{
	int ColumnWidth[4] = {40, 85, 60};
	LV_COLUMN lvc;
	lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

	lvc.iSubItem = 0;
	lvc.pszText = "Channel Id";
	lvc.cx = ColumnWidth[0];
	m_UserChList.InsertColumn(0,&lvc);

	lvc.iSubItem = 1;
	lvc.pszText = "State of Station Channel";
	lvc.cx = ColumnWidth[1];
	m_UserChList.InsertColumn(1,&lvc);

	lvc.iSubItem = 2;
	lvc.pszText = "CalledId";
	lvc.cx = ColumnWidth[2];
	m_UserChList.InsertColumn(2,&lvc);
	
	char dig[3];
	for(int i=0; i<nTotalCh; i++)
	{	
		if (SsmGetChType(i)==2) m_UserChList.InsertItem(i, _itoa(i,dig,10));
	}
}

void CDialDlg::DrawUserChState()
{
	CString state ;
	char tmpstr[51];

	for(int i=0,nIndex=0; i<nTotalCh; i++)
	{
		if( SsmGetChType(i) != 2) continue;
		
		switch( ChInfo[i].nStep )
		{
		case USER_IDLE:					state = "Idle";			break ;
		case USER_GET_PHONE_NUM:		state = "Receive Phone Number"; break ;
		case USER_WAIT_DIAL_TONE:		state = "Wait Dial-tone";	break ;
		case USER_WAIT_REMOTE_PICKUP:	state = "Wait Called Party Answer"; break ;
		case USER_TALKING:				state = "Talking";		break ;
		case USER_WAIT_HANGUP:			state = "Wait Station Hangup"; break ;		
		}
		
		m_UserChList.GetItemText(nIndex,1,tmpstr,50); 
		if(state != tmpstr) 
			m_UserChList.SetItemText(nIndex, 1, state.GetBuffer(50) );

		m_UserChList.GetItemText(nIndex,2,tmpstr,50); 
		if(strcmp(ChInfo[i].pPhoNumBuf,tmpstr) != 0) 
			m_UserChList.SetItemText(nIndex, 2, ChInfo[i].pPhoNumBuf);
		
		nIndex++;
	}
}
		

void CDialDlg::DrawTrunkChState()
{
	CString state;
	char tmpstr[51];

	for(int i=0, nIndex = 0; i<nTotalCh; i++)
	{
		if( !ChInfo[i].EnCalled ) continue;

		switch(ChInfo[i].InUse)
		{
		case 0:		state="Idle";         break;
		case 1:		state="Off-hook";         break;
		case 2:		state="Dialing";         break;
		case 3:		state="Wait Called Party Answer"; break;
		case 4:		state="Talking";         break;
		}

		m_TrkChList.GetItemText(nIndex,1,tmpstr,50);
		if(state != tmpstr) 
			m_TrkChList.SetItemText(nIndex, 1, state.GetBuffer(50) );

		SsmGetDtmfStr(i, ChInfo[i].DtmfBuf);
		m_TrkChList.GetItemText(nIndex,2,tmpstr,50);
		if(strcmp(ChInfo[i].DtmfBuf,tmpstr) != 0) 
			m_TrkChList.SetItemText(nIndex, 2, ChInfo[i].DtmfBuf);

		nIndex++;
	}
}

void CDialDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	SsmCloseCti();	
}

int CDialDlg::myGetAnIdleChannel() // find an idle trunk channel
{
	for(int i=0; i<nTotalCh; i++)
	{
		if( !ChInfo[i].InUse && ChInfo[i].EnCalled  ) break;
	}
	
	if(i==nTotalCh) return -1;
	return i;
}

LRESULT CDialDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	int ch;
	int AtrkCh;
	int eventcode;
	DWORD dw = (DWORD)lParam;  
	int	n;
	if (message >= WM_USER) 
	{
		eventcode = message - WM_USER;
		switch(eventcode) {
		case E_SYS_TIMEOUT:
			n = wParam;
			if(n == nTimer)
			{
				DrawUserChState();
				DrawTrunkChState();			
			}
			return 0;
			
		case E_CHG_HookState:
			ch = wParam;
			if (dw == 0)//station channel hangs up
			{
				
				switch (ChInfo[ch].nStep)
				{
				case USER_GET_PHONE_NUM:
					SsmClearRxDtmfBuf(ch);
					ChInfo[ch].nStep = USER_IDLE;
					break;
					
				case USER_WAIT_REMOTE_PICKUP: 
					AtrkCh = ChInfo[ch].nConnectCh;
					SsmHangup(AtrkCh);
					ChInfo[AtrkCh].InUse = 0;
					ChInfo[AtrkCh].nStep = TRK_IDLE;
					SsmClearRxDtmfBuf(AtrkCh);
					
					SsmClearRxDtmfBuf(ch);
					ChInfo[ch].nStep = USER_IDLE;
					break ;
					
				case USER_TALKING:
					AtrkCh = ChInfo[ch].nConnectCh;
					SsmHangup(AtrkCh);
					SsmStopTalkWith(AtrkCh, ch);
					SsmClearRxDtmfBuf(AtrkCh);
					ChInfo[AtrkCh].InUse = 0;
					ChInfo[AtrkCh].nStep = TRK_IDLE;
					
					ChInfo[ch].nStep = USER_IDLE;
					break;
					
				case USER_WAIT_HANGUP:
					SsmStopSendTone(ch);					//stop sending busy tone
					SsmClearRxDtmfBuf(ch);
					ChInfo[ch].nStep = USER_IDLE;
					break;
					
				default:
					ChInfo[ch].nStep = USER_IDLE;
					break;
				}//end switch
			}
			else if (dw ==1) //station channel picks up
			{   
				if (USER_IDLE == ChInfo[ch].nStep )
				{				
					strcpy(ChInfo[ch].pPhoNumBuf,"");
					SsmClearRxDtmfBuf(ch);					
					ChInfo[ch].nStep = USER_GET_PHONE_NUM;

				}
			}
			return 0;
			
		case E_CHG_RcvDTMF:
			ch = wParam;
			if (ChInfo[ch].nStep == USER_GET_PHONE_NUM)
			{
				n = dw >> 16;
				if (n >= m_PhoNumLen) 
				{
					SsmGetDtmfStr(ch,ChInfo[ch].pPhoNumBuf);		//retrieve phone num
					ChInfo[ch].pPhoNumBuf[m_PhoNumLen] = '\0';
					if((AtrkCh=myGetAnIdleChannel()) == -1)			//no idle trunk channel available
					{
						SsmSendTone(ch,1);						// send busy tone	
						ChInfo[ch].nStep = USER_WAIT_HANGUP;
					}
					else 
					{
						SsmPickup(AtrkCh);
						ChInfo[AtrkCh].InUse = 1;					
						
						if ( SsmAutoDial(AtrkCh, ChInfo[ch].pPhoNumBuf) ==0)
						{							
							ChInfo[AtrkCh].nConnectCh = ch;
							ChInfo[AtrkCh].InUse = 2;
							ChInfo[AtrkCh].nStep = TRK_AutoDial;
							
							ChInfo[ch].nConnectCh = AtrkCh;
							ChInfo[ch].nStep = USER_WAIT_REMOTE_PICKUP;
						}
						else 
						{
							SsmHangup(AtrkCh);
							ChInfo[AtrkCh].InUse = 0;
							SsmClearRxDtmfBuf(AtrkCh);
							
							SsmSendTone(ch,1);				//send busy tone
							ChInfo[ch].nStep = USER_WAIT_HANGUP;
						}
					}
				}
			}
			return 0;
		case E_PROC_AutoDial:
			AtrkCh = wParam;
			if(ChInfo[AtrkCh].nStep == TRK_AutoDial)
			{
				switch(dw) {
				case 2: //	ringback tone is detected after transmission of called id 
					ChInfo[AtrkCh].InUse = 3;
					break;				
					
				case 5://	silence on the line after ringback tone is detected. 
				case 7://	called party answers the call 
					ch = ChInfo[AtrkCh].nConnectCh;
					SsmTalkWith(AtrkCh, ch);
					ChInfo[AtrkCh].InUse = 4;
					ChInfo[AtrkCh].nStep = TRK_TALKING;
					
					ChInfo[ch].nStep = USER_TALKING;
					break;
				case 3://no dialing tone is detected 			
				case 4://called party's line is busy
				case 6://silence on the line after completion of auto-dial 
				case 8://called party answers the call and signal F1 is detected 
				case 9://called party answers the call and signal F2 is detected 
				case 10://	the called party does not answer the call 
				case 11://	failed auto-dial 
				case 12://unallocated number 
					SsmHangup(AtrkCh);
					ChInfo[AtrkCh].InUse = 0;
					SsmClearRxDtmfBuf(AtrkCh);
					ChInfo[AtrkCh].nStep = TRK_IDLE;
					
					ch = ChInfo[AtrkCh].nConnectCh;
					SsmSendTone(ch,1);					//send busy tone
					ChInfo[ch].nStep = USER_WAIT_HANGUP;
					break;
				default:
					break;
				}
			}
			return 0;
			
		case E_CHG_ChState:			
			dw &= 0xFFFF;
			if(dw == S_CALL_PENDING)
			{
				AtrkCh = wParam;
				if(ChInfo[AtrkCh].nStep == TRK_AutoDial)
				{
					SsmHangup(AtrkCh);
					ChInfo[AtrkCh].InUse = 0;
					SsmClearRxDtmfBuf(AtrkCh);
					ChInfo[AtrkCh].nStep = TRK_IDLE;
					
					ch = ChInfo[AtrkCh].nConnectCh;
					SsmSendTone(ch,1);					//send busy tone
					ChInfo[ch].nStep = USER_WAIT_HANGUP;	
				}
				else if(ChInfo[AtrkCh].nStep == TRK_TALKING)
				{
					ch = ChInfo[AtrkCh].nConnectCh;
					SsmHangup(AtrkCh);
					SsmStopTalkWith(AtrkCh, ch);
					SsmClearRxDtmfBuf(AtrkCh);
					ChInfo[AtrkCh].InUse = 0;
					
					SsmSendTone(ch,1);				//send busy tone
					ChInfo[ch].nStep = USER_WAIT_HANGUP;
				}
			}
			return 0;
		default:
			break; 
		}
	}	
	
	return CDialog::WindowProc(message, wParam, lParam);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -