📄 tmonitorview.cpp
字号:
// Sort by rings, date/time and name
case colRings:
nCompare = pcr1->nRings - pcr2->nRings;
if( !nCompare )
{
nCompare = pcr1->tmStart - pcr2->tmStart;
if( !nCompare )
{
nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
}
}
break;
// Sort by result, date/time and name
case colState:
nCompare = strcmp(g_pszStateName[BitSet(pcr1->nState)],
g_pszStateName[BitSet(pcr2->nState)]);
if( !nCompare )
{
nCompare = pcr1->tmStart - pcr2->tmStart;
if( !nCompare )
{
nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
}
}
break;
default:
TRACE1("CompareItems(): Unknown nSortCol= %d\n", psp->nColumn);
ASSERT(FALSE);
break;
}
// Check for descending sort
if( !psp->bAscending )
{
nCompare = (0 - nCompare);
}
return nCompare;
}
void CtMonitorView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
m_sp.nColumn = ((NM_LISTVIEW*)pNMHDR)->iSubItem;
m_sp.bAscending = (::GetKeyState(VK_SHIFT) < 0 ? FALSE : TRUE);
GetListCtrl().SortItems(CompareItems, LPARAM(&m_sp));
*pResult = 0;
}
// Let the document handle this
void CtMonitorView::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
delete (CALLRECORD*)(pNMListView->lParam);
*pResult = 0;
}
// Override so base class can do it's magic
LPCSTR CtMonitorView::GetColumnText(int nColumn, LPARAM lParam)
{
CALLRECORD* pcr = (CALLRECORD*)(lParam);
switch( nColumn )
{
case colName:
return pcr->sName;
break;
case colPhoneNo:
return pcr->sPhoneNo;
break;
case colDateTime:
{
static char szBuf[64];
strftime(szBuf, sizeof(szBuf), "%#c", localtime(&(pcr->tmStart)));
return szBuf;
}
break;
case colDuration:
{
static char szBuf[32];
sprintf(szBuf, "%d min. %d sec.",
pcr->GetDuration()/60, pcr->GetDuration()%60);
return szBuf;
}
break;
case colRings:
{
static char szBuf[8];
return ::ltoa(pcr->nRings, szBuf, 10);
}
break;
case colState:
return g_pszStateName[BitSet(pcr->nState)];
break;
default:
TRACE1("Unknown nColumn= %d\n", nColumn);
return 0;
break;
}
}
// Don't need this if I'm doing owner-draw,
// except to handle finding entries by typing
void CtMonitorView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
if( pDispInfo->item.mask & LVIF_TEXT )
{
LV_ITEM& lvi = pDispInfo->item;
lvi.pszText = LPSTR(GetColumnText(lvi.iSubItem, lvi.lParam));
}
*pResult = 0;
}
void CtMonitorView::OnReturn(NMHDR* pNMHDR, LRESULT* pResult)
{
DoDial();
*pResult = 0;
}
void CtMonitorView::OnDestroy()
{
CWinApp* pApp = ::AfxGetApp();
pApp->WriteProfileInt("Settings", "SortColumn", m_sp.nColumn);
pApp->WriteProfileInt("Settings", "SortAscending", m_sp.bAscending);
CListCtrl& lc = GetListCtrl();
char szEntry[16];
// Save column headers
CHeaderCtrl* pHeader = GetHeaderCtrl();
ASSERT(pHeader);
for( int i = 0; i < pHeader->GetItemCount(); i++ )
{
::wsprintf(szEntry, "ColumnWidth%d", i);
pApp->WriteProfileInt("Settings", szEntry, lc.GetColumnWidth(i));
}
CListViewEx::OnDestroy();
}
CHeaderCtrl* CtMonitorView::GetHeaderCtrl()
{
return (CHeaderCtrl*)GetDlgItem(0);
}
void CtMonitorView::OnMonitorDial()
{
DoDial();
}
void CtMonitorView::OnUpdateMonitorDial(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetListCtrl().GetNextItem(-1, LVNI_SELECTED) >= 0);
}
void CtMonitorView::OnViewAutosizecolumns()
{
CListCtrl& lc = GetListCtrl();
CHeaderCtrl* pHeader = GetHeaderCtrl();
for( int i = 0; i < pHeader->GetItemCount(); i++ )
{
lc.SetColumnWidth(i, LVSCW_AUTOSIZE);
//lc.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
}
}
void CtMonitorView::OnUpdateViewAutosizecolumns(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetListCtrl().GetItemCount() > 0 ? TRUE : FALSE);
}
void CtMonitorView::MonitorCall(
CtLine* pLine,
HCALL hCall)
{
CtCallInfo ci;
CString sName;
CString sPhoneNo;
BOOL bInbound = FALSE;
if( SUCCEEDED(ci.GetCallInfo(hCall)) )
{
switch( ci.GetOrigin() )
{
case LINECALLORIGIN_OUTBOUND:
sName = ci.GetCalledParty();
sPhoneNo = ci.GetDisplayableAddress();
if( sName.IsEmpty() ) sName = "<unknown>";
if( sPhoneNo.IsEmpty() ) sPhoneNo = "<unknown>";
/*
TRACE0("Outbound Call Info:\n");
TRACE1("CallerID= %s\n", ci.GetCallerID());
TRACE1("CallerIDName= %s\n", ci.GetCallerIDName());
TRACE1("CalledID= %s\n", ci.GetCalledID());
TRACE1("CalledIDName= %s\n", ci.GetCalledIDName());
TRACE1("ConnectedID= %s\n", ci.GetConnectedID());
TRACE1("ConnectedIDName= %s\n", ci.GetConnectedIDName());
TRACE1("RedirectionID= %s\n", ci.GetRedirectionID());
TRACE1("RedirectionIDName= %s\n", ci.GetRedirectionIDName());
TRACE1("RedirectingID= %s\n", ci.GetRedirectingID());
TRACE1("RedirectingIDName= %s\n", ci.GetRedirectingIDName());
TRACE1("AppName= %s\n", ci.GetAppName());
TRACE1("DisplayableAddress= %s\n", ci.GetDisplayableAddress());
TRACE1("CalledParty= %s\n", ci.GetCalledParty());
TRACE1("Comment= %s\n", ci.GetComment());
TRACE1("Display= %s\n", ci.GetDisplay());
*/
break;
case LINECALLORIGIN_INTERNAL:
case LINECALLORIGIN_EXTERNAL:
case LINECALLORIGIN_UNKNOWN:
case LINECALLORIGIN_UNAVAIL:
case LINECALLORIGIN_INBOUND:
bInbound = TRUE;
// no break;
default:
GetBestCallerID(ci, &sName, &sPhoneNo);
break;
}
}
CtCall* pCall = new CtCall(pLine, hCall, this);
CALLRECORD* pcr = new CALLRECORD(sName, sPhoneNo, LINECALLSTATE_UNKNOWN, pCall, bInbound);
if( pcr && AppendCallRecord(pcr) )
{
// If this is the first active call,
// set the timer to update duration
if( ++m_nActiveCalls == 1 )
{
m_nTimer = SetTimer(1, 5000, 0);
}
}
}
// Handle telephony events of interest
void CtMonitorView::OnLineNewCall(
CtLine* pLine,
HCALL hCall,
DWORD nAddressID,
DWORD nCallPriviledge)
{
MonitorCall(pLine, hCall);
}
void CtMonitorView::OnLineDevState(
CtLine* pLine,
DWORD nDevState,
DWORD dwParam2,
DWORD dwParam3)
{
if( nDevState == LINEDEVSTATE_RINGING )
{
// Update the view
CALLRECORD* pcr;
int nItem;
if( FindCallRecord(pLine, &pcr, &nItem) )
{
ASSERT(pcr);
pcr->nState = LINECALLSTATE_RINGBACK;
pcr->nRings = dwParam3;
GetListCtrl().Update(nItem);
}
// If we've reached the number of rings, take a message
if( pcr->nMaxRings && pcr->nRings >= pcr->nMaxRings )
{
pcr->pdlg->OnTakeMessage();
}
}
}
void CtMonitorView::OnCallInfo(
CtCall* pCall,
DWORD nCallInfo)
{
// Possible to get several callinfo
// notifications in one message.
if( nCallInfo & LINECALLINFOSTATE_CALLERID )
{
CALLRECORD* pcr;
int nItem;
if( FindCallRecord(pCall, &pcr, &nItem) )
{
ASSERT(pcr);
CtCallInfo ci;
if( TSUCCEEDED(ci.GetCallInfo(pCall)) )
{
GetBestCallerID(ci, &(pcr->sName), &(pcr->sPhoneNo));
pcr->UpdateDialog();
GetListCtrl().Update(nItem);
}
}
}
}
void CtMonitorView::OnCallState(
CtCall* pCall,
DWORD nCallState,
DWORD dwParam2,
DWORD nCallPriviledge)
{
CALLRECORD* pcr;
int nItem;
if( FindCallRecord(pCall, &pcr, &nItem) )
{
ASSERT(pcr);
pcr->nState = nCallState;
switch( nCallState )
{
case LINECALLSTATE_RINGBACK:
// Update the number of rings
// (outgoing calls only)
pcr->nRings++;
break;
case LINECALLSTATE_DISCONNECTED:
pCall->Drop();
break;
case LINECALLSTATE_IDLE:
// When TAPI's done w/ a call, so are we
pcr->SetCallIdle();
// If this is the last active call,
// kill the timer
if( --m_nActiveCalls == 0 )
{
KillTimer(m_nTimer);
m_nTimer = 0;
}
break;
}
GetListCtrl().Update(nItem);
}
}
void CtMonitorView::OnTimer(UINT nIDEvent)
{
// Walk the list for active calls
CListCtrl& lc = GetListCtrl();
for( int nItem = 0; nItem < lc.GetItemCount(); nItem++ )
{
CALLRECORD* pcr = (CALLRECORD*)lc.GetItemData(nItem);
ASSERT(pcr);
// Updating the item will show a new duration
if( !pcr->tmEnd )
{
lc.Update(nItem);
}
}
}
void CtMonitorView::OnViewMessages()
{
const CString sMessages = "Messages";
CString sPathName;
GetModuleFileName(0, sPathName.GetBuffer(MAX_PATH+1), MAX_PATH);
sPathName.ReleaseBuffer();
sPathName = sPathName.Left(sPathName.ReverseFind('\\'));
sPathName += '\\';
sPathName += sMessages;
sPathName += '\\';
if( !SetCurrentDirectory(sPathName) &&
!CreateDirectory(sPathName, 0) )
{
TRACE1("Failed to create messages directory: %s\n", (LPCSTR)sPathName);
}
if( (int)ShellExecute(GetSafeHwnd(), "open", sPathName, 0, sPathName, SW_SHOWDEFAULT) <= 32 )
{
AfxMessageBox(IDS_CANT_OPEN_MESSAGES);
}
}
void CtMonitorView::OnMonitorCallScreenSettings()
{
CWinApp* pApp = ::AfxGetApp();
CCallScreenDlg dlg;
dlg.m_nRings = pApp->GetProfileInt("Settings", "Rings", 4);
if( dlg.DoModal() == IDOK )
{
pApp->WriteProfileInt("Settings", "Rings", dlg.m_nRings);
SetNumRings(dlg.m_nRings);
}
}
void CtMonitorView::SetNumRings(DWORD nRings)
{
if( m_rgLines )
{
for( DWORD nLineID = 0; nLineID < ::TfxGetNumLines(); nLineID++ )
{
if( m_rgLines[nLineID].GetHandle() )
{
CtLineDevCaps ldc;
if( TSUCCEEDED(ldc.GetDevCaps(nLineID)) )
{
for( DWORD nAddressID = 0; nAddressID < ldc.GetNumAddresses(); nAddressID++ )
{
m_rgLines[nLineID].SetNumRings(nAddressID, nRings);
}
}
}
}
}
}
void CtMonitorView::OnViewLines()
{
CLinesDlg dlg;
dlg.m_rgLines = m_rgLines;
dlg.DoModal();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -