📄 talkdlg.cpp
字号:
// talkdlg.cpp : implementation file
// (c) Dialogic corp 1995, 1996
#include "stdafx.h"
#include <tapi.h>
#include "tapiapp.h"
#include "tapiline.h"
#include "tapicall.h"
#include "talker32.h"
#include <mmsystem.h>
#include "wavex.h"
//#include "wavexg.h"
#include "callinfo.h"
#include "lineinfo.h"
#include "talkdlg.h"
#include "helpid.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTalkDlg dialog
CTalkDlg::CTalkDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTalkDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTalkDlg)
m_csDialString = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
SetHelpID(HIDD_TALKER32_DialogMain);
}
void CTalkDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTalkDlg)
DDX_Control(pDX, IDC_DIAL, m_btnDial);
DDX_Control(pDX, IDC_EDIT1, m_ctlDialString);
DDX_Control(pDX, IDC_CALLS, m_ctlActiveCalls);
DDX_Control(pDX, IDC_LINEFRAME, m_ctlLineFrame);
DDX_Control(pDX, IDC_NUMBER0, m_ctlLineNum0);
DDX_Control(pDX, IDC_INFO0, m_btnInfo0);
DDX_Control(pDX, IDC_ACTION0, m_btnAction0);
DDX_Control(pDX, IDC_IND0, m_ctlFrame0);
DDX_Text(pDX, IDC_EDIT1, m_csDialString);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTalkDlg, CDialog)
//{{AFX_MSG_MAP(CTalkDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_DIAL, OnDial)
ON_MESSAGE(MM_WOM_DONE, OnWomDone) // Finish playing WAVE
ON_MESSAGE(MM_WIM_DATA, OnWimData) // Finish recording WAVE
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_BN_CLICKED(ID_CONTEXT_HELP, OnContextHelp)
ON_WM_SETFOCUS()
ON_WM_ACTIVATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTalkDlg message handlers
BOOL CTalkDlg::OnInitDialog()
{
DWORD i;
char szBuf[16];
CTapiLine *ptlTemp;
CDialog::OnInitDialog();
CenterWindow();
// SetHelpID(HIDD_TALKER32_DialogMain);
// set the control ID so that the TapiApp object knows where to send notification messages
((CTalkApp *)AfxGetApp())->SetNotificationControlID(IDC_TAPIALERT);
m_dwLines = ((CTalkApp *)AfxGetApp())->m_dwLines;
m_LineControls[0].uiActionID = IDC_ACTION0;
m_LineControls[0].uiInfoID = IDC_INFO0;
m_LineControls[0].pbtnAction = &m_btnAction0;
m_LineControls[0].pbtnInfo = &m_btnInfo0;
m_LineControls[0].pFrame = &m_ctlFrame0;
m_LineControls[0].pctlLineNum = &m_ctlLineNum0;
m_LineControls[0].pInfoDlg = NULL;
m_nLastX = 95;
m_nLastY = 25;
m_uiLastID = CONTROL_ARRAY_START;
memset((PBYTE)&(m_LineControls[1]), 0, sizeof(LINECONTROL)*(MAXLINES-1)); // zeroinit
//difference between non-existent & non-functional line:ctlLine=0-nonexist, hline=0-nonfunct
for(i=0; i< m_dwLines; i++)
{
if(NULL == (ptlTemp = ((CTalkApp *)AfxGetApp())->GetTapiLine(i))) continue;
if(i) if(FALSE == CreateLineWindows(&(m_LineControls[i]))) continue;
m_LineControls[i].pctlLine = ptlTemp; // save the line pointer for future ref
sprintf(szBuf, "%d", i);
(m_LineControls[i].pctlLineNum)->SetWindowText(szBuf);
if(NULL != ptlTemp->ctlGetHLine()) // Line functional
(m_LineControls[i].pFrame)->m_Colorref = GREEN; //green=OK
else
{
(m_LineControls[i].pFrame)->m_Colorref = BLACK; //black=nonfunctional
(m_LineControls[i].pbtnAction)->EnableWindow(FALSE);
}
m_LineControls[0].pInfoDlg = NULL;
(m_LineControls[i].pFrame)->Invalidate();
}
if(!m_dwLines) // remove the pilot windows
{
m_btnAction0.ShowWindow(SW_HIDE);
m_btnInfo0.ShowWindow(SW_HIDE);
m_ctlFrame0.ShowWindow(SW_HIDE);
m_ctlLineNum0.ShowWindow(SW_HIDE);
MessageBox("No TAPI lines found, check TAPI configuration", "Talker32", MB_ICONEXCLAMATION);
}
m_btnDial.EnableWindow(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.
BOOL CTalkDlg::CreateLineWindows(PLINECONTROL pLineControl)
{
CRect rCur, rNew, rWork;
CFont *pcfTemp = m_btnAction0.GetFont();
POINT pntNew;
if(NULL == (pLineControl->pctlLineNum = new CStatic)) return FALSE;
if(NULL == (pLineControl->pFrame = new CXstatic)) return FALSE;
if(NULL == (pLineControl->pbtnAction = new CButton)) return FALSE;
if(NULL == (pLineControl->pbtnInfo = new CButton)) return FALSE;
m_uiLastID++;
// Get the position & IDs for the new controls
if(FALSE == DetermineLinePos(&pntNew)) return FALSE; // main wnd too small
rNew.left = pntNew.x;
rNew.top = pntNew.y;
rNew.right = pntNew.x + 8;
rNew.bottom = pntNew.y + 10;
rWork = rNew;
MapDialogRect(&rWork); // convert from dialog base units to screen units
if(!pLineControl->pctlLineNum->Create(" ", m_ctlLineNum0.GetStyle(), rWork,
this, m_uiLastID)) return FALSE;
pLineControl->pctlLineNum->ShowWindow(SW_SHOW);
pLineControl->pctlLineNum->SetFont(pcfTemp);
m_uiLastID++;
m_nLastX = rNew.left; // Save new values
m_nLastY = rNew.top;
rCur = rNew;
GetNextRect(&rCur, &rNew, 13, 0, 10, 10); // Lamp
rWork = rNew;
MapDialogRect(&rWork); // convert from dialog base units to screen units
if(!pLineControl->pFrame->Create(" ", m_ctlFrame0.GetStyle(), rWork,
this, m_uiLastID)) return FALSE;
pLineControl->pFrame->ShowWindow(SW_SHOW);
m_uiLastID++;
rCur = rNew;
GetNextRect(&rCur, &rNew, 15, 0, 35, 15); // Action button
rWork = rNew;
MapDialogRect(&rWork);
if(!pLineControl->pbtnAction->Create("Call", m_btnAction0.GetButtonStyle(), rWork,
this, m_uiLastID)) return FALSE;
pLineControl->uiActionID = m_uiLastID;
pLineControl->pbtnAction->ShowWindow(SW_SHOW);
pLineControl->pbtnAction->SetFont(pcfTemp);
m_uiLastID++;
rCur = rNew;
GetNextRect(&rCur, &rNew, 40, 0, 20, 15); // Info button
rWork = rNew;
MapDialogRect(&rWork);
if(!pLineControl->pbtnInfo->Create("Info", m_btnInfo0.GetButtonStyle(), rWork,
this, m_uiLastID)) return FALSE;
pLineControl->uiInfoID = m_uiLastID;
pLineControl->pbtnInfo->ShowWindow(SW_SHOW);
pLineControl->pbtnInfo->SetFont(pcfTemp);
return TRUE;
//may use DeferWindowPos ?...
}
void CTalkDlg::GetNextRect(RECT *pLastRect, RECT *pNewRect, int ndX, int ndY, int nW, int nH)
{
// put bounds check here
pNewRect->top = pLastRect->top + ndY;
pNewRect->bottom = pNewRect->top + nH;
pNewRect->left = pLastRect->left + ndX;
pNewRect->right = pNewRect->left + nW;
}
// Calculate position for new line of controls; resize window if needed
BOOL CTalkDlg::DetermineLinePos(POINT *ppntNew)
{
CRect rctLimit1, rctNew;
CRect rcT(10, 10, 10, 10);
MapDialogRect(&rcT); // isn't it a shame...
//LONG ldbu = GetDialogBaseUnits();
m_ctlLineFrame.GetWindowRect(&rctLimit1);
ScreenToClient(&rctLimit1);
// the real rect
CRect rctLimit((rctLimit1.left*10)/rcT.left, (rctLimit1.top*10)/rcT.top,
(rctLimit1.right*10)/rcT.right ,(rctLimit1.bottom*10)/rcT.bottom);
if(m_nLastY > (rctLimit.bottom - 40)) // resize window; start next row
{
AddColumn();
ppntNew->x = m_nLastX + 100;
ppntNew->y = rctLimit.top + 20; // 25 it should be
}
else
{
ppntNew->x = m_nLastX;
ppntNew->y = m_nLastY + 20;
}
// if(ppntNew->x > (rctLimit1.right - 100)) return FALSE; // need to resize the main wnd
return TRUE;
}
// add a new column of controls
void CTalkDlg::AddColumn()
{
CRect rctMain, rctFrame;
CRect rcT(100, 100, 100, 100);
MapDialogRect(&rcT);
GetWindowRect(&rctMain); // resize main window
rctMain.right += rcT.left; // do everything in dialog units ONLY
MoveWindow(&rctMain);
m_ctlLineFrame.GetWindowRect(&rctFrame); // resize frame
ScreenToClient(&rctFrame);
rctFrame.right += rcT.left; // only horizontally
m_ctlLineFrame.MoveWindow(&rctFrame);
}
void CTalkDlg::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 CTalkDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
// User clicked on Action button; find out what to do & do it
void CTalkDlg::OnAction(DWORD dwIndex)
{
PLINECONTROL plcTemp = &m_LineControls[dwIndex];
LONG lrc;
CTapiCall *pCall = plcTemp->pctlLine->ctlGetActiveCall();
WORD wCallState;
CString csTemp;
LPTSTR lpTemp;
plcTemp->pbtnAction->GetWindowText(csTemp);
plcTemp->pbtnAction->EnableWindow(FALSE); // disable for now
// find out what the line state is
if(pCall == NULL && !csTemp.CompareNoCase("Call")) // no active calls, try to call
{
UpdateData(); // to get m_csDialString
if(m_csDialString.IsEmpty()) lpTemp = NULL;
else lpTemp = m_csDialString.GetBuffer(256);
lrc = plcTemp->pctlLine->ctlLineMakeCall((LPCTSTR)lpTemp, 0);
if(lrc < 0)
{
csTemp.Format("Make call failed reason=%lx", lrc);
MessageBox(csTemp); // restore call state-WHERE?
}
else return;
}
else
{
wCallState = pCall->GetCallState();
switch (wCallState) // find out what to do depending on state
{
case MAKING:
case PROGRESS:
case CONNECTED:
case HOLD:
if(!csTemp.CompareNoCase("Hangup"))
{
((CTalkApp *)AfxGetApp())->m_wLineOptions[dwIndex] &= ~PLAY_ONCE;
plcTemp->pctlLine->ctlLineDrop();
}
return; //break;
case OFFERING:
if(!csTemp.CompareNoCase("Pickup"))
lrc = plcTemp->pctlLine->ctlLineAnswer();
if(lrc < 0) TRACE("*** TALKER32 ***: Answer failed rc=%lx\n",lrc);
break;
case ANSWERING: // do nothing
break;
case DROPPING: // unclear what to do
break;
case DISCONNECTED:
if(!csTemp.CompareNoCase("Hangup"))
plcTemp->pctlLine->ctlLineDrop();
break;
default:
break;
}
}
plcTemp->pbtnAction->EnableWindow(TRUE); // reenable
}
// User clicked on Info button; find out what to do & do it
void CTalkDlg::OnInfo(DWORD dwIndex)
{
CTapiLine *pLine = (&m_LineControls[dwIndex])->pctlLine;
// set the line in the info dialog, let it do the rest
CString csTemp;
csTemp.Format("Line #%d information", dwIndex);
// Always destroy before creation
DestroyPropSheet(dwIndex);
if(m_LineControls[dwIndex].pInfoDlg == NULL) // reallocate brand new
m_LineControls[dwIndex].pInfoDlg = (LPVOID)new CInfo(csTemp, NULL, 0, pLine);
if(m_LineControls[dwIndex].pInfoDlg != NULL)
((CInfo *)m_LineControls[dwIndex].pInfoDlg)->Create();
return;
/***PLINECONTROL plcTemp = &m_LineControls[dwIndex]; // temporary for testing play!!!
CTapiCall *pCall = plcTemp->pctlLine->ctlGetActiveCall();
if(pCall != NULL) pCall->Play("record1.wav");
***/
}
// Update the indicator & other status
void CTalkDlg::UpdateDisplayStatus(DWORD dwLineID)
{
CTapiCall *pCall;
WORD wCallState = IDLE;
DWORD dwError = NULL;
CString csTemp, csWaveName;
int nNum;
if(dwLineID == 0xffff || dwLineID >= m_dwLines) {return;} // update all lines info
PLINECONTROL plcTemp = &m_LineControls[dwLineID];
if(NULL != (pCall = plcTemp->pctlLine->ctlGetActiveCall()))
{
wCallState = pCall->GetCallState(); // No active call==state IDLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -