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

📄 mytreeview.cpp

📁 qq聊天的一些基本功能,要的太飞 飞师大~
💻 CPP
字号:
// MyTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "ChatClient.h"
#include "MyTreeView.h"
#include "ClientLog.h"
#include "SendMessageDlg.h"
#include "ClientFormView.h"
#include "MainFrm.h"
#include "ShowMessage.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMyTreeView

IMPLEMENT_DYNCREATE(CMyTreeView, CTreeView)

CMyTreeView::CMyTreeView():m_Tree(GetTreeCtrl())
{
}

CMyTreeView::~CMyTreeView()
{
	POSITION pos;
	pos = m_ClientNameList.GetHeadPosition();
	POSITION tempos = pos;
	if(pos)
	{
		int iCount = m_ClientNameList.GetCount();
		for(int i = 0;i < iCount; i ++)
		{
			tempos = pos;
			Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
			delete pTempClient;
			m_ClientNameList.RemoveAt(tempos);
		}
	}

}


BEGIN_MESSAGE_MAP(CMyTreeView, CTreeView)
	//{{AFX_MSG_MAP(CMyTreeView)
	ON_WM_CREATE()
	ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
	ON_COMMAND(ID_JOININROOM, OnJoininroom)
	ON_COMMAND(ID_MENU_SEND, OnMenuSend)
	ON_WM_LBUTTONDBLCLK()
	ON_NOTIFY_REFLECT(NM_RDBLCLK, OnRclick)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnRclick)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_ADDNEWROOM,AddNewRoom)
	ON_MESSAGE(WM_NEWCLIENTCOMEIN,OnNewClientIn)
	ON_MESSAGE(WM_USERLOGOUT,OnClientOut)
	ON_MESSAGE(WM_SAYINPRIVATE,OnSayInPrivate)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyTreeView drawing

void CMyTreeView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CMyTreeView diagnostics

#ifdef _DEBUG
void CMyTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CMyTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG
extern CChatClientApp theApp;
void CMyTreeView::AddNewRoom(Message wParam,LPARAM lParam)
{
		//CString
	
	CMainFrame * m_pMainFrame = (CMainFrame *)AfxGetMainWnd();
	ASSERT_VALID(m_pMainFrame);
	ASSERT(m_pMainFrame != NULL);
	static int iTimes = 1;
	if(iTimes == 1)
	{
		AfxGetMainWnd()->ShowWindow(SW_SHOWNORMAL);
		m_pMainFrame ->GetFormView()->SetDlgItemText(IDC_SELFNAME,theApp.m_skMainSocket.GetUserName());
		iTimes ++;
	}

	Message msObj = wParam;
	CString strRoom = msObj.strRoom;
	m_Tree.InsertItem(strRoom,2,3,m_ParentItem);
//	m_Tree.InsertItem("strRoom",2,3,m_ParentItem);
	m_Tree.Expand(m_ParentItem,TVE_EXPAND);
	
}

/////////////////////////////////////////////////////////////////////////////
// CMyTreeView message handlers

int CMyTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CTreeView::OnCreate(lpCreateStruct) == -1)
		return -1;


	// TODO: Add your specialized creation code here
	m_ImageList.Create(IDB_IMAGELIST,16,5,RGB(255,0,255));
	m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
	m_ParentItem = m_Tree.InsertItem("聊天室列表",2,3);
	
	return 0;
}
extern CChatClientApp theApp;

void CMyTreeView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	
	CMenu menu;

	CMenu * pContextMenu; 
	POINT point;
	GetCursorPos(&point);
//	CTreeView::OnLButtonDown(0,point);
	ScreenToClient(&point);
	
	HTREEITEM hItem = m_Tree.GetSelectedItem();
	CRect rect;
	m_Tree.GetItemRect(hItem,&rect,TRUE);

	if(rect.PtInRect(point))
	{
		if(m_Tree.GetParentItem(hItem) == m_ParentItem)
		{
			menu.LoadMenu(IDR_JOINROOM);
			pContextMenu = menu.GetSubMenu(0);
			ClientToScreen(&point);
			
			pContextMenu->TrackPopupMenu(TPM_LEFTBUTTON   ,point.x,point.y ,this);
		}
		else
		{
			if(hItem != m_ParentItem && m_Tree.GetItemText(hItem) != theApp.m_skMainSocket.GetUserName() && theApp.m_skMainSocket.GetState() == HAVELOGIN)
			{
				HTREEITEM hParent = m_Tree.GetParentItem(hItem);
				CString strRoom = m_Tree.GetItemText(hParent);
				if(strRoom == theApp.m_skMainSocket.GetRoomName())
				{
					menu.LoadMenu(IDR_CLIENT);
					pContextMenu = menu.GetSubMenu(0);
					ClientToScreen(&point);
					
					pContextMenu->TrackPopupMenu(TPM_LEFTBUTTON   ,point.x,point.y ,this);
					
				}
				else
					AfxMessageBox("处于不同的房间内,不能执行此项操作");
			}

		}
	}


	*pResult = 0;
}
extern CChatClientApp theApp;
void CMyTreeView::OnJoininroom() 
{
	// TODO: Add your command handler code here
	Message msObj;
	HTREEITEM hItem;
	
	if(theApp.m_skMainSocket.GetState() == NOTLOGIN)
	{
	//构造msobj
	

		hItem = m_Tree.GetSelectedItem();
		CString strRoomName = m_Tree.GetItemText(hItem);
		CString strUsrName = theApp.m_skMainSocket.GetUserName();
	//	theApp.m_skMainSocket.SetUserName(strUsrName);
		theApp.m_skMainSocket.SetRoomName(strRoomName);
		theApp.m_skMainSocket.SetState(HAVELOGIN);
	

		msObj.iType = USERLOG;
		msObj.iSubType = USERLOGIN;
		int iLen = strRoomName.GetLength();
		iLen > 20 ? 20: iLen;
		lstrcpy(msObj.strRoom,_T(strRoomName.GetBuffer(iLen)));
		strRoomName.ReleaseBuffer();
		
		iLen = strUsrName.GetLength();
		iLen > 20 ? 20 : iLen;
		lstrcpy(msObj.strName,_T(strUsrName.GetBuffer(iLen)));
		strUsrName.ReleaseBuffer();
		
		iLen = theApp.m_skMainSocket.Send(&msObj,sizeof(msObj));
		if(iLen < sizeof(msObj))
		{
			AfxMessageBox("发送失败");
			return;
		}	
	}
	else
		if(theApp.m_skMainSocket.GetState() == HAVELOGIN)
		{
			HTREEITEM hItem = m_Tree.GetSelectedItem();
			CString strRoomName = m_Tree.GetItemText(hItem);
			if(strRoomName != theApp.m_skMainSocket.GetRoomName())
			{
				
				HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
							
				msObj.iType = USERSESSION;
				msObj.iSubType = CHANGEROOM;
				//用户名
				CString strTemp;
				strTemp =  theApp.m_skMainSocket.GetUserName();
				int iLen = strTemp.GetLength();
				iLen > 20 ? 20:iLen;
				lstrcpy(msObj.strName,_T(strTemp.GetBuffer(iLen)));
				strTemp.ReleaseBuffer();
				//旧房件名
				strTemp = theApp.m_skMainSocket.GetRoomName();
				iLen = strTemp.GetLength();
				iLen > 20 ? 20 : iLen;
				lstrcpy(msObj.strRoom,_T(strTemp.GetBuffer(iLen)));
				strTemp.ReleaseBuffer();
				//新房间名
				hItem = m_Tree.GetSelectedItem();
				strTemp = m_Tree.GetItemText(hItem);
				iLen = strTemp.GetLength();
				iLen > 20 ? 20 :iLen;
				lstrcpy(msObj.strContent,_T(strTemp.GetBuffer(iLen)));
				strTemp.ReleaseBuffer();
				
				if(theApp.m_skMainSocket.Send(&msObj,sizeof(msObj)) != sizeof(msObj))
				{
					AfxMessageBox("发送错误");
				}
				theApp.m_skMainSocket.SetRoomName(m_Tree.GetItemText(hItem));
			}
		}			
	return;
	
}
void CMyTreeView::OnClientOut(Message wParam, LPARAM lParam)
{
	Message msObj = wParam;
	CString strRoom = msObj.strRoom;
	CString strUsrName = msObj.strName;
	HTREEITEM	hItem = m_Tree.GetChildItem(m_ParentItem);
	BOOL bFind = FALSE;
	while(hItem && !bFind)
	{
		CString strNodeName = m_Tree.GetItemText(hItem);
		if(strNodeName == strRoom)
		{
			//查找用户名的那一项
			HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
			while(hChildItem)
			{
				CString strUserNode = m_Tree.GetItemText(hChildItem);
				if(strUserNode == strUsrName)
				{
					m_Tree.DeleteItem(hChildItem);
					m_Tree.Expand(hItem,TVE_EXPAND);
					bFind = TRUE;
					break;
				}
				hChildItem = m_Tree.GetNextItem(hChildItem,1);
			}
			
		
		}
		hItem = m_Tree.GetNextItem(hItem,1);
	}
}
void CMyTreeView::OnNewClientIn(Message wParam, LPARAM lParam)
{
	Message msObj = wParam;
	CString strRoom = msObj.strRoom;
	CString strUsrName = msObj.strName;
	//自己加入的消息传入进来
	if(strRoom == theApp.m_skMainSocket.GetRoomName() && strUsrName == theApp.m_skMainSocket.GetUserName())
	{
		//改变FormView中的数据
		CClientFormView * m_pFormView =(CClientFormView *) ((CMainFrame * )AfxGetMainWnd())->GetFormView();
		ASSERT(m_pFormView != NULL);
		ASSERT_VALID(m_pFormView);
		m_pFormView ->SetDlgItemText(IDC_SELFNAME,strUsrName);
		m_pFormView ->SetDlgItemText(IDC_ROOMNAME,strRoom);
		//改变任务栏图标的提醒信息
		lstrcpy(theApp.TaskIcon.szTip,_T(strUsrName.GetBuffer(strUsrName.GetLength())));
		Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);
		//显示正常的窗口
	

		return;
	}

	HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
	while(hItem)
	{
		CString strNodeName = m_Tree.GetItemText(hItem);
		CString strTemp = theApp.m_skMainSocket.GetUserName();
		if(strNodeName == strRoom)
		{
			if(strUsrName != strTemp)
			{
				m_Tree.InsertItem(strUsrName,0,1,hItem);
				m_Tree.Expand(hItem,TVE_EXPAND);
				break;
			}
		}
		hItem = m_Tree.GetNextItem(hItem,1);
	}


}

void CMyTreeView::OnMenuSend() 
{
	// TODO: Add your command handler code here
	CSendMessageDlg Dlg;
	
	if(Dlg.DoModal() == IDOK)
	{
		if(Dlg.m_strSentence.GetLength())
		{
			if(Dlg.m_strSentence.GetLength == 0)
				return;
			Message msObj;
			memset(&msObj,0,sizeof(Message));
			msObj.iType = USERSESSION;
			msObj.iSubType = SAYINPRIVATE;
			CString strTemp  = theApp.m_skMainSocket.GetRoomName();
			int iLen = strTemp.GetLength();
			lstrcpy(msObj.strRoom,_T(strTemp.GetBuffer(iLen)));
			strTemp.ReleaseBuffer();
			strTemp = Dlg.m_strSentence;
			iLen = strTemp.GetLength();
			iLen > 1024 ? 1024 : iLen;
			lstrcpy(msObj.strContent,_T(strTemp.GetBuffer(iLen)));
			strTemp.ReleaseBuffer();
			//自己的名字
			strTemp = theApp.m_skMainSocket.GetUserName();
			iLen = strTemp.GetLength();
			iLen > 20 ? 20:iLen;
			lstrcpy(msObj.strName,_T(strTemp.GetBuffer(iLen)));
			strTemp.ReleaseBuffer();
			//说话对象的名字
			HTREEITEM hItem = m_Tree.GetSelectedItem();
			strTemp = m_Tree.GetItemText(hItem);
			iLen = strTemp.GetLength();
			iLen > 20 ? 20 : iLen;
			lstrcpy(msObj.strClientName,_T(strTemp.GetBuffer(iLen)));
			strTemp.ReleaseBuffer();

			 iLen = theApp.m_skMainSocket.Send(&msObj,sizeof(Message));


		}
		
	}

	return;	
}
//接收到信息
//整个的处理过程是这样:
//首先,接收到信息以后,在m_ClientNameList中添加一项,这样,在ontimer中,可以检查链表中都是有谁在发送信息,而且
//你还没有回复.这样OnTimer中就可以实现多个人的头像一起晃动。
//当你回复或者取消以后,相应的应该在m_ClientNameList中删除已经恢复或者取消的那一项。
void CMyTreeView::OnSayInPrivate(Message wParam,LPARAM lParam)
{
	Message msObj = wParam;
	
	CString strClientName = msObj.strName;
	Client * pNewClient;
	//设置每一个Client对应的ontimer中IDEVENT
	pNewClient = new Client();
	int iCount = m_ClientNameList.GetCount();
	pNewClient ->SetUserName(strClientName);
	int iMaxId = 1;
	if(iCount == 0)
	{
		pNewClient ->SetTimerId(iMaxId);
	
	}
	else
	{
		//查找出最大的iTimerId;
	
		POSITION pos;
		pos = m_ClientNameList.GetHeadPosition();
		if(pos)
		{
			for(int i = 0; i< iCount; i ++)
			{
				Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
				if(iMaxId > pTempClient ->GetTimerId())
					iMaxId = pTempClient ->GetTimerId();

			}

			iMaxId ++;
		}
	
		pNewClient ->SetTimerId(iMaxId);

	}
	m_ClientNameList.AddTail(pNewClient);
	//启动Ontimer
	SetTimer(iMaxId,800,NULL);
	//显示对话框
	CString strContent  = msObj.strContent;
	CShowMessage Dlg(strContent,strClientName,iMaxId);
	Dlg.DoModal();
	SetIcon(strClientName,0,1);
	////

	return;
}

BOOL CMyTreeView::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class
	cs.style |= TVS_HASLINES;
	cs.style |= TVS_LINESATROOT;
	cs.style |= TVS_HASBUTTONS;
	return CTreeView::PreCreateWindow(cs);
}

//启动ONtimer。主要是让用户的图标晃动,并且发出报警的声音
void CMyTreeView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	POSITION pos;
	pos = m_ClientNameList.GetHeadPosition();
	int iCount = m_ClientNameList.GetCount();

	if(pos)
	{	
	
								
		for(int i = 0 ;i < iCount; i++)
		{
			Client * pTempClient =(Client *) m_ClientNameList.GetNext(pos);
			if(nIDEvent ==(UINT) pTempClient->GetTimerId())
			{
				int i = pTempClient ->GetTimes();
				pTempClient->AddTimes();
				i %= 2;
				if(i == 1)
				{
					theApp.TaskIcon.hIcon = theApp.LoadIcon(IDI_EMPTY);
					Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);						
					PlaySound("msg.wav",NULL,SND_ASYNC);
					SetIcon(pTempClient ->GetUserName(),0,0);
				}
				else
				{
					theApp.TaskIcon.hIcon = theApp.LoadIcon(IDI_TASKICON);
					Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);						
	
					SetIcon(pTempClient ->GetUserName(),5,5);
				}
		
			}//end if IDEvent == 
			
		}//endfor
	
	}//end if pos
	CTreeView::OnTimer(nIDEvent);
}
//在创建的链表中删除一项
void CMyTreeView::DeleteOneClient(const CString & strName,const int iID)
{
	POSITION pos;
	pos = m_ClientNameList.GetHeadPosition();
	int iCount = m_ClientNameList.GetCount();
	POSITION tempos = pos;
	if(pos && iCount)
	{
	
		for(int i = 0;i < iCount; i ++)
		{
			tempos = pos;
			Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
			if(pTempClient->GetUserName() == strName && pTempClient->GetTimerId() == iID)
			{
				delete pTempClient;
				m_ClientNameList.RemoveAt(tempos);
				break;
			}
		}
	}
	
	
		
	
	return;	
}
//设置树型控件中某一项的图标
void CMyTreeView::SetIcon(const CString &strClientName,const int iNormalIcon,const int iSelectedIcon)
{

	CString strRoom;
	strRoom = theApp.m_skMainSocket.GetRoomName();
	HTREEITEM	hItem = m_Tree.GetChildItem(m_ParentItem);
	BOOL bFind = FALSE;
	while(hItem && !bFind)
	{
		CString strNodeName = m_Tree.GetItemText(hItem);
		if(strNodeName == strRoom)
		{
			//查找用户名的那一项
			HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
			while(hChildItem)
			{
				CString strUserNode = m_Tree.GetItemText(hChildItem);
				if(strUserNode == strClientName)
				{
					m_Tree.SetItemImage(hChildItem,iNormalIcon,iSelectedIcon);

				}
				hChildItem = m_Tree.GetNextItem(hChildItem,1);
			}
			
			
		}
		hItem = m_Tree.GetNextItem(hItem,1);
	}
}

⌨️ 快捷键说明

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