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

📄 ircwnd.cpp

📁 另外一款开放源码的高质量p2p源码软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "IrcWnd.h"
#include "IrcMain.h"
#include "emuledlg.h"
#include "otherfunctions.h"
#include "MenuCmds.h"
#include "HTRichEditCtrl.h"
#include "ClosableTabCtrl.h"
#include "HelpIDs.h"
#include "Opcodes.h"

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

#define NICK_LV_PROFILE_NAME _T("IRCNicksLv")
#define CHAN_LV_PROFILE_NAME _T("IRCChannelsLv")

struct Nick
{
	CString nick;
	CString modes;
	int level;
};

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(CIrcWnd, CDialog)

BEGIN_MESSAGE_MAP(CIrcWnd, CDialog)
	// Tab control
	ON_WM_SIZE()
	ON_WM_CREATE()
    ON_WM_CONTEXTMENU()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_HELPINFO()
END_MESSAGE_MAP()

CIrcWnd::CIrcWnd(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CIrcWnd::IDD, pParent)
{
	m_pIrcMain = NULL;
	m_bConnected = false;
	m_bLoggedIn = false;
	m_nicklist.m_pParent = this;
	m_serverChannelList.m_pParent = this;
	m_channelselect.m_bCloseable = true;
	m_channelselect.m_pParent = this;
}

CIrcWnd::~CIrcWnd()
{
	if( m_bConnected )
	{
		//Do a safe disconnect
		m_pIrcMain->Disconnect(true);
	}
	//Delete our core client..
	delete m_pIrcMain;
}

void CIrcWnd::OnSysColorChange()
{ 
	CResizableDialog::OnSysColorChange();
}

void CIrcWnd::Localize()
{
	//Set all controls to the correct language.
	if( m_bConnected )
		GetDlgItem(IDC_BN_IRCCONNECT)->SetWindowText(GetResString(IDS_IRC_DISCONNECT));
	else
		GetDlgItem(IDC_BN_IRCCONNECT)->SetWindowText(GetResString(IDS_IRC_CONNECT));
	GetDlgItem(IDC_CHATSEND)->SetWindowText(GetResString(IDS_IRC_SEND));
	GetDlgItem(IDC_CLOSECHAT)->SetWindowText(GetResString(IDS_FD_CLOSE));
	m_serverChannelList.Localize();
	m_channelselect.Localize();
	m_nicklist.Localize();
}

BOOL CIrcWnd::OnInitDialog()
{
	CResizableDialog::OnInitDialog();
#ifdef _DEBUG
	CString strBuff;
	m_nicklist.GetWindowText(strBuff);
	ASSERT( strBuff == NICK_LV_PROFILE_NAME );

	strBuff.Empty();
	m_serverChannelList.GetWindowText(strBuff);
	ASSERT( strBuff == CHAN_LV_PROFILE_NAME );
#endif

	m_bConnected = false;
	m_bLoggedIn = false;
	Localize();
	m_pIrcMain = new CIrcMain();
	m_pIrcMain->SetIRCWnd(this);

	UpdateFonts(&theApp.emuledlg->m_fontHyperText);
	InitWindowStyles(this);

	((CEdit*)GetDlgItem(IDC_INPUTWINDOW))->SetLimitText(MAX_IRC_MSG_LEN);

	AddAnchor(IDC_BN_IRCCONNECT,BOTTOM_LEFT);
	AddAnchor(IDC_CLOSECHAT,BOTTOM_LEFT);
	AddAnchor(IDC_CHATSEND,BOTTOM_RIGHT);
	AddAnchor(IDC_INPUTWINDOW,BOTTOM_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_NICKLIST,TOP_LEFT,BOTTOM_LEFT);
	AddAnchor(IDC_TITLEWINDOW,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_SERVERCHANNELLIST,TOP_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_TAB2,TOP_LEFT, TOP_RIGHT);

	m_serverChannelList.Init();
	m_nicklist.Init();
	m_channelselect.Init();
	OnChatTextChange();

	return true;
}

void CIrcWnd::UpdateFonts(CFont* pFont)
{
	TCITEM tci;
	tci.mask = TCIF_PARAM;
	int i = 0;
	while (m_channelselect.GetItem(i++, &tci))
	{
		Channel* ch = (Channel*)tci.lParam;
		if (ch->log.m_hWnd != NULL)
			ch->log.SetFont(pFont);
	}
}

void CIrcWnd::OnSize(UINT nType, int cx, int cy) 
{
	CResizableDialog::OnSize(nType, cx, cy);

	if (m_channelselect.m_pCurrentChannel && m_channelselect.m_pCurrentChannel->log.m_hWnd)
	{
		CRect rcChannel;
		m_serverChannelList.GetWindowRect(&rcChannel);
		ScreenToClient(&rcChannel);
		m_channelselect.m_pCurrentChannel->log.SetWindowPos(NULL, rcChannel.left, rcChannel.top, rcChannel.Width(), rcChannel.Height(), SWP_NOZORDER);
	}
}

int CIrcWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	return CResizableDialog::OnCreate(lpCreateStruct);
}

void CIrcWnd::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_NICKLIST, m_nicklist);
	DDX_Control(pDX, IDC_INPUTWINDOW, inputWindow);
	DDX_Control(pDX, IDC_TITLEWINDOW, titleWindow);
	DDX_Control(pDX, IDC_SERVERCHANNELLIST, m_serverChannelList);
	DDX_Control(pDX, IDC_TAB2, m_channelselect);
}

BOOL CIrcWnd::OnCommand(WPARAM wParam,LPARAM lParam )
{
	int chanItem= m_channelselect.GetCurSel(); 
	switch( wParam )
	{
		case IDC_BN_IRCCONNECT: 
		{
			//Pressed the connect button..
			OnBnClickedBnIrcconnect();
			return true;
		}
		case IDC_CHATSEND: 
		{
			//Pressed the send button..
			OnBnClickedChatsend();
			return true;
		}
		case IDC_CLOSECHAT:
		{
			//Pressed the close button
			OnBnClickedClosechat();
			return true;
		}
   }
   return true;
}

BOOL CIrcWnd::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN && (pMsg->hwnd == GetDlgItem(IDC_INPUTWINDOW)->m_hWnd)) {
		if (pMsg->wParam == VK_RETURN) 
		{
			//If we press the enter key, treat is as if we pressed the send button.
			OnBnClickedChatsend();
			return TRUE;
		}

		if (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN) 
		{
			//If we press page up/down scroll..
			m_channelselect.ScrollHistory(pMsg->wParam == VK_DOWN);
			return TRUE;
		}

		if (pMsg->wParam == VK_TAB )
		{
			AutoComplete();
			return true;
		}
	}
	OnChatTextChange();
	return CResizableDialog::PreTranslateMessage(pMsg);
}

void CIrcWnd::AutoComplete()
{
	CString send;
	CString name;
	GetDlgItem(IDC_INPUTWINDOW)->GetWindowText(send);
	if( send.ReverseFind(_T(' ')) == -1 )
	{
		if(!send.GetLength())
			return;
		name = send;
		send = _T("");
	}
	else
	{
		name = send.Mid(send.ReverseFind(_T(' '))+1);
		send = send.Mid(0, send.ReverseFind(_T(' '))+1);
	}

	POSITION pos1, pos2;
	for (pos1 = m_channelselect.m_pCurrentChannel->nicks.GetHeadPosition();( pos2 = pos1 ) != NULL;)
	{
		m_channelselect.m_pCurrentChannel->nicks.GetNext(pos1);
		Nick* cur_nick = (Nick*)(m_channelselect.m_pCurrentChannel)->nicks.GetAt(pos2);
		if (cur_nick->nick.Left(name.GetLength()) == name)
		{
			name = cur_nick->nick;
			GetDlgItem(IDC_INPUTWINDOW)->SetWindowText(send+name);
			GetDlgItem(IDC_INPUTWINDOW)->SetFocus();
			GetDlgItem(IDC_INPUTWINDOW)->SendMessage(WM_KEYDOWN, VK_END);
			break;
		}
	}
}

void CIrcWnd::OnBnClickedBnIrcconnect()
{
	if(!m_bConnected)
	{
		//if not connected, connect..
		m_pIrcMain->Connect();
	}
	else
	{
		//If connected, disconnect..
		m_pIrcMain->Disconnect();
	}
}

void CIrcWnd::OnBnClickedClosechat(int nItem)
{
	//Remove a channel..
	TCITEM item;
	item.mask = TCIF_PARAM;
	if (nItem == -1)
	{
		//If no item was send, get our current channel..
		nItem = m_channelselect.GetCurSel();
	}

	if (nItem == -1)
	{
		//We have no channel, abort.
		return;
	}

	if (!m_channelselect.GetItem(nItem, &item))
	{
		//We had no valid item here.. Something isn't right..
		//TODO: this should never happen, so maybe we should remove this tab?
		return;
	}
	Channel* partChannel = (Channel*)item.lParam;
	if( partChannel->type == 4 &&  m_bConnected)
	{
		//If this was a channel and we were connected, do not just delete the channel!!
		//Send a part command and the server must respond with a successful part which will remove the channel!
		CString part;
		part = _T("PART ") + partChannel->name;
		m_pIrcMain->SendString( part );
		return;
	}
	else if (partChannel->type == 5 || partChannel->type == 4)
	{
		//If this is a private room, we just remove it as the server doesn't track this.
		//If this was a channel, but we are disconnected, remove the channel..
		m_channelselect.RemoveChannel(partChannel->name);
		return;
	}
}

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Messages
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

void CIrcWnd::AddStatus( CString line,...)
{
	//Add entry to status window with arguments..
	va_list argptr;
	va_start(argptr, line);
	CString temp;
	temp.FormatV(line, argptr);
	va_end(argptr);
	CString timestamp;
	if( thePrefs.GetIRCAddTimestamp() )
	{
		//Append time stamp..
		timestamp = CTime::GetCurrentTime().Format(_T("%X: "));
	}
	Channel* update_channel = (Channel*)(m_channelselect.channelPtrList).GetHead();
	if( !update_channel )
	{
		//This should never happen!
		return;
	}
	//We do not support color codes..
	line = StripMessageOfFontCodes( temp );
	line += _T("\r\n");
	//Now that incoming arguments are finished, it's now safe to put back the % chars.
	line.Replace( _T("\004"), _T("%") );
	if (line == _T("\r\n") )
	{
		//This allows for us to add blank lines to the status..
		update_channel->log.AppendText(line);
	}
	else if (line.Mid(0,1) == _T("*"))
	{
		update_channel->log.AppendText(timestamp);
		update_channel->log.AppendKeyWord(line.Left(2),RGB(255,0,0));
		update_channel->log.AppendText(line.Mid(1) );
	}
	else
		update_channel->log.AppendText(timestamp + line);
	if( m_channelselect.m_pCurrentChannel == update_channel )
		return;
	m_channelselect.SetActivity( update_channel->name, true );
}

void CIrcWnd::AddInfoMessage( CString channelName, CString line,...)
{
	if(channelName.IsEmpty())
		return;
	va_list argptr;
	va_start(argptr, line);
	CString temp;
	temp.FormatV(line, argptr);
	va_end(argptr);
	CString timestamp = _T("");
	if( thePrefs.GetIRCAddTimestamp() )

⌨️ 快捷键说明

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