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

📄 meetingdoc.cpp

📁 聊天的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				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 + -