📄 tapiphonedlg.cpp
字号:
// tapiPhoneDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "tapiPhone.h"
#include "tapiPhoneDlg.h"
#include "tapiPhoneSetupDlg.h"
#include "control.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CtapiPhoneDlg 对话框
CtapiPhoneDlg::CtapiPhoneDlg(CWnd* pParent /*=NULL*/)
: CDialog(CtapiPhoneDlg::IDD, pParent)
, m_AutoAnswer(FALSE)
, m_valStcMsg(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_valEdtNum = "";
m_valCallerNum = "呼入方号码: 当前无呼叫";
}
void CtapiPhoneDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BTN_DISCONNECT, m_btDisconnect);
DDX_Control(pDX, IDC_BTN_CALL, m_btCall);
DDX_Control(pDX, IDC_BTN_CONFIG, m_btConfig);
DDX_Control(pDX, IDC_BTN_PICKUP, m_btPickup);
DDX_Check(pDX, IDC_CHK_AUTO, m_AutoAnswer);
DDX_Text(pDX, IDC_STC_STATUS, m_valStcMsg);
DDX_Text(pDX, IDC_EDIT_NUMBER, m_valEdtNum);
DDX_Text(pDX, IDC_STATIC_, m_valCallerNum);
DDX_Control(pDX, IDC_STC_IMAGE, m_stcImage);
}
BEGIN_MESSAGE_MAP(CtapiPhoneDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTN_PICKUP, OnBnClickedBtnPickup)
//用户自定义消息响应函数
ON_MESSAGE(WM_PRIVATETAPIEVENT, OnTapiEvent)
ON_BN_CLICKED(IDC_CHK_AUTO, OnBnClickedChkAuto)
ON_BN_CLICKED(IDC_BTN_DISCONNECT, OnBnClickedBtnDisconnect)
ON_BN_CLICKED(IDC_BTN_CALL, OnBnClickedBtnCall)
ON_BN_CLICKED(IDC_BTN_EXIT, OnBnClickedBtnExit)
ON_BN_CLICKED(IDC_BTN_CONFIG, OnBnClickedBtnConfig)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CtapiPhoneDlg 消息处理程序
BOOL CtapiPhoneDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将\“关于...\”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO:在此添加额外的初始化代码
//初始化TAPI,在此之前必需调用 AfxOleInit()初始化 COM
//将窗口的句柄 m_hWnd 传给 CTapi,使二者之间建立联系
m_Tapi.m_hWnd = this->m_hWnd;
if( FAILED(m_Tapi.InitializeTapi()) )
{
MessageBox("致命错误:TAPI 初始化失败!");
return FALSE;
}
//
// 初始化按钮状态
//
m_btCall.EnableWindow();
m_btDisconnect.EnableWindow();
m_btPickup.EnableWindow(FALSE);
SetStatusMessage("准备就绪,等待电话呼入...");
// HBITMAP hBitmap;
// m_stcImage.SetBitmap(hBitmap);
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CtapiPhoneDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CtapiPhoneDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CtapiPhoneDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
/////////////////////////////////////////////////////////////////////////////////////
// SetStatusMessage
//
// 显示当前系统消息
/////////////////////////////////////////////////////////////////////////////////////
void CtapiPhoneDlg::SetStatusMessage(CString strMsg)
{
m_valStcMsg = strMsg;
UpdateData(FALSE);
}
/////////////////////////////////////////////////////////////////////////////////////
//
// 以下是用户界面事件响应函数
//
/////////////////////////////////////////////////////////////////////////////////////
void CtapiPhoneDlg::OnBnClickedBtnPickup()
{
//
// 接听电话
//
SetStatusMessage("正在准备接听...");
if ( S_OK == m_Tapi.AnswerTheCall() )
{
SetStatusMessage("通话中");
m_btDisconnect.EnableWindow();
m_btPickup.EnableWindow(FALSE);
}
else
{
m_btPickup.EnableWindow(FALSE);
MessageBox("没有接听成功!");
SetStatusMessage("准备就绪,等待来电...");
}
}
void CtapiPhoneDlg::OnBnClickedChkAuto()
{
//
// 自动接听与手工接听之间切换
//
UpdateData();
}
void CtapiPhoneDlg::OnBnClickedBtnDisconnect()
{
//
// 如果是电话另一方先挂断电话,则 m_pCall 已经挂断并且释放
// 此处不用再次挂断
//
if ( m_Tapi.m_pCall != NULL )
{
SetStatusMessage("正在挂断电话...");
// 挂断电话
if (S_OK != m_Tapi.DisconnectTheCall())
{
MessageBox("挂断电话失败!");
}
else
{
m_btCall.EnableWindow();
m_btPickup.EnableWindow(FALSE);
m_valCallerNum = "呼入方号码: 当前无呼叫";
SetStatusMessage("准备就绪,正在等待电话呼入...");
}
}
}
void CtapiPhoneDlg::OnBnClickedBtnCall()
{
//
// 呼叫号码
//
DWORD dwAddressType;
BSTR szAddressToCall;
UpdateData();
if( m_valEdtNum.GetLength() <= 2 )
return;
szAddressToCall = m_valEdtNum.AllocSysString();
SetStatusMessage( "正在呼叫..." );
dwAddressType = LINEADDRESSTYPE_PHONENUMBER ;
// 开始呼叫
if ( S_OK == m_Tapi.MakeTheCall(dwAddressType, szAddressToCall) )
{
m_btDisconnect.EnableWindow();
m_btPickup.EnableWindow(FALSE);
m_btCall.EnableWindow(FALSE);
}
else
{
MessageBox("呼叫失败!");
}
SysFreeString(szAddressToCall);
// m_Tapi.PreparePlay("Greeting.wav");
}
void CtapiPhoneDlg::OnBnClickedBtnExit()
{
// 退出程序
OnOK();
}
void CtapiPhoneDlg::OnBnClickedBtnConfig()
{
// 把配置对话框中的数据传入
CtapiPhoneSetupDlg SetupDlg;
if(SetupDlg.DoModal() == IDOK)
{
m_Tapi.m_WelcomeFileName = SetupDlg.m_strFileName0;
strFileName0 = SetupDlg.m_strFileName0;
strFileName1 = SetupDlg.m_strFileName1;
strFileName2 = SetupDlg.m_strFileName2;
strPath = SetupDlg.m_strPath;
}
}
///////////////////////////////////////////////////////////////////
// OnTapiEvent
//
// 这是真正的事件处理函数,当 UI 线程接收到 WM_PRIVATETAPIEVENT消息
// 时调用此函数,在 UI 线程中进行事件响应处理
//
///////////////////////////////////////////////////////////////////
LRESULT
CtapiPhoneDlg::OnTapiEvent(
WPARAM wp,
LPARAM lp
)
{
TAPI_EVENT TapiEvent = (TAPI_EVENT)wp;
IDispatch *pEvent = (IDispatch*) lp;
if( TapiEvent == TE_DIGITEVENT )
MessageBox("TE_DIGITEVENT");
else if(TapiEvent == TE_GENERATEEVENT )
MessageBox("TE_GENERATEEVENT");
else if(TapiEvent == TE_GATHERDIGITS)
MessageBox("TE_GATHERDIGITS");
switch ( TapiEvent )
{
case TE_CALLNOTIFICATION:
{
//
// TE_CALLNOTIFICATION: 程序发现一个呼入的电话
//
TRACE("Event:-----------TE_CALLNOTIFICATION----------Event\n");
DoCallNotification(pEvent);
break;
}//TE_CALLNOTIFICATION
case TE_CALLSTATE:
{
//
// TE_CALLSTATE: 程序发现整个 Call 过程状态有变化
//
TRACE("Event:-----------TE_CALLSTATE----------Event\n");
DoCallState(pEvent);
break;
}//TE_CALLSTATE
case TE_CALLMEDIA:
{
//
// TE_CALLMEDIA:关于媒体的事件,如有某种媒体到达
//
TRACE("Event:-----------TE_CALLMEDIA----------Event\n");
DoCallMedia(pEvent);
break;
}//TE_CALLMEDIA
case TE_FILETERMINAL:
{
//
// TE_FILETERMINAL:文件终端事件,只在 TAPI3.1 中支持
//
TRACE("Event:-----------TE_FILETERMINAL----------Event\n");
DoFileEvent(pEvent);
break;
}//TE_FILETERMINAL
case TE_DIGITEVENT:
{
//
// TE_DIGIT:接受到按键事件
//
TRACE("Event:-----------TE_DIGITEVENT----------Event\n");
DoDigitEvent(pEvent);
break;
}
default:
break;
}
pEvent->Release(); // 因为在 CTAPIEventNotification::Event() 中调用过 AddRef
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////
// 处理 TE_NOTIFICATION 事件,有新电话打入时触发此事件
// 功能:
// 1、获取拨入方信息,主要是对方电话号码或IP
// 2、获取 ITBasicCallControl,存入 m_pCall,
// 3、更新用户界面
// 注意:不能在此时就应答电话,应用程序应当等待 TE_CALLSTATE 事件触发并判断当前事件为
// CS_OFFERING 时才可以。
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoCallNotification( IN IDispatch * pEvent)
{
//
//通过接口 ITCallNotificationEvent 可以获得所有关于拨入事件的信息,这里主要用来得到 ITCallInfo
//
ITCallNotificationEvent * pNotify;
HRESULT hr;
hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify );
if (S_OK != hr)
{
MessageBox( "有电话乎入,但获得接口 ITCallNotificationEvent 失败!");
}
else
{
//
//通过 ITCallInfo 获得拨入方信息,如拨入方电话号码等
//
CALL_PRIVILEGE cp;
ITCallInfo * pCall;
//
// 得到 ITCallInfo 的指针
//
hr = pNotify->get_Call( &pCall );
pNotify->Release();
if ( SUCCEEDED(hr) )
{
//
// 检测我们对 call 是否拥有 owner 权限
//
hr = pCall->get_Privilege( &cp );
if ( FAILED(hr) || (CP_OWNER != cp) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -