chatdlg.cpp
来自「仿造QQ聊天界面 超级相向 第一次作品 不足之处见谅」· C++ 代码 · 共 1,568 行 · 第 1/3 页
CPP
1,568 行
FileWork=false;
GetDlgItem(IDCANCEL)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(false);
GetDlgItem(IDC_CONNECT)->EnableWindow(true);//连接可用
GetDlgItem(IDC_IPADDRESS1)->EnableWindow(true);
GetDlgItem(IDC_SEND_FILE)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_CAPUTER)->EnableWindow(false);
DWORD dwStatus;
if (pThreadLisen != NULL)
{
if(::GetExitCodeThread(pThreadLisen->m_hThread, &dwStatus)==0)
{
int errror=GetLastError();
return;
}
if (dwStatus == STILL_ACTIVE)
{
CSocket sockClient;
sockClient.Create();
CString ip,strError;
ip="127.0.0.1";
int conn=sockClient.Connect(ip, m_Potr);
if(conn==0)
{
AfxMessageBox("关闭错误!"+GetError(GetLastError()));
sockClient.ShutDown(2);
sockClient.Close();
return;
}
sockClient.Send("D",FLAG); //结束
}
else
{
delete pThreadLisen;
pThreadLisen = NULL;
}
}
}
UINT _ThreadCapture(LPVOID lparam) //抓取对方屏幕线程
{
CChatDlg *pDlg=(CChatDlg *)lparam;
if(pDlg->StopServer==true) return -1;
CSocket sockClient;
sockClient.Create();
CString ip;
pDlg->m_ip.GetWindowText(ip);
sockClient.Connect(ip, PORT+pDlg->m_client);
//首先发送标记C为抓取,2
int end=0;
end=sockClient.Send("C",FLAG);
///////////////////////////////////////////////////////////////////发送标志是否成功
if(end==SOCKET_ERROR)
{
AfxMessageBox("_ThreadCapture Send错误!"+pDlg->GetError(GetLastError()));
return -1;
}
else if(end!=2)
{
AfxMessageBox("发送头错误");
return -1;
}
return 0;
}
void CChatDlg::OnButtonCaputer()
{
// TODO: Add your control notification handler code here
pThreadCaputre=::AfxBeginThread(_ThreadCapture,this); //开始传送文件线程
}
void CChatDlg::OnMyCaputer()
{
// TODO: Add your control notification handler code here
OnGetCaputer();
CFileDialog dlg(false); /////存储文件
dlg.m_ofn.lpstrFilter="*.bmp";
CString filename;
if (dlg.DoModal() == IDOK)
{
filename=dlg.GetFileName();
}
else
return ;
UpdateData(FALSE);
CFile f(filename+".bmp",CFile::modeCreate|CFile::modeWrite);//存文件
f.Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
f.Write(lpbi, dwDIBSize);
GlobalUnlock(hDib);
GlobalFree(hDib);
f.Close();
}
void CChatDlg::OnGetCaputer()
{
// TODO: Add your control notification handler code here
HBITMAP hBitmap=CopyScreenToBitmap();
dwPaletteSize=0;
hOldPal=NULL;
HDC hDC; //设备描述表
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL)*GetDeviceCaps(hDC, PLANES);//计算位图文件每个像素所占字节数
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 16)
wBitCount = 16;
else if (iBits <= 24)
wBitCount = 24;
else wBitCount=32;
if (wBitCount <= 8)
dwPaletteSize = (1<<wBitCount)*sizeof(RGBQUAD);//计算调色板大小
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount+31)/32)* 4 *Bitmap.bmHeight ;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi=bi; /////////////////////////////////////////
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC=::GetDC(NULL);
hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;
//首先发送标记F为文件,2
FILEINFO myFileInfo;
myFileInfo.fileLength=sizeof(BITMAPFILEHEADER)+dwDIBSize;//得到文件大小
}
void CChatDlg::OnStopFilesend()
{
// TODO: Add your control notification handler code here
FileStop=true;
FileWork=false;
GetDlgItem(IDCANCEL)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true);
}
/////////////////////////////////////////////////
//////////////////////////////////////////////////
UINT Audio_Listen_Thread(LPVOID lParam)
{
CChatDlg *pdlg = (CChatDlg*)lParam;
CSocket m_Server;
DWORD length;
if(!m_Server.Create(6060))
AfxMessageBox("Listen Socket create error"+pdlg->GetError(GetLastError()));//不可单个运行,重复产生同一端口显然是错误的
if(!m_Server.Listen())
AfxMessageBox("m_server.Listen ERROR"+pdlg->GetError(GetLastError()));
CSocket recSo;
if(! m_Server.Accept(recSo))
AfxMessageBox("m_server.Accept() error"+pdlg->GetError(GetLastError()));
m_Server.Close();
int sendcount=0;//just for test
int ret ;
while(1)
{ //开始循环接收声音文件,首先接收文件长度
ret = recSo.Receive(&length,sizeof(DWORD));
if(ret== SOCKET_ERROR )
AfxMessageBox("服务器端接收声音文件长度出错,原因: "+pdlg->GetError(GetLastError()));
if(ret!=sizeof(DWORD))
{
AfxMessageBox("接收文件头错误,将关闭该线程");
recSo.Close();
return -1;
}//接下来开辟length长的内存空间
pdlg->m_AudioDataOut[pdlg->nReceive].lpdata =(PBYTE)realloc (0,length);
if (pdlg->m_AudioDataOut[pdlg->nReceive].lpdata == NULL)
{
MessageBeep (MB_ICONEXCLAMATION) ;
AfxMessageBox("erro memory_ReceiveAudio");
// pdlg->OnOK();
recSo.Close();
return -1;
}
else//内存申请成功,可以进行循环检测接受
{
DWORD dwReceived = 0,dwret;
while(length>dwReceived)
{
dwret = recSo.Receive((pdlg->m_AudioDataOut[pdlg->nReceive].lpdata+dwReceived),(length-dwReceived));
dwReceived +=dwret;
if(dwReceived ==length)
{
pdlg->m_AudioDataOut[pdlg->nReceive].dwLength = length;
break;
}
}
}//本轮声音文件接收完毕
pdlg->nReceive=(pdlg->nReceive+1)%OutBlocks;
}
recSo.Close();
// pdlg->OnOK();
return 0;
}
UINT Audio_Send_Thread(LPVOID lParam)//专职的声音文件发送线程
{ // 端口也是专用的
CChatDlg *pdlg = (CChatDlg*)lParam;
CSocket m_Client;
m_Client.Create();
if( m_Client.Connect(pdlg->str2,6060))
{
DWORD ret, length;
int count=0;
while(1)//循环使用指针nSend
{
length =pdlg->m_AudioDataIn[pdlg->nSend].dwLength;
if(length !=0)
{ //首先发送块的长度
if(((ret = m_Client.Send(&length,sizeof(DWORD)))!=sizeof(DWORD))||(ret==SOCKET_ERROR))
{
AfxMessageBox("声音文件头传输错误!"+pdlg->GetError(GetLastError()));
// pdlg->OnOK();
break;
}//其次发送块的内容 ,循环检测发送
DWORD dwSent = 0;//已经发送掉的字节数
while(1)//==============================发送声音文件开始
{
ret = m_Client.Send((pdlg->m_AudioDataIn[pdlg->nSend].lpdata+dwSent),(length-dwSent));
if(ret==SOCKET_ERROR)//检错
{
AfxMessageBox("声音文件传输错误!"+pdlg->GetError(GetLastError()));
// pdlg->OnOK();
break;
}
else //发送未发送完的
{
dwSent += ret;
if(dwSent ==length)
{
free(pdlg->m_AudioDataIn[pdlg->nSend].lpdata);
pdlg->m_AudioDataIn[pdlg->nSend].dwLength = 0;
break;
}
}
} //======================================发送声音文件结束
}
pdlg->nSend = (pdlg->nSend +1)% InBlocks;
}
}
else
AfxMessageBox("Socket连接失败"+pdlg->GetError(GetLastError()));
m_Client.Close();
return 0;
}
void CChatDlg::OnVoice()
{
// TODO: Add your control notification handler code here
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6060);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
str2=inet_ntoa(addrTo.sin_addr);
GetDlgItem(IDC_VOICE)->EnableWindow(false);
GetDlgItem(IDOK)->EnableWindow(true);
//allocate buffer memory
pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE);
pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE);
if (!pBuffer1||!pBuffer2)
{
if (pBuffer1) free(pBuffer1);
if (pBuffer2) free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Memory erro!");
return ;
}
//open waveform audio for input
m_waveformin.wFormatTag=WAVE_FORMAT_PCM;
m_waveformin.nChannels=1;
m_waveformin.nSamplesPerSec=11025;//采样频率
m_waveformin.nAvgBytesPerSec=11025;
m_waveformin.nBlockAlign=1;
m_waveformin.wBitsPerSample=8;
m_waveformin.cbSize=0;
if (waveInOpen(&hWaveIn,WAVE_MAPPER,&m_waveformin,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW))
{ //打开录音设备函数
free(pBuffer1);
free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Audio can not be open!");
}
pWaveHdr1->lpData=(LPTSTR)pBuffer1;
pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr1->dwBytesRecorded=0;
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=1;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
pWaveHdr2->lpData=(LPTSTR)pBuffer2;
pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr2->dwBytesRecorded=0;
pWaveHdr2->dwUser=0;
pWaveHdr2->dwFlags=0;
pWaveHdr2->dwLoops=1;
pWaveHdr2->lpNext=NULL;
pWaveHdr2->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
// Add the buffers
waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
// Begin sampling
waveInStart (hWaveIn) ;
::AfxBeginThread(Audio_Listen_Thread,this);
::AfxBeginThread(Audio_Send_Thread,this);
m_waveformout.wFormatTag = WAVE_FORMAT_PCM;
m_waveformout.nChannels =1;
m_waveformout.nSamplesPerSec =11025;
m_waveformout.nAvgBytesPerSec =11025;
m_waveformout.nBlockAlign =1;
m_waveformout.wBitsPerSample =8;
m_waveformout.cbSize =0;
if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&m_waveformout,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Audio output erro");
}
return ;
}
void CChatDlg::OnMM_WIM_DATA(UINT wParam,LONG lParam)
{
int nextBlock = (nAudioIn+1)% InBlocks;
if(m_AudioDataIn[nextBlock].dwLength!=0)//下一“块”没发走
{ //把PWAVEHDR(即pBUfferi)里的数据拷贝到当前“块”中
m_AudioDataIn[nAudioIn].lpdata
= (PBYTE)realloc (m_AudioDataIn[nAudioIn].lpdata , (((PWAVEHDR) lParam)->dwBytesRecorded+m_AudioDataIn[nAudioIn].dwLength)) ;
if (m_AudioDataIn[nAudioIn].lpdata == NULL)
{
waveInClose (hWaveIn) ;
MessageBeep (MB_ICONEXCLAMATION) ;
AfxMessageBox("erro memory OnMM_WIM_DATA");
return ;
}
CopyMemory ((m_AudioDataIn[nAudioIn].lpdata+m_AudioDataIn[nAudioIn].dwLength),
((PWAVEHDR) lParam)->lpData,
((PWAVEHDR) lParam)->dwBytesRecorded) ;//(*destination,*resource,nLen);
m_AudioDataIn[nAudioIn].dwLength +=((PWAVEHDR) lParam)->dwBytesRecorded;
}
else //把PWAVEHDR(即pBUfferi)里的数据拷贝到下一“块”中
{
nAudioIn = (nAudioIn+1)% InBlocks;
m_AudioDataIn[nAudioIn].lpdata = (PBYTE)realloc
(0,((PWAVEHDR) lParam)->dwBytesRecorded);
CopyMemory(m_AudioDataIn[nAudioIn].lpdata,
((PWAVEHDR) lParam)->lpData,
((PWAVEHDR) lParam)->dwBytesRecorded) ;
m_AudioDataIn[nAudioIn].dwLength =((PWAVEHDR) lParam)->dwBytesRecorded;
}
// Send out a new buffer
waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
return ;
}
void CChatDlg::OnMM_WIM_CLOSE(UINT wParam,LONG lParam)
{
waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
free (pBuffer1) ;
free (pBuffer2) ;
return ;
}
void CChatDlg::OnMM_WOM_OPEN(UINT wParam,LONG lParam)
{
// Set up header
pWaveHdrOut->lpData = (LPTSTR)m_AudioDataOut[nAudioOut].lpdata ;
pWaveHdrOut->dwBufferLength = m_AudioDataOut[nAudioOut].dwLength ;
pWaveHdrOut->dwBytesRecorded = 0 ;
pWaveHdrOut->dwUser = 0 ;
pWaveHdrOut->dwFlags = WHDR_BEGINLOOP ;
pWaveHdrOut->dwLoops = 1 ;
pWaveHdrOut->lpNext = NULL ;
pWaveHdrOut->reserved = 0 ;
// Prepare and write
waveOutPrepareHeader (hWaveOut, pWaveHdrOut, sizeof (WAVEHDR)) ;
waveOutWrite (hWaveOut, pWaveHdrOut, sizeof (WAVEHDR)) ;
return;
}
void CChatDlg::OnMM_WOM_DONE(UINT wParam,LONG lParam)
{
free(m_AudioDataOut[nAudioOut].lpdata);
m_AudioDataOut[nAudioOut].lpdata = reinterpret_cast<PBYTE>(malloc(1));
m_AudioDataOut[nAudioOut].dwLength = 0;
nAudioOut= (nAudioOut+1)%OutBlocks;
((PWAVEHDR)lParam)->lpData = (LPTSTR)m_AudioDataOut[nAudioOut].lpdata ;
((PWAVEHDR)lParam)->dwBufferLength = m_AudioDataOut[nAudioOut].dwLength ;
TRACE("the next length %d\n",((PWAVEHDR)lParam)->dwBufferLength);
waveOutPrepareHeader (hWaveOut,(PWAVEHDR)lParam,sizeof(WAVEHDR));
waveOutWrite(hWaveOut,(PWAVEHDR)lParam,sizeof(WAVEHDR));//cut
return;
}
void CChatDlg::OnMM_WOM_CLOSE(UINT wParam,LONG lParam)
{
waveOutUnprepareHeader (hWaveOut, pWaveHdrOut, sizeof (WAVEHDR)) ;
//release all the memory of the AudioData
for(int i=0;i<InBlocks;i++)
{
if(m_AudioDataIn[i].dwLength != 0)
free(m_AudioDataIn[i].lpdata);
}
for(i=0;i<OutBlocks;i++)
{
if(m_AudioDataOut[i].dwLength != 0)
free(m_AudioDataOut[i].lpdata);
}
}
void CChatDlg::OnOK()
{
// TODO: Add extra validation here
waveInReset(hWaveIn);
waveInClose(hWaveIn);
waveOutReset(hWaveOut);
waveOutClose (hWaveOut);
GetDlgItem(IDC_VOICE)->EnableWindow(true);
GetDlgItem(IDOK)->EnableWindow(false);
}
void CChatDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
}
void CChatDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
// CAboutDlg dlg;
// dlg.DoModal();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?