www.pudn.com > qq.rar > MyQQDlg.cpp


// MyQQDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "MyQQ.h" 
#include "MyQQDlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#include  
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
	 
	// Dialog Data 
	//{{AFX_DATA(CAboutDlg) 
	enum { IDD = IDD_ABOUTBOX }; 
	//}}AFX_DATA 
	 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CAboutDlg) 
protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
	//}}AFX_VIRTUAL 
	 
	// Implementation 
protected: 
	//{{AFX_MSG(CAboutDlg) 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
	//{{AFX_DATA_INIT(CAboutDlg) 
	//}}AFX_DATA_INIT 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAboutDlg) 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
//{{AFX_MSG_MAP(CAboutDlg) 
// No message handlers 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyQQDlg dialog 
 
 
 
#define PORT		34567 
#define FLAG		2 
#define SIZEFILE	1024 
 
const int SOCK_TCP	= 0;	//TCP模式 
const int SOCK_UDP  = 1;	//UPD模式 
 
CWinThread	*pThreadSendFile;	//发送文件线程-->_SendFileThread 
CWinThread	*pThreadSendMsg;		//发送消息线程 
CWinThread	*pThreadLisen;		//监听线程-->_ListenTcpThread 
CWinThread	*pReceiveThread;		//接受线程-->_ReceiveThread 
CWinThread  *pThreadCaputre;		//抓取屏幕线程 
 
 
////////////////////////////////////////////////////////////////////////////// 
 
 
CMyQQDlg::CMyQQDlg(CWnd* pParent /*=NULL*/) 
: CDialog(CMyQQDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CMyQQDlg) 
	m_MsgSend = _T(""); 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
	m_nSockType=0;//TCP 
	m_WorkType=2;//两者 
	m_client=0; 
	m_server=0; 
	FileWork=false; 
	FileStop=false; 
	StopServer=false; 
} 
 
void CMyQQDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CMyQQDlg) 
	DDX_Control(pDX, IDC_PROGRESS_SEND_FILE, m_Progress); 
	DDX_Control(pDX, IDC_LIST_BOX_ADDMSG, m_AddMsgLIst); 
	DDX_Control(pDX, IDC_IPADDRESS, m_You_IP); 
	DDX_Text(pDX, IDC_EDIT_SENDMSG, m_MsgSend); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CMyQQDlg, CDialog) 
//{{AFX_MSG_MAP(CMyQQDlg) 
ON_WM_SYSCOMMAND() 
ON_WM_PAINT() 
ON_WM_QUERYDRAGICON() 
ON_BN_CLICKED(IDC_BUTTON_CONNECT, OnButtonConnect) 
ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, OnButtonDisconnect) 
ON_BN_CLICKED(IDC_BUTTON_SEND_MSG, OnButtonSendMsg) 
ON_BN_CLICKED(IDC_BUTTON_SEND_FILE, OnButtonSendFile) 
ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear) 
ON_BN_CLICKED(IDC_RADIO_TCP, OnRadioTcp) 
ON_BN_CLICKED(IDC_RADIO_UDP, OnRadioUdp) 
ON_BN_CLICKED(IDC_RADIO_SERVER, OnRadioServer) 
ON_BN_CLICKED(IDC_RADIO_CLIENT, OnRadioClient) 
ON_BN_CLICKED(IDC_RADIO_BOTH, OnRadioBoth) 
ON_BN_CLICKED(IDC_BUTTON_STOP_FILE, OnButtonStopFile) 
ON_MESSAGE(WM_KSEND,OnKSend) 
ON_BN_CLICKED(IDC_BUTTON_CAPUTER, OnButtonCaputer) 
	ON_LBN_SELCHANGE(IDC_LIST_BOX_ADDMSG, OnSelchangeListBoxAddmsg) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyQQDlg message handlers 
 
BOOL CMyQQDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
	 
	// Add "About..." menu item to system menu. 
	 
	// IDM_ABOUTBOX must be in the system command range. 
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
	ASSERT(IDM_ABOUTBOX < 0xF000); 
	 
	CMenu* pSysMenu = GetSystemMenu(FALSE); 
	if (pSysMenu != NULL) 
	{ 
		CString strAboutMenu; 
		strAboutMenu.LoadString(IDS_ABOUTBOX); 
		if (!strAboutMenu.IsEmpty()) 
		{ 
			pSysMenu->AppendMenu(MF_SEPARATOR); 
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
		} 
	} 
	 
	// Set the icon for this dialog.  The framework does this automatically 
	//  when the application's main window is not a dialog 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
	// TODO: Add extra initialization here 
	///////////////////////////////////////////////////////// 
	CString strLocalName; 
	GetLocalHostName(strLocalName); 
	CString strLocalIP; 
	GetIpAddress(strLocalName,strLocalIP); 
	m_You_IP.SetWindowText(strLocalIP);	//设置默认IP为本机 
	///////////////////////////////////////////////////////// 
	((CButton*)GetDlgItem(IDC_RADIO_BOTH))->SetCheck(BST_CHECKED);//默认为服务器、客户端一体 
	SetWindowText("MyQQ TCP方式"); 
 
	GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("启    动"); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->SetWindowText("关    闭"); 
	 
	GetDlgItem(IDC_BUTTON_CAPUTER)->EnableWindow(false);//默认为不可勇 
	((CButton*)GetDlgItem(IDC_RADIO_TCP))->SetCheck(BST_CHECKED);//默认为TCP 
	GetDlgItem(IDC_BUTTON_SEND_MSG)->EnableWindow(false);//发送消息不可用 
	GetDlgItem(IDC_BUTTON_SEND_FILE)->EnableWindow(false);//发送文件不可用 
	GetDlgItem(IDC_BUTTON_CLEAR)->EnableWindow(false);//清除不可用 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(false);//断开连接不可用 
	GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_HIDE); 
	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
void CMyQQDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
// If you add a minimize button to your dialog, you will need the code below 
//  to draw the icon.  For MFC applications using the document/view model, 
//  this is automatically done for you by the framework. 
 
void CMyQQDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // device context for painting 
		 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
		 
		// Center icon in client rectangle 
		int cxIcon = GetSystemMetrics(SM_CXICON); 
		int cyIcon = GetSystemMetrics(SM_CYICON); 
		CRect rect; 
		GetClientRect(&rect); 
		int x = (rect.Width() - cxIcon + 1) / 2; 
		int y = (rect.Height() - cyIcon + 1) / 2; 
		 
		// Draw the icon 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		CDialog::OnPaint(); 
	} 
} 
 
// The system calls this to obtain the cursor to display while the user drags 
//  the minimized window. 
HCURSOR CMyQQDlg::OnQueryDragIcon() 
{ 
	return (HCURSOR) m_hIcon; 
} 
//////////////////////////////////线程/////////////////////////////////////////// 
//////////////////////////////////线程/////////////////////////////////////////// 
 
 
 
//////////////////////////////////服务器线程开始/////////////////////////////////////////// 
 
//TCP监听线程 
UINT _ListenTcpThread(LPVOID lparam) 
{ 
	CMyQQDlg *pDlg=(CMyQQDlg *)lparam; 
	if(pDlg->StopServer==true)	return -1; 
	 
	CSocket sockSrvr; 
	pDlg->m_Potr=PORT+pDlg->m_server;//保存当前使用端口,用于关闭 
	int createSucceed=sockSrvr.Create(pDlg->m_Potr); 
	if(createSucceed==0) 
	{ 
		AfxMessageBox("_ListenTcpThread Create错误!"+pDlg->GetError(GetLastError())); 
		return -1; 
	} 
	 
	int listenSucceed=sockSrvr.Listen();	//开始监听 
	if(listenSucceed==0) 
	{ 
		AfxMessageBox("_ListenTcpThread Listen错误!"+pDlg->GetError(GetLastError())); 
		return -1; 
	} 
	 
	CSocket recSo; 
	SOCKADDR_IN client; 
	int iAddrSize=sizeof(client); 
	 
	int acceptSucceed=sockSrvr.Accept(recSo,(SOCKADDR *)&client,&iAddrSize);	//接受连接并取得对方IP 
	if(acceptSucceed==0) 
	{ 
		AfxMessageBox("_ListenTcpThread Accept错误!"+pDlg->GetError(GetLastError())); 
		return -1; 
	} 
	sockSrvr.Close(); 
	char flag[FLAG]={0};		 
	if(recSo.Receive(flag,FLAG)!=2)  
	{ 
		return -1;	 
	} 
	pDlg->m_type=flag[0]; 
	if(pDlg->m_type=='D') return 0; 
	 
	pThreadLisen=::AfxBeginThread(_ListenTcpThread,pDlg); 
	pDlg->ReceiveFileMsg(recSo,client); 
	return 0; 
	 
} 
 
 
 
 
UINT _UDPThread(LPVOID lparam)	/////UDP接受信息线程开始 
{ 
	 
	CMyQQDlg *pDlg=(CMyQQDlg *)lparam; 
	if(pDlg->StopServer==true)	return -1; 
	 
	CSocket sockSrvrUdp; 
	sockSrvrUdp.Create(PORT+pDlg->m_client,SOCK_DGRAM); 
	char buff[100]={0}; 
	int ret=0; 
	CString ipStr; 
	CString msg; 
	UINT port; 
	for(;;) 
	{ 
		 
		ret=sockSrvrUdp.ReceiveFrom(buff,100,ipStr,port);//IP和port均为返回值 
		 
		if(buff[0]=='D') return 0; 
		if(ret==SOCKET_ERROR)  
		{ 
			break; 
		} 
		msg.Format(buff); 
		pDlg->AddMsgList(ipStr,msg); 
	} 
	sockSrvrUdp.Close(); 
	return 0; 
} 
 
 
 
 
 
////////////////////////////////////服务器线程结束////////////////////////////////////// 
 
 
////////////////////////////////////客户端线程开始////////////////////////////////////// 
 
//发送文件线程 
UINT _SendFileThread(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);  
	//首先发送标记F为文件,2 
	int end=0; 
	end=sockClient.Send("F",FLAG); 
	///////////////////////////////////////////////////////////////////发送标志是否成功 
	if(end==SOCKET_ERROR)										 
	{ 
		AfxMessageBox("_SendFileThread Send错误!"+pDlg->GetError(GetLastError())); 
		return -1; 
	} 
	 
	else if(end!=2)  
	{ 
		AfxMessageBox("文件头错误"); 
		return -1; 
	} 
	/////////////////////////////////////////////////////////////////// 
	CFile myFile; 
	FILEINFO myFileInfo; 
	if(!myFile.Open(pDlg->m_fileName, CFile::modeRead | CFile::typeBinary)) 
		return -1; 
	myFileInfo.fileLength=myFile.GetLength();		//得到文件大小 
	strcpy(myFileInfo.fileName,myFile.GetFileName());//得到文件名称 
	 
	sockClient.Send(&myFileInfo,sizeof(myFileInfo));	//发送文件信息 
	 
	pDlg->m_Progress.SetRange32(0,myFileInfo.fileLength); 
	 
	myFile.Seek(0,CFile::begin); 
	char m_buf[SIZEFILE]={0}; 
	CString strError; 
	int num=0; 
	end=0; 
	int temp=0; 
	pDlg->GetDlgItem(IDC_BUTTON_STOP_FILE)->EnableWindow(true); 
	 
	for(;;) 
	{ 
		if(pDlg->FileWork==false) 
		{ 
			pDlg->FileWork=true; 
			pDlg->GetDlgItem(IDCANCEL)->EnableWindow(false); 
			pDlg->GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(false); 
		} 
		num=myFile.Read(m_buf, SIZEFILE); 
		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<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); 
	GetDlgItem(IDC_BUTTON_STOP_FILE)->EnableWindow(false); 
	 
	GetDlgItem(IDCANCEL)->EnableWindow(true); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true); 
	return 0; 
} 
 
////////////////////////////////按钮/////////////////////////////////////////////// 
////////////////////////////////按钮/////////////////////////////////////////////// 
////////////////////////////////按钮/////////////////////////////////////////////// 
 
void CMyQQDlg::OnButtonConnect() //开始连接 
{ 
	// TODO: Add your control notification handler code here 
	CString str; 
	m_You_IP.GetWindowText(str); 
	CString strOut,strIn; 
	m_You_IP.GetWindowText(strIn); 
	if(GetNamebyAddress(strIn,strOut)==-1) 
	{ 
		GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(true);//连接不可用 
		return; 
	} 
	m_MsgSend="你好"+strOut+"!"; 
	UpdateData(false); 
 
	if(m_nSockType==SOCK_TCP) 
	{ 
		 
		pThreadLisen=::AfxBeginThread(_ListenTcpThread,this);	//开始TCP线程 
		GetDlgItem(IDC_BUTTON_SEND_MSG)->EnableWindow(true);//发送消息可用 
		GetDlgItem(IDC_BUTTON_SEND_FILE)->EnableWindow(true);//文件可用 
		GetDlgItem(IDC_BUTTON_CAPUTER)->EnableWindow(true);//抓取 
	} 
	else 
	{ 
		pThreadLisen=::AfxBeginThread(_UDPThread,this);	//开始UDP线程 
		GetDlgItem(IDC_BUTTON_SEND_MSG)->EnableWindow(true);//发送可用 
		GetDlgItem(IDC_BUTTON_SEND_FILE)->EnableWindow(false);//文件不可用 
	} 
 
	GetDlgItem(IDC_RADIO_TCP)->EnableWindow(false);//单选不可用 
	GetDlgItem(IDC_RADIO_UDP)->EnableWindow(false);//单选不可用 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true);//断开可用 
	GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(false);//连接不可用 
	GetDlgItem(IDC_RADIO_SERVER)->EnableWindow(false); 
	GetDlgItem(IDC_RADIO_CLIENT)->EnableWindow(false); 
	GetDlgItem(IDC_RADIO_BOTH)->EnableWindow(false); 
	GetDlgItem(IDC_IPADDRESS)->EnableWindow(false); 
 
	 
	 
} 
 
void CMyQQDlg::OnButtonDisconnect() //关闭 
{ 
	// TODO: Add your control notification handler code here 
	GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(true); 
	GetDlgItem(IDC_RADIO_TCP)->EnableWindow(true); 
	((CButton*)GetDlgItem(IDC_RADIO_UDP))->EnableWindow(true); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(false); 
	GetDlgItem(IDC_BUTTON_SEND_MSG)->EnableWindow(false); 
	GetDlgItem(IDC_BUTTON_SEND_FILE)->EnableWindow(false); 
	m_AddMsgLIst.ResetContent(); 
	GetDlgItem(IDC_BUTTON_CLEAR)->EnableWindow(false); 
	((CButton*)GetDlgItem(IDC_RADIO_SERVER))->EnableWindow(true); 
	((CButton*)GetDlgItem(IDC_RADIO_CLIENT))->EnableWindow(true); 
	((CButton*)GetDlgItem(IDC_RADIO_BOTH))->EnableWindow(true); 
	GetDlgItem(IDC_BUTTON_CAPUTER)->EnableWindow(false); 
	GetDlgItem(IDC_IPADDRESS)->EnableWindow(true); 
	m_AddMsgLIst.SendMessage(LB_SETHORIZONTALEXTENT,0,0); 
 
/////////////////////////////////////////发送结束 
	if(m_nSockType==SOCK_TCP) 
	{ 
		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; 
			} 
		} 
	} 
	else 
	{ 
		CSocket sockClientUdp; 
		int succeedCreate=sockClientUdp.Create(m_type,SOCK_DGRAM); 
		CString strMsg="D"; 
		int ret=0; 
		CString ipStr; 
		m_You_IP.GetWindowText(ipStr); 
		UINT port=PORT+m_server; 
		ret=sockClientUdp.SendTo(strMsg,1,port,ipStr); 
		 
	} 
	 
} 
 
void CMyQQDlg::OnButtonSendMsg() //发送消息 
{ 
	// TODO: Add your control notification handler code here 
	UpdateData(true); 
	if(m_MsgSend.GetLength()==0) return; 
	if(m_nSockType==SOCK_TCP) 
		::AfxBeginThread(_SendMsgThread,this); 
	else 
		::AfxBeginThread(_SendMsgUdpThread,this); 
 
} 
 
 
void CMyQQDlg::OnButtonSendFile() //发送文件 
{ 
	// TODO: Add your control notification handler code here 
	CFileDialog dlg(true); 
	CString ip; 
	m_You_IP.GetWindowText(ip); 
	CString title="文件发往"+ip+"请选择"; 
	dlg.m_ofn.lpstrTitle=title;//标题条 
	if(dlg.DoModal()==IDOK) 
	{ 
		m_fileName=dlg.GetPathName(); 
		GetDlgItem(IDC_PROGRESS_SEND_FILE)->ShowWindow(SW_SHOW); 
		pThreadSendFile=::AfxBeginThread(_SendFileThread,this);	//开始传送文件线程 
	} 
	 
} 
 
void CMyQQDlg::OnButtonCaputer() //抓取屏幕 
{ 
	// TODO: Add your control notification handler code here 
	pThreadCaputre=::AfxBeginThread(_ThreadCapture,this);	//开始传送文件线程 
	 
} 
 
void CMyQQDlg::AddMsgList(CString IP,CString str) //添加信息于LISTBOX 控件中 
{ 
	SYSTEMTIME tm; 
	GetLocalTime(&tm); 
	CString time; 
	time.Format(_T(" %d:%02.2d"), tm.wHour, tm.wMinute); 
	m_AddMsgLIst.AddString(IP+"于"+time+"说道: "+str); 
	int numList=m_AddMsgLIst.GetCount()-1; 
	GetDlgItem(IDC_BUTTON_CLEAR)->EnableWindow(true); 
	m_AddMsgLIst.SetTopIndex(numList); 
	m_AddMsgLIst.SetCurSel(numList); 
	//水平滚动 
	int max_width=0; 
	CSize sz; 
	CClientDC dc(this); 
	for(int i=0;iEnableWindow(false); 
	m_AddMsgLIst.SendMessage(LB_SETHORIZONTALEXTENT,0,0); 
 
} 
 
void CMyQQDlg::OnRadioTcp()		//选择TCP模式 
{ 
	// TODO: Add your control notification handler code here 
	m_nSockType=SOCK_TCP; 
	CString text; 
	if(m_WorkType==0) text="MyQQ服务器"; 
	else if(m_WorkType==1) text="MyQQ客户端"; 
	else text="MyQQ"; 
	SetWindowText(text+" TCP方式"); 
 
} 
 
void CMyQQDlg::OnRadioUdp()		//选择UPD模式 
{ 
	// TODO: Add your control notification handler code here 
	m_nSockType=SOCK_UDP; 
	CString text; 
	if(m_WorkType==0) text="MyQQ服务器"; 
	else if(m_WorkType==1) text="MyQQ客户端"; 
	else text="MyQQ"; 
	SetWindowText(text+" UDP方式"); 
 
	 
} 
 
CString CMyQQDlg::GetError(DWORD error)	//返回错误信息 
{ 
	CString strError; 
	switch(error) 
	{ 
	case WSANOTINITIALISED: 
		strError="初始化错误"; 
		break; 
	case WSAENOTCONN: 
		strError="对方没有启动"; 
		break; 
	case WSAEWOULDBLOCK : 
		strError="对方已经关闭"; 
		break; 
	case WSAECONNREFUSED: 
		strError="连接的尝试被拒绝"; 
		break; 
	case WSAENOTSOCK: 
		strError="在一个非套接字上尝试了一个操作"; 
		break; 
	case WSAEADDRINUSE: 
		strError="特定的地址已在使用中"; 
		break; 
	case WSAECONNRESET: 
		strError="与主机的连接被关闭"; 
		break; 
	default: 
		strError="一般错误";	 
	} 
	return strError; 
	 
} 
 
int CMyQQDlg::GetLocalHostName(CString &sHostName)	//获得本地计算机名称 
{ 
	char szHostName[256]; 
	int nRetCode; 
	nRetCode=gethostname(szHostName,sizeof(szHostName)); 
	if(nRetCode!=0) 
	{ 
		//产生错误 
		sHostName=_T("没有取得"); 
		return GetLastError(); 
	} 
	sHostName=szHostName; 
	return 0; 
} 
 
int CMyQQDlg::GetIpAddress(const CString &sHostName, CString &sIpAddress)//获得本地IP 
{ 
	struct hostent FAR * lpHostEnt=gethostbyname(sHostName); 
	if(lpHostEnt==NULL) 
	{ 
		//产生错误 
		sIpAddress=_T(""); 
		return GetLastError(); 
	} 
	//获取IP 
	LPSTR lpAddr=lpHostEnt->h_addr_list[0]; 
	if(lpAddr) 
	{ 
		struct in_addr inAddr; 
		memmove(&inAddr,lpAddr,4); 
		//转换为标准格式 
		sIpAddress=inet_ntoa(inAddr); 
		if(sIpAddress.IsEmpty()) 
			sIpAddress=_T("没有取得"); 
	} 
	return 0; 
} 
int CMyQQDlg::GetNamebyAddress(const CString &IpAddress,CString &sYouName)//获得对方计算机名称 
{ 
	unsigned long addr; 
	addr=inet_addr(IpAddress); 
	struct hostent FAR * lpHostEnt=gethostbyaddr((char *)&addr,4,AF_INET); 
	if(lpHostEnt==NULL) 
	{ 
		//产生错误 
		sYouName=_T(""); 
 
		AfxMessageBox("连接不上");//应该取得其错误 
		return -1; 
	} 
	CString name=lpHostEnt->h_name; 
	sYouName=name; 
	return 0; 
 
} 
 
void CMyQQDlg::OnRadioServer()  
{ 
	// TODO: Add your control notification handler code here 
	CString text; 
	if(m_nSockType==SOCK_TCP) text="TCP方式"; 
	else  
		text="UDP方式"; 
	m_server=1; 
	m_client=2; 
	m_WorkType=0; 
	SetWindowText("MyQQ服务器 "+text); 
	GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("启动服务"); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->SetWindowText("关闭服务"); 
	 
} 
 
void CMyQQDlg::OnRadioClient()  
{ 
	// TODO: Add your control notification handler code here 
	CString text; 
	if(m_nSockType==SOCK_TCP) text="TCP方式"; 
	else  
		text="UDP方式"; 
	m_server=2; 
	m_client=1; 
	m_WorkType=1; 
	SetWindowText("MyQQ客户端 "+text); 
	GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("连    接"); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->SetWindowText("断开连接"); 
	 
} 
 
void CMyQQDlg::OnRadioBoth()  
{ 
	// TODO: Add your control notification handler code here 
	CString text; 
	if(m_nSockType==SOCK_TCP) text="TCP方式"; 
	else  
		text="UDP方式"; 
	m_server=m_client=0; 
	m_WorkType=2; 
	SetWindowText("MyQQ "+text); 
	GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("启    动"); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->SetWindowText("关    闭"); 
} 
 
void CMyQQDlg::OnButtonStopFile()  
{ 
	// TODO: Add your control notification handler code here 
	FileStop=true; 
	FileWork=false; 
	GetDlgItem(IDCANCEL)->EnableWindow(true); 
	GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(true); 
} 
 
LRESULT CMyQQDlg::OnKSend(WPARAM wParam,LPARAM lParam) 
{ 
	OnButtonSendMsg(); 
	return 0; 
} 
 
 
BOOL CMyQQDlg::PreTranslateMessage(MSG* pMsg)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	if (pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN) 
		 
		if(GetFocus()->GetDlgCtrlID()==IDC_EDIT_SENDMSG ||GetFocus()->GetDlgCtrlID()==IDC_BUTTON_SEND_MSG) 
		{ 
			AfxGetMainWnd()->SendMessage(WM_KSEND); 
			return TRUE; 
		} 
		return CDialog::PreTranslateMessage(pMsg); 
} 
////////////////////////////////////////////////////////////// 
 
void CMyQQDlg::OnSelchangeListBoxAddmsg()  
{ 
	// TODO: Add your control notification handler code here 
	 
}