📄 mainframe.cpp
字号:
#include "StdAfx.h"
#include "App.h"
#include "MainFrame.h"
IMPLEMENT_DYNAMIC(MainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_DESTROY()
END_MESSAGE_MAP()
typedef struct ConInfo
{
int recNum;
};
struct ConInfo conInfo[50] = {0};
// ENG: Channel list
// CHS: 通道列表
Channel *channels;
BOOL IsStartCti;
// ENG: Conference_id - master_channel pair
// CHS: 会议号-主持人通道 对
map<int, int> cm_pair;
int total_ch;
int recNumber = 0;
// ENG: Master Channel Configure
// CHS: 主持人通道
// ENG: Reserved channels
// CHS: 保留通道
int master[] = {0, 1, 2, 3};
const int master_num = sizeof(master) / sizeof(int);
// ENG: Add files to playlist by num.
// Example: if num = 12, it will add 1.wav and 2.wav to the playlist of ch.
// CHS: 根据参数 num 将需要的文件加到播放列表。
// 例如:如果 num = 12,那么本函数将添加 1.wav 和 2.wav 到 ch 通道的播放列表。
void add_list(int ch, long num)
{
int a = log10(num);
int d;
char s[2];
char file[100];
while (a >= 0)
{
// ENG: Get first bit (10-based)
// CHS: 取第一位
d = num / pow(10, a);
num -= d * pow(10, a--);
itoa(d, s, 10);
// ENG: Cat a filename
// CHS: 拼接文件名
strcpy(file, ".\\wav\\");
strcat(file, s);
strcat(file, ".wav");
// ENG: Add to the playlist
// CHS: 添加到文件列表
CHECK_RETURN SsmAddToFileList(ch, file, -1, 0, -1);
}
}
// ENG: Get its master channel of the parameter 'conf'
// CHS: 返回会议号 conf 的主持人通道号。
int get_master(int conf)
{
return cm_pair.find(conf)->second;
}
// ENG: Get master channel of the conf that parameter 'channel' joined.
// CHS: 返回通道 channel 加入的会议的主持人通道号。
int get_chs_master(int channel)
{
int GrpId, MmbrId;
DWORD SilenceTime;
WORD JoinMode, IsSpeaking;
CHECK_RETURN SsmGetConfChInfo(channel, &GrpId, &MmbrId, &JoinMode, &IsSpeaking, &SilenceTime);
return get_master(GrpId);
}
// ENG: get an idle channel for the master from the array master
// CHS: 从数组 master 中返回一个空闲的通道给主持人使用。
int get_idle()
{
for (int i = 0; i < total_ch; i++)
{
if (channels[i].master == MASTER_IDLE)
return i;
}
return -1;
}
// ENG: check whether the two channel are in the same conference
// CHS: 检查这两个通道是否是在同一个会议中。
bool is_same_group(int ch1, int ch2)
{
int group1, group2;
int tmp;
WORD tmp2;
DWORD tmp3;
if (SsmGetConfChInfo(ch1, &group1, &tmp, &tmp2, &tmp2, &tmp3) == -1)
return false;
if (SsmGetConfChInfo(ch2, &group2, &tmp, &tmp2, &tmp2, &tmp3) == -1)
return false;
return (group1 == group2);
}
// ENG: UI and something unimportant
// CHS: 用户界面和一些不重要的东西
int MainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWnd::OnCreate(lpCreateStruct);
EVENT_SET_INFO EventSet;
int i;
// ENG: CTI Board initalizes
// CHS: CTI 板卡初始化
IsStartCti = FALSE;
if (SsmStartCti(".\\shconfig.ini", ".\\shindex.ini") != 0)
{
CString sdfs = SsmGetLastErrMsgA();
MessageBox(SsmGetLastErrMsgA(), _T("Conference Demo"), MB_OK | MB_ICONWARNING);
DestroyWindow();
}
else if (SsmGetMaxUsableBoard() != SsmGetMaxCfgBoard())
{
MessageBox(SsmGetLastErrMsgA(), _T("Conference Demo"), MB_OK | MB_ICONWARNING);
DestroyWindow();
}
else
{
IsStartCti = TRUE;
EventSet.dwWorkMode = EVENT_MESSAGE;
EventSet.lpHandlerParam = this->GetSafeHwnd();
CHECK_RETURN SsmSetEvent(-1, -1, TRUE, &EventSet);
total_ch = SsmGetMaxCh();
if (total_ch >= master_num)
{
channels = new Channel[total_ch];
for (i = 0; i < total_ch; i++)
{
channels[i].state_channel = CH_IDLE;
channels[i].state_conference = CO_IDLE;
channels[i].type = SsmGetChType(i);
channels[i].master = NOT;
channels[i].BgSoundEnabled = false;
channels[i].IsPlayingBgSound = false;
channels[i].BgSoundVolume = 0;
channels[i].ch_to_talk_securely = -1;
}
for(i = 0; i < master_num; i++)
{
if (master[i] < total_ch)
{
channels[master[i]].master = MASTER_IDLE;
}
}
}
else
{
MessageBox("Can not get enough channels.", _T("Conference Demo"), MB_OK | MB_ICONWARNING);
DestroyWindow();
}
SetTimer(0, 100, NULL);
}
return 0;
}
BOOL MainFrame::DestroyWindow()
{
CFrameWnd::DestroyWindow();
return TRUE;
}
void MainFrame::OnDestroy()
{
if (IsStartCti)
{
delete[] channels;
SsmCloseCti();
}
return;
}
BOOL MainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
wndSplitter.CreateStatic(this, 1, 2);
wndSplitter.CreateView(0, 0, RUNTIME_CLASS(LeftView), CSize(400, 100), pContext);
wndSplitter.CreateView(0, 1, RUNTIME_CLASS(ChildView), CSize(400, 100), pContext);
wndStatusBar.Create(this);
return TRUE;
}
BOOL MainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
CFrameWnd::PreCreateWindow(cs);
return TRUE;
}
BOOL MainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (wndSplitter.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
else
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
// ENG: Deal with Synway messages.
// It is important for the demo and you may refer here.
// CHS: 处理三汇的用户消息。
// 这一部分对本程序很重要,您可能需要作参考。
LRESULT MainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
int new_state;
int ch;
char dtmf;
if (message >= WM_USER)
{
ch = wParam;
switch (message - WM_USER)
{
// ENG: Here is about the channel state, it will send unitive messages to the conference.
// For more details, please see Channel flowchart.
// CHS: 这里是关于通道状态的代码,它将发送统一的消息给会议。
// 欲了解详情,请参考通道状态转移图。
case E_CHG_ChState:
new_state = lParam & 0x00FF;
// ENG: Trunk and digital
// CHS: 外线和数字
if (channels[ch].type == 0 ||
channels[ch].type == 4 ||
channels[ch].type == 6 ||
channels[ch].type == 7 ||
channels[ch].type == 8 ||
channels[ch].type == 11 ||
channels[ch].type == 16 ||
channels[ch].type == 17
)
{
if( channels[ch].state_channel == CH_INVITEUSER)
{
if( new_state == 3)
{
channels[ch].state_channel = CH_TALK;
channels[ch].creater = false;
channels[ch].dtmf_str.erase(channels[ch].dtmf_str.begin(), channels[ch].dtmf_str.end());
CHECK_RETURN SsmPlayFile(ch, ".\\wav\\c.wav", -1, 0, -1);
SsmSetDtmfStopPlay(ch, TRUE);
channels[ch].state_conference = CO_HOW_TO_JOIN;
}
else if(new_state = S_CALL_STANDBY || new_state == S_CALL_PENDING)
{
CHECK_RETURN SsmHangup(ch);
channels[ch].state_channel = CH_IDLE;
}
}
else if (new_state == 2 && channels[ch].state_channel == CH_IDLE)
{
CHECK_RETURN SsmPickup(ch);
channels[ch].state_channel = CH_WAIT_TALK;
}
else if (new_state == 3 && channels[ch].state_channel == CH_WAIT_TALK)
{
PostMessage(TO_START, ch);
channels[ch].state_channel = CH_TALK;
}
else if (channels[ch].state_channel == CH_WAIT_TALK && (channels[ch].type != 16 && channels[ch].type != 17))
{
CHECK_RETURN SsmHangup(ch);
channels[ch].state_channel = CH_IDLE;
}
else if (channels[ch].state_channel == CH_TALK || S_CALL_PENDING == SsmGetChState(ch))
{
CHECK_RETURN SsmHangup(ch);
PostMessage(TO_END, ch);
channels[ch].state_channel = CH_IDLE;
}
}
// ENG: Station
// CHS: 坐席
else if (channels[ch].type == 2)
{
if (new_state == 1 && channels[ch].state_channel == CH_IDLE)
{
PostMessage(TO_START, ch);
channels[ch].state_channel = CH_TALK;
}
else if (new_state == 0 && channels[ch].state_channel == CH_TALK)
{
PostMessage(TO_END, ch);
channels[ch].state_channel = CH_IDLE;
}
}
break;
// ENG: Here is about dtmf for each choice.
// CHS: 用于选择的 DTMF 音。
case E_CHG_RcvDTMF:
// Arc 4
if (channels[ch].state_conference == CO_CREATE_OR_JOIN)
{
dtmf = lParam & 0x00FF;
if (dtmf == '*')
{
if (channels[ch].dtmf_str.length() != 0)
{
char szRecFile[MAX_PATH];
strcpy(szRecFile, ".\\rec\\");
strcat(szRecFile, channels[ch].dtmf_str.c_str());
strcat(szRecFile, ".wav");
CHECK_RETURN SsmSetDtmfStopPlay(ch, TRUE);
CHECK_RETURN SsmAddToFileList(ch, szRecFile, -1, 0, -1);
CHECK_RETURN SsmPlayFileList(ch);
channels[ch].dtmf_str.erase(channels[ch].dtmf_str.begin(), channels[ch].dtmf_str.end());
break;
}
break;
}
if (dtmf == '#')
{
// ENG: To create
// CHS: 创建
if (channels[ch].dtmf_str.length() == 0)
{
// ENG: Create a conference.
// CHS: 创建一个会议。
int conf_id = SsmCreateConfGroup(8, 8, 6, -1);
channels[ch].creater = true;
if (conf_id >= 0)
{
channels[ch].conf_to_join = conf_id;
int master_ch = get_idle();
if (master_ch >= 0)
{
// ENG: Add master
// CHS: 添加主持人
channels[master_ch].master = MASTER_BUSY;
cm_pair.insert(make_pair(conf_id, master_ch));
if(master_ch != ch)
{
CHECK_RETURN SsmJoinConfGroup(conf_id, master_ch, 0, 0, FALSE, FALSE);
}
// ENG: Play "The id of the conference created is ..." .
// CHS: 播放“您创建的会议的编号的是……”。
CHECK_RETURN SsmClearFileList(ch);
CHECK_RETURN SsmAddToFileList(ch, ".\\wav\\d.wav", -1, 0, -1);
add_list(ch, conf_id);
// ENG: Play "Choose join-mode ...".
// CHS: 播放“请选择加入模式……”。
CHECK_RETURN SsmAddToFileList(ch, ".\\wav\\c.wav", -1, 0, -1);
CHECK_RETURN SsmPlayFileList(ch);
// ENG: Change state.
// CHS: 改变状态。
char fileName[MAX_PATH];
wsprintf(fileName, ".\\rec\\%d.wav", recNumber);
conInfo[conf_id].recNum = recNumber;
CHECK_RETURN SsmRecToFile(master_ch, fileName, -1, 0, -1, 0, 0);
recNumber++;
channels[ch].state_conference = CO_HOW_TO_JOIN;
}
else // ENG: No more master channels
// CHS: 没有更多的主持人通道
{
CHECK_RETURN SsmFreeConfGroup(conf_id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -