imsdlg.cpp

来自「本系统所完成功能如下: &#61548 即时消息:用户之间发送即时消息。 」· C++ 代码 · 共 845 行 · 第 1/2 页

CPP
845
字号
// IMSDlg.cpp : implementation file
//

#include "stdafx.h"
#include "IMS.h"
#include "IMSDlg.h"
#include "LoginDlg.h"
#include "QueryDlg.h"
#include "head.h"
#include "Broadcast.h"
#include "DelUser.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// 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()

/////////////////////////////////////////////////////////////////////////////
// CIMSDlg dialog

CIMSDlg::CIMSDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CIMSDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CIMSDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CIMSDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CIMSDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CIMSDlg, CDialog)
	//{{AFX_MSG_MAP(CIMSDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_VIP, OnBtnVip)
	ON_BN_CLICKED(IDC_BTN_BROADCAST, OnBtnBroadcast)
	ON_BN_CLICKED(IDC_BTN_CANCEL, OnCancel)
	ON_BN_CLICKED(IDC_BTN_DELUSER, OnBtnDeluser)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_RECVDATA,OnRecvData)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIMSDlg message handlers

BOOL CIMSDlg::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
	LoginDlg ld;
	if(ld.DoModal()==IDOK)
	{
		CoInitialize(NULL);
		_ConnectionPtr pConn(__uuidof(Connection));
		_RecordsetPtr pRst(__uuidof(Recordset));
		//_CommandPtr pCmd(__uuidof(Command));
		pConn->ConnectionString="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=TL;Initial Catalog=IM;Data Source=TLFZN";
		pConn->Open("","","",adConnectUnspecified);

		CString str;
		str.Format("select * from MngTbl where MngID=%d",ld.m_mID);
		pRst=pConn->Execute((_bstr_t)str,NULL,adCmdText);
		  
		if(!pRst->rsEOF)
		{
			_variant_t vstr;
			vstr = pRst->GetCollect("MngPW");
			if( vstr.iVal!=ld.m_mPassword )
			{
				MessageBox("ID或密码错误!请重新登陆!");
				exit(0);
			}
		}
		else
			{
				MessageBox("ID或密码错误!请重新登陆!");
				exit(0);
			}

		pRst->Close();
		pConn->Close();
		//pCmd.Release();
		pRst.Release();
		pConn.Release();
		CoUninitialize();
	}
	else exit(0);
	//初始化窗口句柄为了消息映射时接收消息	
	jubing=m_hWnd;

	//初始化UDP套接字
	InitUDPSocket();
	//UDP无需接受所以无需子线程

	//初始化TCP套接字
	InitTCPSocket();
	//创建子进程接收客户端TCP连接请求 传递参数为初始化TCP套接字,调用LinkProc函数
	HANDLE hThread=CreateThread(NULL,0,LinkProc,(LPVOID)m_TCPsocket,0,NULL);
	CloseHandle(hThread);
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CIMSDlg::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 CIMSDlg::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 CIMSDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CIMSDlg::OnCancel() 
{
	// TODO: Add your control notification handler code here
	closesocket(m_TCPsocket);
	exit(0);
}

BOOL CIMSDlg::InitUDPSocket()
{
	m_UDPsocket=socket(AF_INET,SOCK_DGRAM,0);
	if(INVALID_SOCKET==m_UDPsocket)
	{
		AfxMessageBox("套接字创建失败!");
		exit(1);
	}
	SOCKADDR_IN addrSend;
	addrSend.sin_family=AF_INET;
	addrSend.sin_port=htons(12345);
	addrSend.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/*inet_addr("59.72.27.169")*/;

	int retval;
	retval=bind(m_UDPsocket,(SOCKADDR*)&addrSend,sizeof(SOCKADDR));
	if(SOCKET_ERROR==retval)
	{
		int t;
		t = WSAGetLastError();
		closesocket(m_UDPsocket);
		MessageBox("绑定失败!");
		exit(1);
	}
	return TRUE;
}


BOOL CIMSDlg::InitTCPSocket()
{
	m_TCPsocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(INVALID_SOCKET==m_TCPsocket)
	{
		AfxMessageBox("套接字创建失败!");
		exit(1);
	}
	SOCKADDR_IN addrListen;
	addrListen.sin_family=AF_INET;
	addrListen.sin_port=htons(700);
	addrListen.sin_addr.S_un.S_addr=htonl(INADDR_ANY);



	int retval;
	retval=bind(m_TCPsocket,(SOCKADDR*)&addrListen,sizeof(SOCKADDR));
	if(SOCKET_ERROR==retval)
	{
		int t;
		t = WSAGetLastError();
		closesocket(m_TCPsocket);
		MessageBox("绑定失败!");
		exit(1);
	}
	if(listen(m_TCPsocket, SOMAXCONN) == SOCKET_ERROR)
	{
		MessageBox("无法监听!");
		closesocket(m_TCPsocket);
		exit(1);
	}
	return TRUE;
}


DWORD WINAPI CIMSDlg::LinkProc(LPVOID lpParameter)
{
	//子进程接收客户端TCP连接请求 处理函数
	SOCKET sock= (SOCKET)lpParameter;
	SOCKET subsock;
	RECVPARAM *pRecvParam=new RECVPARAM;
	while(TRUE)
	{
		SOCKADDR_IN addrFrom;
		int len=sizeof(SOCKADDR);
		subsock=::accept(sock,(SOCKADDR*)&addrFrom,&len);		
		
		if(subsock!=INVALID_SOCKET)
		{
			pRecvParam->sock=subsock;
			pRecvParam->IPPortBuf.Format("%s",inet_ntoa(addrFrom.sin_addr));

			//接收到连接请求后 系统再创建个子进程专门处理该连接
			//传递参数为子套接字和IP地址
			//子进程处理的函数为RecvProc
			HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
			CloseHandle(hThread);
		}
	}
	return 0;
}


DWORD WINAPI CIMSDlg::RecvProc(LPVOID lpParameter)
{
	//子进程处理的函数
	SOCKET sock=((RECVPARAM*)lpParameter)->sock;//从传递参数中获取套接字

	char recvBuf[1024];
	int retval;
	RECVPARAM *pRecvParam=new RECVPARAM;
	
	while(TRUE)
	{
		retval=recv(sock,recvBuf,1024,0);
		if(SOCKET_ERROR==retval||retval==0)
			break;
		pRecvParam->IPPortBuf =((RECVPARAM*)lpParameter)->IPPortBuf;
		pRecvParam->sock=sock;

		//接收到请求后采用消息传递给窗口句柄 
		//并且将本函数的参数和接收到的数据包作为参数传递给窗口
		//而窗口则调用成员函数对传递参数处理
		::PostMessage(jubing,WM_RECVDATA,(WPARAM)pRecvParam,(LPARAM)recvBuf);
	}
	return 0;
}



void CIMSDlg::OnBtnVip() 
{
	// TODO: Add your control notification handler code here
	QueryDlg qd;
	qd.DoModal();
}

void CIMSDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
	CString str2=((RECVPARAM*)wParam)->IPPortBuf,str1=((char *)lParam);
	SOCKET sock=((RECVPARAM*)wParam)->sock;//传str2: ip和str1: 内容
	char c=str1.GetAt(0);
	str1.Delete(0,1);
	/*		根据标志位判断进入什么服务处理
			A: 用户登陆服务
			B: 添加好友服务
			C: 删除好友服务
			D: 注册服务
			E: 离线通知服务
			F: 获取好友列表服务
			其他:抛弃请求包
	*/
	switch(c)
	{
	case 'a':	UserLogin(str1,str2,sock);break;
	case 'b':	AddfriendProc(str1,sock);break;
	case 'c':	DelfriendProc(str1,sock);break;
	case 'd':	RegProc(str1,sock);break;
	case 'e':	QuitProc(atoi(str1),FALSE);closesocket(sock);break;
	case 'f':	GetFriendMsg(atoi(str1),sock);
	default:;
	}

}

void CIMSDlg::OnBtnBroadcast() 
{
	// TODO: Add your control notification handler code here
	Broadcast bd;
	bd.m_UDPsocket=m_UDPsocket;
	bd.DoModal();
}

void CIMSDlg::OnBtnDeluser() 
{
	// TODO: Add your control notification handler code here
	DelUser du;
	du.DoModal();
}

void CIMSDlg::UserLogin(CString str1,CString str2,SOCKET sock)
{
	//str1:用户号码和密码和端口;str2:ip

	//A: 用户登陆服务

	//转换ID,密码和端口
	int uid,password,port,j=1;
		CString s=str1.GetAt(0);
		for(int i=1;i<str1.GetLength();i++)
		{
			if(str1.GetAt(i)!='#')
				s=s+str1.GetAt(i);
			else
			{
				if(j==1)
				{
					uid=atoi(s);
					s="";

⌨️ 快捷键说明

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