📄 meetingdoc.cpp
字号:
pSocket->Close();
delete pSocket;
pSocket=NULL;
break;
}
}
//给列表中的用户发送消除消息
pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
CClientSocket* socket=(CClientSocket*)m_listClient.GetNext(pos);
socket->SendShape(pOrder);
}
}
}
void CMeetingDoc::UserRegister(CShape* pOrder,CClientSocket* pSocket)
{
POSITION pos;
CClientSocket* pTSocket;
COrder *pOrder1=(COrder*)pOrder;
LV_ITEM lvitem;
if(m_bIsServer)
{
//给新用户发送已有用户列表
pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
pTSocket=(CClientSocket*)m_listClient.GetNext(pos);
if(pTSocket==pSocket)
{
pTSocket->m_strUserName=pOrder1->m_strParam;
pTSocket->m_nSex=pOrder1->m_nParam;
}
CShape* pp=new COrder(LOGIN,pTSocket->m_strUserName
,pTSocket->m_nSex);
TrashCollect(pp);
pSocket->SendShape(pp);
}
//给已有用户发送新用户加入信息
pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
pTSocket=(CClientSocket*)m_listClient.GetNext(pos);
if(pTSocket==pSocket) continue;
pTSocket->SendShape(pOrder);
}
}
CMainFrame* pFrm=(CMainFrame*)AfxGetApp()->GetMainWnd();
CListCtrl* p=&pFrm->m_wndUserList;
lvitem.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
lvitem.iItem=p->GetItemCount()+1;
lvitem.iSubItem=0;
lvitem.pszText=(LPTSTR)(LPCTSTR)pOrder1->m_strParam;
lvitem.iImage=pOrder1->m_nParam;
lvitem.lParam=1;
int iPos=p->InsertItem(&lvitem);
}
void CMeetingDoc::OnDrawClear()
{
while(!m_tempList.IsEmpty())
delete m_tempList.RemoveHead();
while(!m_shapeList.IsEmpty())
delete m_shapeList.RemoveHead();
UpdateAllViews(NULL);
}
void CMeetingDoc::OnDrawSetup()
{
CDrawSetDlg dlg;
dlg.m_bFill=m_bFill;
dlg.m_colorBack=m_colorFill;
dlg.m_colorFront=m_colorPen;
dlg.m_nWidth=m_nPenWidth;
if(dlg.DoModal()==IDOK)
{
m_colorPen=dlg.m_colorFront;
m_colorFill=dlg.m_colorBack;
m_bFill=dlg.m_bFill;
m_nPenWidth=dlg.m_nWidth;
if(m_penCur.Detach())
m_penCur.DeleteObject();
m_penCur.CreatePen(PS_SOLID,m_nPenWidth,m_colorPen);
}
}
CMeetingDoc::LogOut(CShape* pOrder)
{
CMainFrame* pFrm=(CMainFrame*)AfxGetApp()->GetMainWnd();
CListCtrl* p=&pFrm->m_wndUserList;
COrder* pp=(COrder*)pOrder;
LVFINDINFO info;
int nIndex;
info.flags = LVFI_PARTIAL|LVFI_STRING;
info.psz = pp->m_strParam;
if ((nIndex=p->FindItem(&info)) != -1)
{
p->DeleteItem(nIndex);
}
}
CMeetingDoc::BroadcastMsg(CShape* pShape)
{
POSITION pos;
if(m_bIsServer)
{
pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
CClientSocket* pSocket=(CClientSocket*)m_listClient.GetNext(pos);
pSocket->SendShape(pShape);
}
}
if(m_bIsClient)
{
m_socketClient->SendShape(pShape);
}
}
CMeetingDoc::ClearAll()
{
if(m_bIsServer)
{
if(m_socketListen!=NULL)
{
m_socketListen->Close();
delete m_socketListen;
m_socketListen=NULL;
}
POSITION pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
CClientSocket* client=(CClientSocket*)m_listClient.GetNext(pos);
delete client;
} m_bIsServer=false;
}
if(m_bIsClient)
{
if(m_socketClient!=NULL)
{
m_socketClient->Close();
delete m_socketClient;
m_socketClient=NULL;
}
m_bIsClient=false;
}
while(!m_tempList.IsEmpty())
delete m_tempList.RemoveHead();
}
HWAVEOUT hWaveOut;
bool m_Opened;
WAVEHDR WaveHdrOut[MAXWAVEBLOCK];
//局部变量
static WAVEHDR WaveHdrIn[MAXWAVEBLOCK];
static char WaveOutBuffer[MAXWAVEBLOCK][MAXWAVEBUFFER];//保存播音数据用内存块
static char WaveInBuffer[MAXWAVEBLOCK][MAXWAVEBUFFER];//记录录音数据用内存块
static HWAVEIN hWaveIn;
void CMeetingDoc::PlayAudio(int len, char *buf)
{
TRACE("------->>%d,%0x\n",len,buf);
if(DataBlock < MaxDataBlock)
{//总播音数据块符合要求
memcpy(WaveHdrOut[CurrentBlock].lpData, buf, len);//复制语音数据
//为结构赋值
WaveHdrOut[CurrentBlock].dwBufferLength=len;
WaveHdrOut[CurrentBlock].dwFlags=0;
WaveHdrOut[CurrentBlock].dwUser=0;
//准备、锁定内存块
waveOutPrepareHeader(hWaveOut, &WaveHdrOut[CurrentBlock], sizeof(WAVEHDR));
//播放该语音数据
waveOutWrite(hWaveOut, &WaveHdrOut[CurrentBlock], sizeof(WAVEHDR));
DataBlock++;
CurrentBlock = (CurrentBlock+1) % MAXWAVEBLOCK;
MaxDataBlock = MAXWAVEBLOCK;
}else
{//总内存块过多,需要减少(到2个)内存块
//该设置保证数据最多为 MAXWAVEBLOCK个,最少为2个
//在当前设置下,放音最大延时为 0.5秒(忽略网络延时)。
MaxDataBlock = 3;
}
}
void CALLBACK CMeetingDoc::waveInProc(HWAVEIN hwi, UINT uMsg, WORD dwInstance,
WAVEHDR* dwParam1, DWORD dwParam2)
{
long result;
char buffer[MAXWAVEBUFFER];
long buf_len;
switch(uMsg)
{//判断回调类型
case WIM_OPEN:
//录音设备正常打开时,触发该事件
//MessageBox(NULL,"Open success", "提示", MB_OK);
break;
case WIM_CLOSE:
//录音设备正常关闭时,触发该事件
//MessageBox(NULL,"Close success", "提示", MB_OK);
break;
case WIM_DATA:
//录音设备返回数据时,触发该事件
if(!waveInUnprepareHeader(hwi, dwParam1,sizeof(WAVEHDR)))
{//可以释放内存。有的情况虽然返回数据,但不能释放内存,
//如使用同一个WAVEHDR增加多个内存块时,会出现上述情况
memcpy(buffer, dwParam1->lpData , MAXWAVEBUFFER);//复制返回数据
buf_len = dwParam1->dwBytesRecorded;//记录录音数据长度
dwParam1->dwUser=0;//恢复设置
dwParam1->dwBufferLength=MAXWAVEBUFFER;
dwParam1->dwFlags=0;
//准备、锁定内存块
// waveOutPrepareHeader(hWaveOut, dwParam1, sizeof(WAVEHDR));
//播放该语音数据
// waveOutWrite(hWaveOut, dwParam1, sizeof(WAVEHDR));
if(m_Opened)
{//录音仍在继续
result=waveInPrepareHeader(hwi,dwParam1,sizeof(WAVEHDR));
result=waveInAddBuffer(hwi,dwParam1,sizeof(WAVEHDR));
}
}
// memcpy(buffer,"wolfking i love you deeply",27);
g_pView->SendMessage(USER_MESSAGE_PLAY,(WPARAM)buf_len
,(LPARAM)buffer);
/* if( m_Opened && buf_len > 0 && buf_len <= MAXWAVEBUFFER )
{//有录音数据
//发送录音数据
m_pChange->SendTo(buffer, buf_len, RemotePort, LPCTSTR(RemoteHost));
}
*/ break;
}
};
void CALLBACK CMeetingDoc::waveOutProc(HWAVEOUT hwo, UINT uMsg, WORD dwInstance,
WAVEHDR* dwParam1, DWORD dwParam2)
{
switch(uMsg)
{//判断回调类型
case WOM_OPEN:
//播音设备正常打开时,触发该事件
//MessageBox(NULL,"Open success",NULL,MB_OK);
break;
case WOM_CLOSE:
//播音设备正常关闭时,触发该事件
//MessageBox(NULL,"Close success",NULL,MB_OK);
break;
case WOM_DONE:
//内存播放完成时,触发该事件
if(!waveOutUnprepareHeader(hwo, dwParam1, sizeof(WAVEHDR)))
{
// m_pChange->DelDataBlock();//减少内存数量记数
}
break;
}
};
long _stdcall CMeetingDoc::StartPhone()
{
// TODO: Add your dispatch handler code here
long sta;
int i;
ClosePhone();
if(m_Opened)
//设备正在使用
return -1;
m_Opened = true;//设置设备打开标志
WAVEFORMATEX waveFormatEx;
waveFormatEx.cbSize=0;
waveFormatEx.nAvgBytesPerSec=16000;
waveFormatEx.nBlockAlign=2;
waveFormatEx.nChannels=1;
waveFormatEx.nSamplesPerSec=8000;
waveFormatEx.wBitsPerSample=16;
waveFormatEx.wFormatTag=WAVE_FORMAT_PCM;
//打开播音设备并开始播音
for(i=0;i < MAXWAVEBLOCK; i++)
WaveHdrOut[i].lpData=WaveOutBuffer[i];//设置播音数据内存区
hWaveOut = NULL;
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormatEx, (unsigned long)waveOutProc, 0L, CALLBACK_FUNCTION))
{//播音设备打开失败,播音设备被其他程序占用
ClosePhone();
return 1;
}
hWaveIn = NULL;
if(sta=waveInOpen(&hWaveIn, WAVE_MAPPER, &waveFormatEx, (unsigned long)waveInProc, 1L, CALLBACK_FUNCTION))
{//录音设备打开失败,可能声卡不支持全双工。
ClosePhone();
return 2;
}
for(i=0;i < MAXWAVEBLOCK; i++)
{//增加录音内存
WaveHdrIn[i].lpData=WaveInBuffer[i];
WaveHdrIn[i].dwBufferLength=MAXWAVEBUFFER;
WaveHdrIn[i].dwFlags=0;
WaveHdrIn[i].dwUser=0;
if(waveInPrepareHeader(hWaveIn, &WaveHdrIn[i], sizeof(WAVEHDR)))
{//无法锁定该内存
ClosePhone();
return 3;
};
if(waveInAddBuffer(hWaveIn,&WaveHdrIn[i],sizeof(WAVEHDR)))
{//无法增加该内存
ClosePhone();
return 4;
}
}
if(waveInStart(hWaveIn))
{//无法开始录音
ClosePhone();
return 5;
}
return 0;
}
void _stdcall CMeetingDoc::ClosePhone()
{
// TODO: Add your dispatch handler code here
if(!m_Opened)//电话已经关闭
return;
m_Opened = false;//关闭电话使用标志
if(hWaveIn){
waveInStop(hWaveIn);//停止录音
waveInReset(hWaveIn);//清空录音缓存
waveInClose(hWaveIn);//关闭录音设备
hWaveIn = NULL;
}
if(hWaveOut)
{
waveOutReset(hWaveOut);//清空声音输出缓存
waveOutClose(hWaveOut);//关声音输出设备
hWaveOut = NULL;
}
}
void CMeetingDoc::ProcessMsg(CShape* &pShape,CClientSocket* pSocket)
{
POSITION pos;
CClientSocket* pTSocket;
BOOL bSendFlag=false;
if(pShape->IsKindOf(RUNTIME_CLASS(COrder)))
{
TrashCollect(pShape);
COrder* pOrder=(COrder*)pShape;
switch(pOrder->m_Order)
{
case LOGIN:
UserRegister(pOrder,pSocket);
break;
case LOGOUT:
LogOut(pOrder);
break;
default:
break;
}
}
else if(pShape->IsKindOf( RUNTIME_CLASS(CTask) ) )
{
bSendFlag=true;
if(m_pTalkDlg==NULL)
{
CMainFrame* pFrm=(CMainFrame*)AfxGetApp()->GetMainWnd();
m_pTalkDlg=(CTalkDlg*)&pFrm->m_wndTalkDlg;
}
pShape->DrawShape(m_pTalkDlg);
}
else if(pShape->IsKindOf( RUNTIME_CLASS(CAudio) ) )
{
bSendFlag=true;
CAudio* pAudio=(CAudio*)pShape;
if(m_bPhone)PlayAudio(pAudio->buf_len,pAudio->buffer);
TrashCollect(pAudio);
}
else
{
bSendFlag=true;
m_shapeList.AddTail(pShape);
CClientDC dc(m_pView);
pShape->DrawShape(&dc);
}
if(m_bIsServer&&bSendFlag)
{
pos=m_listClient.GetHeadPosition();
while(pos!=NULL)
{
pTSocket=(CClientSocket*)m_listClient.GetNext(pos);
if(pTSocket==pSocket)
continue;
pTSocket->SendShape(pShape);
}
}
}
CMeetingDoc::TrashCollect(CShape *pShape)
{
if(m_tempList.GetCount()>50)
{
while(m_tempList.GetCount()>30)
delete m_tempList.RemoveHead();
}
m_tempList.AddTail(pShape);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -