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

📄 myqqdlg.cpp

📁 用vc实现的聊天程序!功能强大!大家不妨看看!模仿实现
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if(num==0) break;
		end=sockClient.Send(m_buf, num); 
		temp+=end;
		pDlg->m_Progress.SetPos(temp);
		if(pDlg->FileStop==true) 
		{
			pDlg->FileStop=false;
			pDlg->FileWork=false;
			break;
		}
		
		if(end==SOCKET_ERROR)
		{
			AfxMessageBox("_SendFileThread Send错误!"+pDlg->GetError(GetLastError()));
			break;
			
		}
	}
	pDlg->m_Progress.SetPos(0);
	CString strLocalName;
	pDlg->GetLocalHostName(strLocalName);
	CString strLocalIP;
	pDlg->GetIpAddress(strLocalName,strLocalIP);
	if(temp==myFileInfo.fileLength)
		pDlg->AddMsgList(strLocalIP+"->"+strLocalName,"文件发送成功");
	else 
		pDlg->AddMsgList(strLocalIP+"->"+strLocalName,"文件发送失败");
	myFile.Close();
	sockClient.Close();
	pDlg->FileWork=false;
	pDlg->GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_HIDE);
	pDlg->GetDlgItem(IDC_BUTTON_STOP_FILE)->EnableWindow(false);

	pDlg->GetDlgItem(IDCANCEL)->EnableWindow(true);
	pDlg->GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true);
	
	return 0;
}



UINT _SendMsgThread(LPVOID lparam)	//TCP发送信息线程
{
	
	CMyQQDlg *pDlg=(CMyQQDlg *)lparam;
	if(pDlg->StopServer==true)	return -1;
	
	CSocket sockClient;
	sockClient.Create();
	CString ip,strError;
	pDlg->m_You_IP.GetWindowText(ip);
	int conn=sockClient.Connect(ip, PORT+pDlg->m_client);
	if(conn==0)	///////////////////////////////////
	{
		AfxMessageBox("_SendMsgThread Connect错误!"+pDlg->GetError(GetLastError()));
		sockClient.ShutDown(2);
		sockClient.Close();
		AfxEndThread(1L);
		return 0;
		
	}
	//首先发送标记M为信息,2
	int end=0;
	end=sockClient.Send("M",FLAG); 
	if(end==SOCKET_ERROR)
	{
		AfxMessageBox("_SendMsgThread Send错误!"+pDlg->GetError(GetLastError()));
		return -1;
	}
	else if(end!=2)
	{
		AfxMessageBox("消息头错误");
		return -1;
	}
	CString strMsg=pDlg->m_MsgSend;
	end=sockClient.Send(strMsg,strMsg.GetLength()); 
	if(end==SOCKET_ERROR)
	{
		AfxMessageBox("_SendMsgThread Send错误!"+pDlg->GetError(GetLastError()));
		return -1;
	}
	CString strLocalName;
	pDlg->GetLocalHostName(strLocalName);
	CString strLocalIP;
	pDlg->GetIpAddress(strLocalName,strLocalIP);
	pDlg->AddMsgList(strLocalIP+"->"+strLocalName,strMsg);
	
	int i=0;
	sockClient.Close();

	return 0;
}
UINT _ThreadCapture(LPVOID lparam)	//抓取对方屏幕线程
{
	
	CMyQQDlg *pDlg=(CMyQQDlg *)lparam;
	if(pDlg->StopServer==true)	return -1;
	
	CSocket sockClient;
	sockClient.Create();
	CString ip;
	pDlg->m_You_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;
}
///////////////////////////////////////////////////////////////////
UINT _SendMsgUdpThread(LPVOID lparam)	//UDP发送信息
{
	
	CMyQQDlg *pDlg=(CMyQQDlg *)lparam;
	if(pDlg->StopServer==true)	return -1;
	
	CSocket sockClientUdp;
	pDlg->m_type=PORT+pDlg->m_client+10;
	sockClientUdp.Create(pDlg->m_type,SOCK_DGRAM);
	CString strMsg=pDlg->m_MsgSend;
	int ret=0;
	CString ipStr;
	pDlg->m_You_IP.GetWindowText(ipStr);
	UINT port=PORT+pDlg->m_server;
	ret=sockClientUdp.SendTo(strMsg,strMsg.GetLength(),port,ipStr);
	if(ret==SOCKET_ERROR) 
	{
		DWORD error=GetLastError();
		
	}
	CString strLocalName;
	pDlg->GetLocalHostName(strLocalName);
	CString strLocalIP;
	pDlg->GetIpAddress(strLocalName,strLocalIP);
	pDlg->AddMsgList(strLocalIP+"->"+strLocalName,strMsg);
	sockClientUdp.Close();
	return 0;
	
}

////////////////////////////////////客户端线程结束//////////////////////////////////////



///////////////////////////////////函数//////////////////////////////////////////

int CMyQQDlg::ReceiveFileMsg(CSocket &recSo,SOCKADDR_IN &client)//接受函数
{
//	if(StopServer==true)	return -1;
	if(m_type=='C')		//抓取
	{
		SaveYouScreen(CopyScreenToBitmap(),client);//发送地址
	}
	
	else if(m_type=='F')			//文件
	{
		SaveYouFile(recSo,client);
	}
	
	else if(m_type=='M')	//信息
	{
		char buff[100]={0};
		CString msg;
		int ret=0;
		for(;;)
		{
			ret=recSo.Receive(buff,100);
			if(ret==0)
				break;
			msg+=buff;
		}
		CString strOut,strIn;
		m_You_IP.GetWindowText(strIn);
		GetNamebyAddress(strIn,strOut);
		CString youName;
		youName.Format(inet_ntoa(client.sin_addr));
		CString str=youName+"<-"+strOut;
		AddMsgList(str,msg);
	}
	recSo.Close();	
	return 0;
}



HBITMAP CMyQQDlg::CopyScreenToBitmap()
{
	CRect rect(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
	HDC hScrDC,hMemDC;	// 屏幕和内存设备描述表
	HBITMAP hBitmap, hOldBitmap;// 位图句柄
	int xScrn, yScrn;	// 屏幕分辨率
	hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);	//为屏幕创建设备描述表
	hMemDC = CreateCompatibleDC(hScrDC);//为屏幕设备描述表创建兼容的内存设备描述表
	xScrn = GetDeviceCaps(hScrDC, HORZRES);// 获得屏幕分辨率
	yScrn = GetDeviceCaps(hScrDC, VERTRES);
	hBitmap = CreateCompatibleBitmap(hScrDC, rect.Width(), rect.Height());// 创建一个与屏幕设备描述表兼容的位图
	hOldBitmap =(HBITMAP)SelectObject(hMemDC, hBitmap);// 把新位图选到内存设备描述表中
	BitBlt(hMemDC, 0, 0, rect.Width(), rect.Height(),hScrDC,rect.left,rect.top, SRCCOPY);// 把屏幕设备描述表拷贝到内存设备描述表中
	hBitmap =(HBITMAP)SelectObject(hMemDC, hOldBitmap);//得到屏幕位图的句柄
	DeleteDC(hScrDC);//清除 
	DeleteDC(hMemDC);
	return hBitmap;// 返回位图句柄
}


void CMyQQDlg::SaveYouScreen(HBITMAP hBitmap,SOCKADDR_IN &client)//接受屏幕
{
	HDC hDC; //设备描述表
	int iBits;//当前显示分辨率下每个像素所占字节数
	WORD wBitCount;//位图中每个像素所占字节数
	DWORD dwPaletteSize=0,//定义调色板大小
		  dwBmBitsSize,//位图中像素字节大小
		  dwDIBSize;//位图文件大小 
	BITMAP Bitmap;//位图属性结构
	BITMAPFILEHEADER bmfHdr;//位图文件头结构
	BITMAPINFOHEADER bi;//位图信息头结构 
	LPBITMAPINFOHEADER lpbi;//指向位图信息头结构
	HANDLE hDib, hPal,hOldPal=NULL;//定义文件,分配内存句柄,调色板句柄
	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 <= 24)
		wBitCount = 24;
	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;
	
	CSocket sockClient;
	sockClient.Create();
	sockClient.Connect(inet_ntoa(client.sin_addr), PORT+m_client); //连接到申请方

	//首先发送标记F为文件,2
	FILEINFO myFileInfo;
	myFileInfo.fileLength=sizeof(BITMAPFILEHEADER)+dwDIBSize;//得到文件大小
	strcpy(myFileInfo.fileName,"对方屏幕.bmp");//得到文件名称
	sockClient.Send("F",FLAG);
	sockClient.Send(&myFileInfo,sizeof(FILEINFO));
	sockClient.Send(&bmfHdr, sizeof(BITMAPFILEHEADER)); 
	sockClient.Send(lpbi, dwDIBSize); 
	GlobalUnlock(hDib);
	GlobalFree(hDib);
}


int CMyQQDlg::SaveYouFile(CSocket &recSo, SOCKADDR_IN &client)//接受文件
{
	CString fname;
	CFileDialog dlg(false);	//另存文件
	FILEINFO myFileInfo;
	recSo.Receive(&myFileInfo,sizeof(FILEINFO));
	int fileLength=myFileInfo.fileLength;
	CString strfileIp,strfileName,strfileLength;
	strfileIp.Format(inet_ntoa(client.sin_addr));
	strfileName.Format(myFileInfo.fileName);
	strfileLength.Format("%f",myFileInfo.fileLength/1024.0);
	CString title="文件"+strfileName+" 大小"+strfileLength+"KB "+"来在"+strfileIp+" 是否接受";
	dlg.m_ofn.lpstrTitle=title;//标题条
	char fileme[500]={0};//必须足够大小
	strcpy(fileme,strfileIp+strfileName);
	dlg.m_ofn.lpstrFile=fileme;	//文件名称
	if(dlg.DoModal()==IDOK)
	{
		fname=dlg.GetPathName();	//得到文件名名称、路径
		GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_SHOW);
	}
	else
	{
		GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_HIDE);
		GetDlgItem(IDC_BUTTON_STOP_FILE)->EnableWindow(false);
		
		GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true);
		GetDlgItem(IDCANCEL)->EnableWindow(true);
		
		recSo.Close();	
		return 0;	
		
	}
	char buf[SIZEFILE]={0};
	CFile f(fname,CFile::modeCreate|CFile::modeWrite);	//存文件
	
	m_Progress.SetRange32(0,fileLength);
	
	int n=0;	//接受的字节数 0表示结束
	int temp=0;
	GetDlgItem(IDC_BUTTON_STOP_FILE)->EnableWindow(true);
	
	GetDlgItem(IDCANCEL)->EnableWindow(false);
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(false);
	
	
	for(;;)
	{
		n=recSo.Receive(buf,SIZEFILE);	//接受
		if(n==0)		//0表示结束
			break;		//接受完毕
		f.Write(buf,n);
		temp+=n;
		m_Progress.SetPos(temp);
		if(FileWork==false) FileWork=true;
		if(FileStop==true) 
		{
			FileStop=false;
			FileWork=false;
			break ;
		}
		
	}
	f.Close();
	m_Progress.SetPos(0);
	if(temp==fileLength)
		AddMsgList(inet_ntoa(client.sin_addr),"文件接受成功");
	else
		AddMsgList(inet_ntoa(client.sin_addr),"文件接受失败");
	FileWork=false;
	GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_HIDE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -