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

📄 ircchanneltabctrl.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include <Mmsystem.h>
#include "ircchanneltabctrl.h"
#include "ircwnd.h"
#include "ircmain.h"
#include "emuledlg.h"
#include "OtherFunctions.h"
#include "MenuCmds.h"
#include "emule.h"
#include "HTRichEditCtrl.h"

struct Channel
{
	CString	name;
	CString modesA;
	CString modesB;
	CString modesC;
	CString modesD;
	CHTRichEditCtrl log;
	CString title;
	CPtrList nicks;
	uint8 type;
	CStringArray history;
	uint16 history_pos;
	// Type is mainly so that we can use this for IRC and the eMule Messages..
	// 1-Status, 2-Channel list, 4-Channel, 5-Private Channel, 6-eMule Message(Add later)
};

IMPLEMENT_DYNAMIC(CIrcChannelTabCtrl, CClosableTabCtrl)

BEGIN_MESSAGE_MAP(CIrcChannelTabCtrl, CClosableTabCtrl)
	ON_WM_CONTEXTMENU()
	ON_WM_LBUTTONUP()
	ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnTcnSelchangeTab2)
END_MESSAGE_MAP()

CIrcChannelTabCtrl::CIrcChannelTabCtrl()
{
	m_pCurrentChannel = NULL;
	m_pParent = NULL;
	m_bCloseable = true;
	memset(&m_iiCloseButton, 0, sizeof m_iiCloseButton);
	m_ptCtxMenu.SetPoint(-1, -1);
}

CIrcChannelTabCtrl::~CIrcChannelTabCtrl()
{
	//Remove and delete all our open channels.
	DeleteAllChannel();
}

void CIrcChannelTabCtrl::Init()
{
	//This adds the two static windows, Status and ChanneList
	NewChannel( GetResString(IDS_STATUS), 1 );
	NewChannel( GetResString(IDS_IRC_CHANNELLIST), 2);
	//Initialize the IRC window to be in the ChannelList
	m_pCurrentChannel = (Channel*)channelPtrList.GetTail();
	SetCurSel(0);
	OnTcnSelchangeTab2( NULL, NULL );
	SetAllIcons();
}

void CIrcChannelTabCtrl::OnSysColorChange()
{ 
	CClosableTabCtrl::OnSysColorChange();
	SetAllIcons();
}

void CIrcChannelTabCtrl::SetAllIcons()
{
	CImageList iml;
	iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1);
	iml.Add(CTempIconLoader(_T("Chat")));
	iml.Add(CTempIconLoader(_T("Message")));
	iml.Add(CTempIconLoader(_T("MessagePending")));
	SetImageList(&iml);
	m_imlIRC.DeleteImageList();
	m_imlIRC.Attach(iml.Detach());
	SetPadding(CSize(10, 0));
}

void CIrcChannelTabCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{ 
	int iCurTab = GetTabUnderMouse(point);
	if (iCurTab < 2)
	{
		return;
	}
	TCITEM item;
	item.mask = TCIF_PARAM;
	GetItem(iCurTab, &item);

	Channel* chan = FindChannelByName(((Channel*)item.lParam)->name);
	if( !chan )
	{
		return;
	}

	CTitleMenu ChatMenu;
	ChatMenu.CreatePopupMenu();
	ChatMenu.AddMenuTitle(GetResString(IDS_IRC)+_T(" : ")+chan->name);
	ChatMenu.AppendMenu(MF_STRING, Irc_Close, GetResString(IDS_FD_CLOSE));
	if (iCurTab < 2) // no 'Close' for status log and channel list
		ChatMenu.EnableMenuItem(Irc_Close, MF_GRAYED);

	int totallength = m_sChannelModeSettingsTypeA.GetLength()+m_sChannelModeSettingsTypeB.GetLength()+m_sChannelModeSettingsTypeC.GetLength()+m_sChannelModeSettingsTypeD.GetLength();
	int index = 0;
	if( totallength > index )
	{
		int length = m_sChannelModeSettingsTypeA.GetLength();
		for( int i = 0; i < length; i++)
		{
			CString mode = m_sChannelModeSettingsTypeA.Mid(i,1);
			if( chan->modesA.Find(mode[0]) == -1 )
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
				ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
			}
			else
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Not Supported Yet )") );
				ChatMenu.EnableMenuItem(Irc_ChanCommands+index+50, MF_GRAYED);
			}
			index++;
		}
		length = m_sChannelModeSettingsTypeB.GetLength();
		for( int i = 0; i < length; i++)
		{
			CString mode = m_sChannelModeSettingsTypeB.Mid(i,1);
			if( chan->modesB.Find(mode[0]) == -1 )
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
				ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
			}
			else
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Not Supported Yet )") );
				ChatMenu.EnableMenuItem(Irc_ChanCommands+index+50, MF_GRAYED);
			}
			index++;
		}
		length = m_sChannelModeSettingsTypeC.GetLength();
		for( int i = 0; i < length; i++)
		{
			CString mode = m_sChannelModeSettingsTypeC.Mid(i,1);
			if( chan->modesC.Find(mode[0]) == -1 )
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
				ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
			}
			else
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Remove ") + mode + _T(" )") );
			}
			index++;
		}
		length = m_sChannelModeSettingsTypeD.GetLength();
		for( int i = 0; i < length; i++)
		{
			CString mode = m_sChannelModeSettingsTypeD.Mid(i,1);
			if( chan->modesD.Find(mode[0]) == -1 )
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Add ") + mode + _T(" )") );
			}
			else
			{
				ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Remove ") + mode + _T(" )") );
			}
			index++;
		}
	}

	ChatMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
	VERIFY( ChatMenu.DestroyMenu() );
}

int CIrcChannelTabCtrl::GetTabUnderMouse(CPoint point) 
{
	TCHITTESTINFO hitinfo;
	CRect rect;
	GetWindowRect(&rect);
	point.Offset(0-rect.left,0-rect.top);
	hitinfo.pt = point;

	if( GetItemRect( 0, &rect ) )
		if (hitinfo.pt.y< rect.top+30 && hitinfo.pt.y >rect.top-30)
			hitinfo.pt.y = rect.top;

	// Find the destination tab...
	unsigned int nTab = HitTest( &hitinfo );
	if( hitinfo.flags != TCHT_NOWHERE )
		return nTab;
	else
		return -1;
}

Channel* CIrcChannelTabCtrl::FindChannelByName(CString name)
{
	POSITION pos1, pos2;
	for (pos1 = channelPtrList.GetHeadPosition();( pos2 = pos1 ) != NULL;)
	{
		channelPtrList.GetNext(pos1);
		Channel* cur_channel = (Channel*)channelPtrList.GetAt(pos2);
		if (cur_channel->name.CompareNoCase(name.Trim()) == 0 && (cur_channel->type == 4 || cur_channel->type == 5))
			return cur_channel;
	}
	return 0;
}

Channel* CIrcChannelTabCtrl::NewChannel( CString name, uint8 type )
{
	Channel* toadd = new Channel;
	toadd->name = name;
	toadd->title = name;
	toadd->type = type;
	toadd->history_pos = 0;
	if (type != 2)
	{
		CRect rcChannel;
		m_pParent->m_serverChannelList.GetWindowRect(&rcChannel);
		toadd->log.Create(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | ES_MULTILINE | ES_READONLY, rcChannel, m_pParent, (UINT)-1);
		toadd->log.ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_FRAMECHANGED);
		toadd->log.SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3));
		toadd->log.SetEventMask(toadd->log.GetEventMask() | ENM_LINK);
		toadd->log.SetFont(&theApp.emuledlg->m_fontHyperText);
		toadd->log.SetTitle(name);
		toadd->log.SetProfileSkinKey(_T("IRCChannel"));
		toadd->log.ApplySkin();
	}
	channelPtrList.AddTail(toadd);
	
	TCITEM newitem;
	newitem.mask = TCIF_PARAM|TCIF_TEXT|TCIF_IMAGE;

	newitem.lParam = (LPARAM)toadd;
	newitem.pszText = name.GetBuffer();
	newitem.iImage = 1; // 'Message'
	uint32 pos = GetItemCount();
	InsertItem(pos,&newitem);
	if(type == 4)
	{
		SetCurSel(pos);
		SetCurFocus(pos);
		OnTcnSelchangeTab2( NULL, NULL );
	}
	return toadd;
}

void CIrcChannelTabCtrl::RemoveChannel( CString channel )
{
	Channel* todel = FindChannelByName( channel );
	if( !todel )
		return;
	TCITEM item;
	item.mask = TCIF_PARAM;
	item.lParam = -1;
	int i;
	for (i = 0; i < GetItemCount();i++)
	{
		GetItem(i,&item);
		if (((Channel*)item.lParam) == todel)
			break;
	}
	if (((Channel*)item.lParam) != todel)
		return;
	DeleteItem(i);

	if( todel == m_pCurrentChannel )
	{
		m_pParent->m_nicklist.DeleteAllItems();
		if( GetItemCount() > 2 && i > 1 ) 
		{
			if ( i == 2 )
				i++;
			SetCurSel(i-1);
			SetCurFocus(i-1);
			OnTcnSelchangeTab2( NULL, NULL );
		}
		else 
		{
			SetCurSel(0);
			SetCurFocus(0);
			OnTcnSelchangeTab2( NULL, NULL );
		}
	}
	m_pParent->m_nicklist.DeleteAllNick(todel->name);
	channelPtrList.RemoveAt(channelPtrList.Find(todel));
	delete todel;
}

void CIrcChannelTabCtrl::DeleteAllChannel()
{
	POSITION pos1, pos2;
	for (pos1 = channelPtrList.GetHeadPosition();( pos2 = pos1 ) != NULL;)
	{
		channelPtrList.GetNext(pos1);
		Channel* cur_channel =	(Channel*)channelPtrList.GetAt(pos2);
		m_pParent->m_nicklist.DeleteAllNick(cur_channel->name);
		channelPtrList.RemoveAt(pos2);
		delete cur_channel;
	}
}


bool CIrcChannelTabCtrl::ChangeChanMode( CString channel, CString nick, CString mode )
{
	if( channel.Left(1) != _T("#") )
	{
		//Not a channel, this shouldn't happen
		return true;
	}
	//We are changing a mode to something..
	Channel* update = FindChannelByName( channel );
	if( !update )
	{
		//No channel found, this shouldn't happen.
		return false;
	}
	//Update modes.
	int modeLevel = m_sChannelModeSettingsTypeA.Find(mode[1]);
	if( modeLevel != -1 )
	{
		//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
		update->modesA.Remove(mode[1]);
		if( mode.Left(1) == _T("+") )
		{
			if( update->modesA == _T("") )
			{
				//Channel has no modes, just set it.. 
				update->modesA = mode[1];
			}
			else
			{
				//The chan does have other modes.. Lets make sure we put things in order..
				int index = 0;
				//This will pad the mode string..
				while( index < m_sChannelModeSettingsTypeA.GetLength() )
				{
					if( update->modesA.Find(m_sChannelModeSettingsTypeA[index]) == -1 )
						update->modesA.Insert(index, _T(" "));
					index++;
				}
				//Insert the new mode
				update->modesA.Insert(modeLevel, mode[1]);
				//Remove pads
				update->modesA.Remove(_T(' '));
			}
		}
		return true;
	}
	modeLevel = m_sChannelModeSettingsTypeB.Find(mode[1]);
	if( modeLevel != -1 )
	{
		//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
		update->modesB.Remove(mode[1]);
		if( mode.Left(1) == _T("+") )
		{
			if( update->modesB == _T("") )
			{
				//Channel has no modes, just set it.. 
				update->modesB = mode[1];
			}
			else
			{
				//The chan does have other modes.. Lets make sure we put things in order..
				int index = 0;
				//This will pad the mode string..
				while( index < m_sChannelModeSettingsTypeB.GetLength() )
				{
					if( update->modesB.Find(m_sChannelModeSettingsTypeB[index]) == -1 )
						update->modesB.Insert(index, _T(" "));
					index++;
				}
				//Insert the new mode
				update->modesB.Insert(modeLevel, mode[1]);
				//Remove pads
				update->modesB.Remove(_T(' '));
			}
		}
		return true;
	}
	modeLevel = m_sChannelModeSettingsTypeC.Find(mode[1]);
	if( modeLevel != -1 )
	{
		//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
		update->modesC.Remove(mode[1]);
		if( mode.Left(1) == _T("+") )
		{
			if( update->modesC == _T("") )
			{
				//Channel has no modes, just set it.. 
				update->modesC = mode[1];
			}
			else
			{
				//The chan does have other modes.. Lets make sure we put things in order..
				int index = 0;
				//This will pad the mode string..
				while( index < m_sChannelModeSettingsTypeC.GetLength() )
				{
					if( update->modesC.Find(m_sChannelModeSettingsTypeC[index]) == -1 )
						update->modesC.Insert(index, _T(" "));
					index++;
				}
				//Insert the new mode
				update->modesC.Insert(modeLevel, mode[1]);
				//Remove pads
				update->modesC.Remove(_T(' '));
			}
		}
		return true;
	}
	modeLevel = m_sChannelModeSettingsTypeD.Find(mode[1]);
	if( modeLevel != -1 )
	{
		//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
		update->modesD.Remove(mode[1]);
		if( mode.Left(1) == _T("+") )
		{
			if( update->modesD == _T("") )
			{
				//Channel has no modes, just set it.. 
				update->modesD = mode[1];
			}
			else
			{
				//The chan does have other modes.. Lets make sure we put things in order..
				int index = 0;
				//This will pad the mode string..
				while( index < m_sChannelModeSettingsTypeD.GetLength() )
				{
					if( update->modesD.Find(m_sChannelModeSettingsTypeD[index]) == -1 )
						update->modesD.Insert(index, _T(" "));
					index++;
				}
				//Insert the new mode
				update->modesD.Insert(modeLevel, mode[1]);
				//Remove pads
				update->modesD.Remove(_T(' '));
			}
		}
		return true;
	}
	return false;
}

void CIrcChannelTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
	if (m_bCloseable)
	{
		int iTabs = GetItemCount();
		for (int i = 0; i < iTabs; i++)
		{

⌨️ 快捷键说明

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