📄 ircwnd.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.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"
#include "InputBox.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);
//MORPH START -Added by SiRoB, Splitting Bar [O瞉
CRect rc,rcSpl;
CWnd* pWnd = GetDlgItem(IDC_NICKLIST);
pWnd->GetWindowRect(rcSpl);
ScreenToClient(rcSpl);
GetWindowRect(rc);
ScreenToClient(rc);
rcSpl.bottom=rc.bottom-10; rcSpl.left=rcSpl.right +3; rcSpl.right=rcSpl.left+4;
m_wndSplitterIRC.Create(WS_CHILD | WS_VISIBLE, rcSpl, this, IDC_SPLITTER_IRC);
//MORPH END - Added by SiRoB, Splitting Bar [O瞉
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);
//MORPH START - Added by SiRoB, Splitting Bar [O瞉
AddAnchor(m_wndSplitterIRC,TOP_LEFT, BOTTOM_LEFT);
int PosStatinit = rcSpl.left;
int PosStatnew = thePrefs.GetSplitterbarPositionIRC();
int max = 700;
int min = 200;
if (thePrefs.GetSplitterbarPositionIRC() > 700) PosStatnew = 700;
else if (thePrefs.GetSplitterbarPositionIRC() < 200) PosStatnew = 200;
rcSpl.left = PosStatnew;
rcSpl.right = PosStatnew+5;
m_wndSplitterIRC.MoveWindow(rcSpl);
DoResize(PosStatnew-PosStatinit);
//MORPH END - Added by SiRoB, Splitting Bar [O瞉
m_serverChannelList.Init();
m_nicklist.Init();
m_channelselect.Init();
OnChatTextChange();
return true;
}
//MORPH START - Added by SiRoB, Splitting Bar [O瞉
void CIrcWnd::DoResize(int delta)
{
CSplitterControl::ChangeWidth(GetDlgItem(IDC_NICKLIST), delta);
CSplitterControl::ChangeWidth(GetDlgItem(IDC_INPUTWINDOW), -delta, CW_RIGHTALIGN);
CSplitterControl::ChangeWidth(GetDlgItem(IDC_TITLEWINDOW), -delta, CW_RIGHTALIGN);
CSplitterControl::ChangeWidth(GetDlgItem(IDC_SERVERCHANNELLIST), -delta, CW_RIGHTALIGN);
CSplitterControl::ChangeWidth(GetDlgItem(IDC_STATUSWINDOW), -delta, CW_RIGHTALIGN);
CSplitterControl::ChangeWidth(GetDlgItem(IDC_TAB2), -delta, CW_RIGHTALIGN);
CRect rcChannel;
m_serverChannelList.GetWindowRect(&rcChannel);
ScreenToClient(&rcChannel);
if (m_channelselect.m_pCurrentChannel) m_channelselect.m_pCurrentChannel->log.SetWindowPos(NULL, rcChannel.left, rcChannel.top, rcChannel.Width(), rcChannel.Height(), SWP_NOZORDER);
CRect rcW;
GetWindowRect(rcW);
ScreenToClient(rcW);
CRect rcspl;
GetDlgItem(IDC_NICKLIST)->GetClientRect(rcspl);
thePrefs.SetSplitterbarPositionIRC(rcspl.right);
RemoveAnchor(IDC_BN_IRCCONNECT);
AddAnchor(IDC_BN_IRCCONNECT,BOTTOM_LEFT);
RemoveAnchor(IDC_CLOSECHAT);
AddAnchor(IDC_CLOSECHAT,BOTTOM_LEFT);
RemoveAnchor(IDC_INPUTWINDOW);
AddAnchor(IDC_INPUTWINDOW,BOTTOM_LEFT,BOTTOM_RIGHT);
RemoveAnchor(IDC_NICKLIST);
AddAnchor(IDC_NICKLIST,TOP_LEFT,BOTTOM_LEFT);
RemoveAnchor(IDC_TITLEWINDOW);
AddAnchor(IDC_TITLEWINDOW,TOP_LEFT,TOP_RIGHT);
RemoveAnchor(IDC_SERVERCHANNELLIST);
AddAnchor(IDC_SERVERCHANNELLIST,TOP_LEFT,BOTTOM_RIGHT);
RemoveAnchor(IDC_TAB2);
AddAnchor(IDC_TAB2,TOP_LEFT, TOP_RIGHT);
RemoveAnchor(m_wndSplitterIRC);
AddAnchor(m_wndSplitterIRC,TOP_LEFT, BOTTOM_LEFT);
m_wndSplitterIRC.SetRange(rcW.left+190, rcW.left+700);
//initCSize(thePrefs.GetSplitterbarPositionIRC());
m_nicklist.SetColumnWidth(0,rcspl.Width()-75);
m_nicklist.SetColumnWidth(1,70);
Invalidate();
UpdateWindow();
}
LRESULT CIrcWnd::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_PAINT:
if (m_wndSplitterIRC) {
CRect rctree,rcSpl,rcW;
CWnd* pWnd;
GetWindowRect(rcW);
ScreenToClient(rcW);
pWnd = GetDlgItem(IDC_NICKLIST);
pWnd->GetWindowRect(rctree);
ScreenToClient(rctree);
if (rcW.Width()>0) {
rcSpl.left=rctree.right;
rcSpl.right=rcSpl.left+5;
rcSpl.top=rctree.top;
rcSpl.bottom=rcW.bottom-40;
m_wndSplitterIRC.MoveWindow(rcSpl,true);
m_nicklist.SetColumnWidth(0,rctree.Width()-75);
m_nicklist.SetColumnWidth(1,70);
}
}
break;
case WM_NOTIFY:
if (wParam == IDC_SPLITTER_IRC)
{
SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
DoResize(pHdr->delta);
}
break;
case WM_WINDOWPOSCHANGED :
{
CRect rcW;
GetWindowRect(rcW);
ScreenToClient(rcW);
if (m_wndSplitterIRC && rcW.Width()>0) Invalidate();
break;
}
case WM_SIZE:
{
//set range
if (m_wndSplitterIRC)
{
CRect rc;
GetWindowRect(rc);
ScreenToClient(rc);
m_wndSplitterIRC.SetRange(rc.left+190 , rc.left+700);
}
break;
}
}
return CResizableDialog::DefWindowProc(message, wParam, lParam);
}
//MORPH END - Added by SiRoB, Splitting Bar [O瞉
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( thePrefs.GetIRCNick().MakeLower() == _T("emule") || thePrefs.GetIRCNick().MakeLower().Find(_T("emuleirc")) != -1 )
{
InputBox inputbox;
inputbox.SetLabels(GetResString(IDS_IRC_NEWNICK), GetResString(IDS_IRC_NEWNICKDESC), _T("eMule"));
if (inputbox.DoModal() == IDOK)
{
CString input = inputbox.GetInput();
input.Trim();
input = input.SpanExcluding(_T(" !@#$%^&*():;<>,.?{}~`+=-"));
if( input != "" )
thePrefs.SetIRCNick(input.GetBuffer());
}
}
//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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -