www.pudn.com > tapi3.zip > LINEINFO.CPP


// lineinfo.cpp : implementation file for CLineInfo 
// (c) Dialogic corp 1995, 1996 
 
#include "stdafx.h" 
#include  
#include "tapiapp.h" 
#include "tapiline.h" 
#include "tapicall.h" 
#include "talker32.h" 
#include "talkdlg.h" 
#include "callinfo.h" 
#include "lineinfo.h" 
#include "helpid.h" 
#include "wavedlg.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char BASED_CODE THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CLineInfo property page 
 
IMPLEMENT_DYNCREATE(CLineInfo, CPropertyPage) 
 
CLineInfo::CLineInfo() : CPropertyPage(CLineInfo::IDD) 
{ 
	//{{AFX_DATA_INIT(CLineInfo) 
	m_csLineInfo = _T(""); 
	m_fAuto = FALSE; 
	m_csDisplayWaveName = _T(""); 
	m_fAutoPlay = FALSE; 
	//}}AFX_DATA_INIT 
	m_pParent = NULL; 
	m_csWaveName = "play.wav"; 
} 
 
CLineInfo::~CLineInfo() 
{ 
} 
 
void CLineInfo::DoDataExchange(CDataExchange* pDX) 
{ 
	CPropertyPage::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CLineInfo) 
	DDX_Control(pDX, IDC_WAVENAME, m_ctlWaveName); 
	DDX_Control(pDX, IDC_AUTOPLAY, m_btnAutoPlay); 
	DDX_Control(pDX, IDC_DEVCAPS, m_btnDevCaps); 
	DDX_Control(pDX, IDC_AUTOANSWER, m_btnAutoAnswer); 
	DDX_Text(pDX, IDC_LINEINFO, m_csLineInfo); 
	DDX_Check(pDX, IDC_AUTOANSWER, m_fAuto); 
	DDX_Text(pDX, IDC_WAVENAME, m_csDisplayWaveName); 
	DDX_Check(pDX, IDC_AUTOPLAY, m_fAutoPlay); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CLineInfo, CPropertyPage) 
	//{{AFX_MSG_MAP(CLineInfo) 
	ON_BN_CLICKED(IDC_DEVCAPS, OnDevcaps) 
	ON_BN_CLICKED(IDC_CONFIG, OnConfig) 
	ON_BN_CLICKED(IDC_AUTOANSWER, OnAutoanswer) 
	ON_BN_CLICKED(IDC_BROWSE, OnBrowse) 
	ON_BN_CLICKED(IDC_GETDEVSTATUS, OnGetdevstatus) 
	ON_BN_CLICKED(IDC_AUTOPLAY, OnAutoplay) 
	ON_WM_SETFOCUS() 
	ON_WM_DESTROY() 
	ON_BN_CLICKED(IDC_WAVEFORMAT, OnWaveformat) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
// call lineGetLineDevCaps & display results 
void CLineInfo::DisplayDevCaps() 
{ 
 
	LPLINEDEVCAPS lpDC; 
	if(m_pLine->ctlLineGetCaps(&lpDC)) return; 
	if(lpDC == NULL) return; 
	// display status 
	m_csLineInfo.Empty(); 
	CString csTemp; 
	csTemp.Format("dwPermanentLineID = %d,\r\ndwAddressModes = %d,\r\ndwGenerateToneModes = %d\r\n", 
			lpDC->dwPermanentLineID, lpDC->dwAddressModes, lpDC->dwGenerateToneModes); 
	m_csLineInfo += csTemp; 
	csTemp.Format("dwMonitorDigitModes = %d,\r\ndwMediaModes = %d,\r\ndwMaxRate = %d\r\n", 
			lpDC->dwMonitorDigitModes, lpDC->dwMediaModes, lpDC->dwMaxRate); 
	m_csLineInfo += csTemp; 
	if(m_pLine->m_csName.IsEmpty()) 
		csTemp.Format("Line name = %s\r\n", (LPSTR)((LPBYTE)lpDC + lpDC->dwLineNameOffset)); 
	else 
		csTemp.Format("Line name = %s\r\n", m_pLine->m_csName); 
	m_csLineInfo += csTemp; 
	csTemp.Format("Provider info = %s\r\n", (LPCTSTR)((LPBYTE)lpDC + lpDC->dwProviderInfoOffset)); 
	m_csLineInfo += csTemp; 
	if(m_pLine->IsRemote()) 
		csTemp.Format("Line is operating on remote machine!\r\n"); 
	else 
		csTemp.Format("Wave/In ID = %d, Wave/Out ID = %d\r\n", m_pLine->ctlGetWaveInID(), m_pLine->ctlGetWaveOutID()); 
	m_csLineInfo += csTemp; 
	UpdateData(FALSE); 
	delete lpDC; 	 
} 
 
 
// call lineGetLineDevStatus & display results 
void CLineInfo::DisplayDevStatus() 
{ 
	CString csTemp; 
 
	LPLINEDEVSTATUS lpDS = m_pLine->ctlGetLineDevStatus(); 
	if(lpDS == NULL)  
	{ 
		m_csLineInfo.Format("Status unavailable!\r\n"); 
		UpdateData(FALSE); 
		return; 
	} 
	// display status 
	m_csLineInfo.Empty(); 
	csTemp.Format("dwNumOpens = %d,\r\ndwOpenMediaModes = %d,\r\ndwNumActiveCalls = %d\r\n", 
			lpDS->dwNumOpens, lpDS->dwOpenMediaModes, lpDS->dwNumActiveCalls); 
	m_csLineInfo += csTemp; 
	csTemp.Format("dwNumOnHoldCalls = %d,\r\ndwNumOnHoldPendCalls = %d,\r\ndwLineFeatures = %d\r\n", 
			lpDS->dwNumOnHoldCalls, lpDS->dwNumOnHoldPendCalls, lpDS->dwLineFeatures); 
	m_csLineInfo += csTemp; 
	UpdateData(FALSE); 
	delete lpDS; 	 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CLineInfo message handlers 
 
BOOL CLineInfo::OnInitDialog()  
{ 
	CPropertyPage::OnInitDialog(); 
	WORD wOptions = ((CTalkApp *)AfxGetApp())->m_wLineOptions[m_pLine->ctlGetLineID()]; 
	if(wOptions & AUTOANSWER) m_fAuto = TRUE; 
	if(wOptions & AUTOPLAY) m_fAutoPlay = TRUE; 
	FitWaveName(); 
	if(m_pLine != NULL)	DisplayDevStatus(); 
	m_nFormatID = 10;			// default = 11k 8bit PCM 
	m_dwRecFileSize = 65534;	// default 
		 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
void CLineInfo::OnDevcaps()  
{ 
	if(m_pLine==NULL) return; 
	if(m_pLine != NULL) DisplayDevCaps();		 
} 
 
 
void CLineInfo::OnConfig()  
{ 
	m_pLine->ctlConfigDialog(GetSafeHwnd(), "tapi/line");	 
} 
 
void CLineInfo::OnAutoanswer()  
{ 
	CString csTemp; 
 
	csTemp.Format("line%d", m_pLine->ctlGetLineID()); 
	if(m_btnAutoAnswer.GetCheck()) 
	{ 
		AfxGetApp()->WriteProfileString(csTemp, "AutoAnswer", "yes"); 
		((CTalkApp *)AfxGetApp())->m_wLineOptions[m_pLine->ctlGetLineID()] |= AUTOANSWER; 
	} 
	else  
	{ 
		AfxGetApp()->WriteProfileString(csTemp, "AutoAnswer", "no"); 
		((CTalkApp *)AfxGetApp())->m_wLineOptions[m_pLine->ctlGetLineID()] &= ~AUTOANSWER; 
	} 
	UpdateData(); 
} 
 
void CLineInfo::OnAutoplay()  
{ 
	CString csTemp; 
 
	csTemp.Format("line%d", m_pLine->ctlGetLineID()); 
	if(m_btnAutoPlay.GetCheck()) 
	{ 
		AfxGetApp()->WriteProfileString(csTemp, "AutoPlay", "yes"); 
		((CTalkApp *)AfxGetApp())->m_wLineOptions[m_pLine->ctlGetLineID()] |= AUTOPLAY; 
	} 
	else  
	{ 
		AfxGetApp()->WriteProfileString(csTemp, "AutoPlay", "no"); 
		((CTalkApp *)AfxGetApp())->m_wLineOptions[m_pLine->ctlGetLineID()] &= ~AUTOPLAY; 
	} 
	UpdateData(); 
} 
 
 
// Select the wave file to play 
void CLineInfo::OnBrowse()  
{ 
	CString csTemp; 
 
	csTemp.Format("line%d", m_pLine->ctlGetLineID()); 
 
	CString csFilter = "Wave Files(*.wav)|*.wav|All Files(*.*)|*.*||"; 
	CFileDialog dlg(TRUE, NULL, m_csWaveName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
				(LPCTSTR) csFilter, this); 
	if(IDOK == dlg.DoModal()) 
	{ 
		m_csWaveName = dlg.GetPathName(); 
		AfxGetApp()->WriteProfileString(csTemp, "Wave Play File", m_csWaveName); 
		FitWaveName(); 
		UpdateData(FALSE);		 
		m_pParent->m_CallInfo[0].m_pWaveName = &m_csWaveName; 
	} 
 
	DWORD  dwDesiredAccess = GENERIC_READ;	// access (read-write) mode  
    DWORD  dwShareMode = 0;	// share mode  
    LPSECURITY_ATTRIBUTES  lpSecurityAttributes = NULL;	// address of security descriptor  
    DWORD  dwCreationDistribution = OPEN_EXISTING;	// how to create  
    HANDLE  hF = CreateFile((LPCTSTR)m_csWaveName, dwDesiredAccess,  
		dwShareMode, lpSecurityAttributes, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL,NULL); 
	if(hF == INVALID_HANDLE_VALUE)  
	TRACE("Openfailed err=%d\n", GetLastError()); 
	else CloseHandle(hF); 
} 
 
// Fit the wave file name into available space 
void CLineInfo::FitWaveName() 
{ 
	int nChars = 0, nLen, nInd1, nInd2; 
	// find out how much space is available 
	CDC *pDC  = m_ctlWaveName.GetDC(); 
	if(pDC)  
	{ 
		TEXTMETRIC myTM; 
		if(pDC->GetTextMetrics(&myTM)) 
		{ 
			CRect cr; 
			m_ctlWaveName.GetClientRect(&cr); 
			nChars = (cr.right - cr.left)/myTM.tmAveCharWidth; 
		} 
		m_ctlWaveName.ReleaseDC(pDC); 
	} 
	if(nChars < 25 || nChars > 40) nChars = 25;		// just in case 
	nLen = m_csWaveName.GetLength(); 
	if(nLen <= nChars)		// fits already 
	{ 
		m_csDisplayWaveName = m_csWaveName; 
		goto FinishFit; 
	} 
	nInd1 = m_csWaveName.Find('\\'); 
	nInd2 = m_csWaveName.ReverseFind('\\'); 
	if(nInd1 && nInd2 && nInd2 > nInd1) 			// remove all between ind1 & ind2 
	{ 
		m_csDisplayWaveName = m_csWaveName.Left(nInd1+1) + (LPCTSTR) "..." +m_csWaveName.Right(nLen - nInd2);  
	} 
	else m_csDisplayWaveName = m_csWaveName; 
	FinishFit: 
	m_csDisplayWaveName.MakeLower(); 
} 
 
void CLineInfo::OnGetdevstatus()  
{ 
	DisplayDevStatus();		 
} 
 
void CLineInfo::OnSetFocus(CWnd* pOldWnd)  
{ 
	CPropertyPage::OnSetFocus(pOldWnd); 
	((CTalkApp *)AfxGetApp())->SetHelpId(HIDD_TALKER32_DialogLineInfo); 
	 
} 
 
void CLineInfo::OnWaveformat()  
{ 
	CWaveDlg dlg(this); // bring up the format dialog	 
	dlg.m_nFormatID = m_nFormatID; 
	dlg.m_csFileName = m_csWaveName; 
	if(IDOK == dlg.DoModal()) 
		m_nFormatID = dlg.m_nFormatID; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CInfo 
 
IMPLEMENT_DYNAMIC(CInfo, CPropertySheet) 
 
CInfo::CInfo(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) 
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage) 
{ 
	m_pbtnClose = NULL; 
	m_pbtnHelp = NULL; 
	BuildSheet(); 
} 
 
CInfo::CInfo(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage, LPVOID lpLine) 
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage) 
{ 
	m_pbtnClose = NULL; 
	m_pbtnHelp = NULL; 
	BuildSheet(lpLine); 
} 
 
CInfo::~CInfo() 
{ 
} 
 
BEGIN_MESSAGE_MAP(CInfo, CPropertySheet) 
	//{{AFX_MSG_MAP(CInfo) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SHOWWINDOW() 
	ON_BN_CLICKED(IDCANCEL, OnClose) 
	ON_BN_CLICKED(ID_HELP, OnContextHelp) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void CInfo::BuildSheet(LPVOID lpLine) 
{ 
	DWORD i; 
	CString csTemp; 
	OSVERSIONINFO verinfo; 
	BOOL bNT = FALSE; 
 
	verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
	if(GetVersionEx(&verinfo) &&  
		verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) bNT = TRUE;	 
 
	// find out the number of calls; can handle only one for now 
	m_LineInfo.m_dwCalls = 0; 
	if(lpLine == NULL) return; 
	m_LineInfo.m_pLine = (CTapiLine *)lpLine; 
	m_LineInfo.m_pParent = this;  
	CTapiCall *pCall = m_LineInfo.m_pLine->ctlGetActiveCall(); 
	if(pCall != NULL) 
	{ 
		m_LineInfo.m_dwCalls = 1; 
		m_LineInfo.m_ppCalls[0] = pCall; 
	} 
 
	m_LineInfo.m_csLineName.Empty(); 
	m_LineInfo.m_bRemote = FALSE; 
	LPLINEDEVCAPS lpDC; 
	if(!m_LineInfo.m_pLine->ctlLineGetCaps(&lpDC))			// extract line name 
	{ 
		if(lpDC != NULL)  
		{ 
			m_LineInfo.m_csLineName.Format("%s", (LPSTR)((LPBYTE)lpDC + lpDC->dwLineNameOffset)); 
			if(bNT) 
				m_LineInfo.m_bRemote = IsLineRemote(lpDC);	// find out if line is remote 
			delete lpDC; 
		} 
	} 
	// set the wave file name 
	csTemp.Format("line%d", m_LineInfo.m_pLine->ctlGetLineID()); 
	m_LineInfo.m_csWaveName = AfxGetApp()->GetProfileString((LPCTSTR)csTemp, "Wave Play File", ""); 
	m_LineInfo.m_csWaveRecName = AfxGetApp()->GetProfileString((LPCTSTR)csTemp, "Wave Record File", ""); 
	if(m_LineInfo.m_csWaveName.IsEmpty()) 		//  
		m_LineInfo.m_csWaveName = "play.wav"; 
	if(m_LineInfo.m_csWaveRecName.IsEmpty()) 		//  
		m_LineInfo.m_csWaveRecName.Format("record%.2d.wav",m_LineInfo.m_pLine->ctlGetLineID()); 
 
	AddPage(&m_LineInfo); 
	for(i = 0; i < m_LineInfo.m_dwCalls; i++) 
	{ 
		m_CallInfo[i].m_csCaption.Format("Call %d", i+1); 
		m_CallInfo[i].m_pCall = m_LineInfo.m_ppCalls[i]; 
		m_CallInfo[i].m_pLine = (CTapiLine *)lpLine; 
		m_CallInfo[i].m_pWaveName = &m_LineInfo.m_csWaveName; 
		m_CallInfo[i].m_pWaveRecName = &m_LineInfo.m_csWaveRecName; 
		m_CallInfo[i].m_pLineName = &m_LineInfo.m_csLineName; 
		m_CallInfo[i].m_bRemote = m_LineInfo.m_bRemote; 
		m_CallInfo[i].m_bRunningOnNT = bNT; 
		m_CallInfo[i].m_pnWaveFormatID = &m_LineInfo.m_nFormatID; 
		m_CallInfo[i].m_pdwRecFileSize = &m_LineInfo.m_dwRecFileSize; 
		AddPage(&m_CallInfo[i]);	// where to init call info page? 
	} 
} 
 
void CInfo::CreateCloseButton() 
{ 
	CRect crctw; 
	 
	if(m_pbtnClose) return; 
	m_pbtnClose = new CButton; 
	m_pbtnHelp = new CButton; 
	GetWindowRect(&crctw); 
	crctw.InflateRect(10,15); 
	MoveWindow(&crctw); 
	GetWindowRect(&crctw); 
	 
	CRect crctb(crctw.Width()-60, crctw.Height()-50, crctw.Width()-20, crctw.Height()-30);  
	m_pbtnClose->Create("Close", BS_PUSHBUTTON, crctb, this, IDCANCEL);	//special ID 
	CFont *pcfTemp = m_LineInfo.m_btnDevCaps.GetFont();	//a little dirty, but works 
	m_pbtnClose->SetFont(pcfTemp); 
	m_pbtnClose->ShowWindow(SW_SHOW); 
	crctb.left -= 60; 
	crctb.right -= 60; 
	m_pbtnHelp->Create("Help", BS_PUSHBUTTON, crctb, this, ID_HELP);	//special ID 
	m_pbtnHelp->SetFont(pcfTemp); 
	m_pbtnHelp->ShowWindow(SW_SHOW); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CInfo message handlers 
 
 
int CInfo::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CPropertySheet::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
//	CreateCloseButton();	 
	return 0; 
} 
 
void CInfo::OnDestroy()  
{ 
	CPropertySheet::OnDestroy(); 
	 
	if(m_pbtnClose==NULL) return; 
	delete m_pbtnClose; 
	m_pbtnClose = NULL; 
	delete m_pbtnHelp; 
	m_pbtnHelp = NULL; 
} 
 
void CInfo::OnShowWindow(BOOL bShow, UINT nStatus)  
{ 
	CPropertySheet::OnShowWindow(bShow, nStatus); 
	 
	CreateCloseButton();	 
	if(m_pbtnClose)  
	m_pbtnClose->ShowWindow(SW_SHOW); 
	if(m_pbtnHelp)  
	m_pbtnHelp->ShowWindow(SW_SHOW); 
} 
 
void CInfo::OnClose()  
{ 
	PostMessage(WM_CLOSE,0,0); 
} 
 
void CInfo::OnContextHelp()  
{ 
	((CTalkApp *)AfxGetApp())->OnHelp(); 
//	CPropertySheet::WinHelp(HIDD_TALKER32_DialogLineInfo, HELP_CONTEXT); 
} 
 
// Determine if the line is running on the remote computer 
// Since MS doesn't provide a standard way, use whatever mechanism is available for the SP 
// Override this function to implement a better way 
/***	Moved to talker32.cpp 
BOOL IsLineRemote(LPLINEDEVCAPS lpDC) 
{ 
	int nInd; 
	CString csTemp; 
 
	if(!lpDC->dwLineNameOffset) return FALSE; 
	csTemp.Format("%s", (LPSTR)((LPBYTE)lpDC + lpDC->dwLineNameOffset)); 
	csTemp.MakeUpper(); 
	if(-1 == csTemp.Find("DXXXB")) return FALSE;		// non-Dialogic TSP 
	if(-1 == (nInd = csTemp.Find("\\"))) return FALSE;	// computer name not a part of board name 
	csTemp = csTemp.Left(nInd); 
	char szName[MAX_COMPUTERNAME_LENGTH+1]; 
	DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1; 
	if(!GetComputerName(szName, &dwSize)) return FALSE;	// Name unavailable for some reason 
	if(!strcmpi(szName, (LPCTSTR)csTemp)) return FALSE;	// Same name 
	return TRUE;					 // Finally, the names ARE different 
} ***/