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

📄 tmonitorview.cpp

📁 使用环境VC++ 6.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// tMonitorView.cpp : implementation of the CtMonitorView class
//

#include "stdafx.h"
#include "tMonitor.h"

#include "tMonitorDoc.h"
#include "tMonitorView.h"
#include "tPhoneNo.h"
#include "CallScreenDlg.h"
#include "LinesDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CtMonitorView

enum ListColumn
{
    colName = 0,
    colPhoneNo,
    colDateTime,
    colDuration,
    colRings,
    colState,
    colColumns,
};

static
const char* g_pszStateName[] = 
{
    "Over", // Idle
    "Offering",
    "Accepted",
    "Dial Tone",
    "Dialing",
    "Ringing",
    "Busy",
    "Special Info",
    "Connect",
    "Proceeding",
    "On Hold",
    "Conferenced",
    "On Hold Pending Conference",
    "On Hold Pending Transfer",
    "Disconnected",
    "Unknown",
};

// Translate bit field into the single set bit
// (0-based, of course)
static
int BitSet(DWORD dw)
{
    if( !dw ) return -1;

    int nBitSet = 0;
    while( !(dw & 1) )
    {
        //dw /= 2;
        dw = dw >> 1;
        nBitSet++;
    }
    
    return nBitSet;
}

static
void GetBestCallerID(
    const CtCallInfo&   ci,
    CString*            psName,
    CString*            psPhoneNo)
{
    LPCSTR      pszName = 0;
    LPCSTR      pszPhoneNo = 0;
    CtPhoneNo   pno;
    
    if( ci.GetCallerIDFlags() & LINECALLPARTYID_BLOCKED )
    {
        pszName = "<blocked>";
        pszPhoneNo = "<blocked>";
    }
    else if( ci.GetCallerIDFlags() & LINECALLPARTYID_OUTOFAREA )
    {
        pszName = "<out of area>";
        pszPhoneNo = "<out of area>";
    }
    else if( ci.GetCallerIDFlags() & LINECALLPARTYID_UNKNOWN )
    {
        pszName = "<unknown>";
        pszPhoneNo = "<unknown>";
    }
    else if( ci.GetCallerIDFlags() & LINECALLPARTYID_UNAVAIL )
    {
        pszName = "<unavailable>";
        pszPhoneNo = "<unavailable>";
    }
    else
    {
        pszName = ci.GetCallerIDName();

        pno.SetWholePhoneNo(ci.GetCallerID());
        pszPhoneNo = pno.GetTranslatable(0);
    }
    
    *psName = (pszName ? pszName : "<unknown>");
    *psPhoneNo = (pszPhoneNo ? pszPhoneNo : "<unknown>");
}

IMPLEMENT_DYNCREATE(CtMonitorView, CListView)

BEGIN_MESSAGE_MAP(CtMonitorView, CListView)
	//{{AFX_MSG_MAP(CtMonitorView)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
	ON_NOTIFY_REFLECT(NM_RETURN, OnReturn)
	ON_WM_DESTROY()
	ON_COMMAND(ID_MONITOR_DIAL, OnMonitorDial)
	ON_UPDATE_COMMAND_UI(ID_MONITOR_DIAL, OnUpdateMonitorDial)
	ON_COMMAND(ID_VIEW_AUTOSIZECOLUMNS, OnViewAutosizecolumns)
	ON_UPDATE_COMMAND_UI(ID_VIEW_AUTOSIZECOLUMNS, OnUpdateViewAutosizecolumns)
	ON_WM_TIMER()
	ON_COMMAND(ID_VIEW_MESSAGES, OnViewMessages)
	ON_COMMAND(ID_MONITOR_CALLSCREENSETTINGS, OnMonitorCallScreenSettings)
	ON_COMMAND(ID_VIEW_LINES, OnViewLines)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CtMonitorView construction/destruction

CtMonitorView::CtMonitorView()
    :
    m_sp(0, TRUE),
    m_bViewInited(FALSE),
    m_nActiveCalls(0),
    m_nTimer(0),
    m_rgLines(0)
{
}

CtMonitorView::~CtMonitorView()
{
    delete[] m_rgLines;
}

BOOL CtMonitorView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style |= LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED;
	return CListViewEx::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CtMonitorView drawing

void CtMonitorView::OnDraw(CDC* pDC)
{
	CtMonitorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
}

void CtMonitorView::OpenValidLines()
{
    // Open all of the lines to watch for new calls
    if( m_rgLines = new CtLine[::TfxGetNumLines()] )
    {
        for( DWORD nLineID = 0; nLineID < ::TfxGetNumLines(); nLineID++ )
        {
            TRESULT tr;

            // NOTE: Need automated voice to be able to generate digits
            // NOTE: Need unknown to be able to get incoming calls
            tr = m_rgLines[nLineID].Open(nLineID, this,
                                         LINECALLPRIVILEGE_MONITOR | LINECALLPRIVILEGE_OWNER,
                                         LINEMEDIAMODE_UNKNOWN | LINEMEDIAMODE_AUTOMATEDVOICE);
            if( FAILED(tr) )
            {
                // If we can't do automated voice, drop back and punt
                tr = m_rgLines[nLineID].Open(nLineID, this,
                                             LINECALLPRIVILEGE_MONITOR);
            }

            // Check for existing calls
            if( TSUCCEEDED(tr) )
            {
                CtCallList  cl;
                if( TSUCCEEDED(cl.GetNewCalls(m_rgLines[nLineID].GetHandle())) )
                {
                    for( DWORD nCall = 0; nCall < cl.GetNumCalls(); nCall++ )
                    {
                        MonitorCall(&m_rgLines[nLineID], cl.GetCall(nCall));
                    }
                }
            }
        }

        SetNumRings(::AfxGetApp()->GetProfileInt("Settings", "Rings", 4));
    }
}

void CtMonitorView::OnInitialUpdate()
{
    // Guard against re-initing during SDI view reuse
    if( !m_bViewInited )
    {
        CWinApp*    pApp = ::AfxGetApp();
        m_sp.nColumn = pApp->GetProfileInt("Settings", "SortColumn", m_sp.nColumn);
        m_sp.bAscending = pApp->GetProfileInt("Settings", "SortAscending", m_sp.bAscending);

        int         acxColumns[colColumns];
        char        szEntry[16];

        // Set up column headers
        CRect       rect;
        GetClientRect(&rect);
        int         nDefaultWidth = rect.Width()/colColumns;

        for( int i = 0; i < colColumns; i++ )
        {
            ::wsprintf(szEntry, "ColumnWidth%d", i);
            acxColumns[i] = pApp->GetProfileInt("Settings", szEntry, nDefaultWidth);
        }

        CListCtrl&  lc = GetListCtrl();

        lc.InsertColumn(colName, "Name", LVCFMT_LEFT, acxColumns[colName]);
        lc.InsertColumn(colPhoneNo, "Phone No.", LVCFMT_LEFT, acxColumns[colPhoneNo]);
        lc.InsertColumn(colDateTime, "Date/Time",  LVCFMT_LEFT, acxColumns[colDateTime]);
        lc.InsertColumn(colDuration, "Duration",  LVCFMT_LEFT, acxColumns[colDuration]);
        lc.InsertColumn(colRings, "Rings",  LVCFMT_LEFT, acxColumns[colRings]);
        lc.InsertColumn(colState, "State",  LVCFMT_LEFT, acxColumns[colState]);

        OpenValidLines();

        m_bViewInited = TRUE;
    }

    // Call parent (which calls OnUpdate())
    CListViewEx::OnInitialUpdate();
}

BOOL CtMonitorView::AppendCallRecord(
    CALLRECORD* pcr)
{
    if( pcr )
    {
        CListCtrl&  lc = GetListCtrl();
        return (lc.InsertItem(LVIF_TEXT | LVIF_PARAM, lc.GetItemCount(),
                              LPSTR_TEXTCALLBACK, 0, 0, 0, LPARAM(pcr)) >= 0
                ? TRUE : FALSE);
    }
    else
    {
        return FALSE;
    }
}

BOOL CtMonitorView::FindCallRecord(
    CtCall*         pCall,
    CALLRECORD**    ppcr,
    int*            pnItem)
{
    ASSERT(pCall);
    ASSERT(ppcr);
    ASSERT(pnItem);

    CListCtrl&  lc = GetListCtrl();
    for( int nItem = 0; nItem < lc.GetItemCount(); nItem++ )
    {
        CALLRECORD* pcr = (CALLRECORD*)lc.GetItemData(nItem);
        ASSERT(pcr);

        if( pcr->pCall == pCall )
        {
            *ppcr = pcr;
            *pnItem = nItem;
            return TRUE;
        }
    }

    *ppcr = 0;
    *pnItem = 0;
    return FALSE;
}

BOOL CtMonitorView::FindCallRecord(
    CtLine*         pLine,
    CALLRECORD**    ppcr,
    int*            pnItem)
{
    ASSERT(pLine);
    ASSERT(ppcr);
    ASSERT(pnItem);

    CListCtrl&  lc = GetListCtrl();
    for( int nItem = 0; nItem < lc.GetItemCount(); nItem++ )
    {
        CALLRECORD* pcr = (CALLRECORD*)lc.GetItemData(nItem);
        ASSERT(pcr);

        if( pcr->pCall &&
            pcr->pCall->GetLine() == pLine )
        {
            *ppcr = pcr;
            *pnItem = nItem;
            return TRUE;
        }
    }

    *ppcr = 0;
    *pnItem = 0;
    return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CtMonitorView diagnostics

#ifdef _DEBUG
void CtMonitorView::AssertValid() const
{
	CListViewEx::AssertValid();
}

void CtMonitorView::Dump(CDumpContext& dc) const
{
	CListViewEx::Dump(dc);
}

CtMonitorDoc* CtMonitorView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CtMonitorDoc)));
	return (CtMonitorDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CtMonitorView message handlers

void CtMonitorView::DoDial()
{
    CListCtrl&  lc = GetListCtrl();
    int         nItem = lc.GetNextItem(-1, LVNI_SELECTED);

    if( nItem >= 0 )
    {
        CALLRECORD* pcr = (CALLRECORD*)lc.GetItemData(nItem);
        ASSERT(pcr);

        // Check for a non-empty and non-special phone number
        if( !pcr->sPhoneNo.IsEmpty() && pcr->sPhoneNo[0] != '<' )
        {
            // Translate the phone number the best we can
            // to canonical or at least all number format
            CtPhoneNo   pno(pcr->sPhoneNo);
            TRESULT     tr = ::tapiRequestMakeCall(pno.GetTranslatable(),
                                                   ::AfxGetAppName(), pcr->sName, 0);
            switch( tr )
            {
            case TAPIERR_NOREQUESTRECIPIENT:
                ::AfxMessageBox(IDS_NOREQUESTRECIPIENT);
            break;

            case TAPIERR_REQUESTQUEUEFULL:
                ::AfxMessageBox(IDS_REQUESTQUEUEFULL);
            break;

            case TAPIERR_INVALDESTADDRESS:
                ::AfxMessageBox(IDS_INVALDESTADDRESS);
            break;

            case TAPIERR_INVALPOINTER:
                TRACE("TAPIERR_INVALPOINTER\n");
                ASSERT(FALSE);
            break;
            }
        }
    }
}

void CtMonitorView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
    DoDial();
	*pResult = 0;
}

int CALLBACK CompareItems(LPARAM lP1, LPARAM lP2, LPARAM lPSort)
{
    CtMonitorView::CALLRECORD*  pcr1 = (CtMonitorView::CALLRECORD*)lP1;
    CtMonitorView::CALLRECORD*  pcr2 = (CtMonitorView::CALLRECORD*)lP2;
    CtMonitorView::SORTPARAMS*  psp = (CtMonitorView::SORTPARAMS*)lPSort;
    int                         nCompare;

    // Compare assuming ascending sorting
    switch( psp->nColumn )
    {
    // Sort by name and date/time
    case colName:
        nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
        if( !nCompare )
        {
            nCompare = pcr1->tmStart - pcr2->tmStart;
        }
    break;

    // Sort by phone no., name and date/time
    case colPhoneNo:
        nCompare = pcr1->sPhoneNo.CompareNoCase(pcr2->sPhoneNo);
        if( !nCompare )
        {
            nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
            if( !nCompare )
            {
                nCompare = pcr1->tmStart - pcr2->tmStart;
            }
        }
    break;

    // Sort by date/time and name
    case colDateTime:
        nCompare = pcr1->tmStart - pcr2->tmStart;
        if( !nCompare )
        {
            nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
        }
    break;

    // Sort by duration and name
    case colDuration:
        nCompare = pcr1->GetDuration() - pcr2->GetDuration();
        if( !nCompare )
        {
            nCompare = pcr1->sName.CompareNoCase(pcr2->sName);
        }
    break;

⌨️ 快捷键说明

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