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

📄 hypertextctrl.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/********************************************************************
		HyperTextCtrl.h - Controls that shows hyperlinks 
		in text

		Copyright (C) 2001-2002 Magomed G. Abdurakhmanov			
********************************************************************/

//edited by (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//-> converted it to MFC
//-> included colored keywords
//-> fixed GPF bugs
//-> made it flickerfree
//-> some other small changes
// (the whole code still needs some work though)
//
//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 "emuledlg.h"
#include "hypertextctrl.h"
#include <deque>

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


// CHyperLink
CHyperLink::CHyperLink(int iBegin, uint16 iEnd, const CString& sTitle, const CString& sCommand, const CString& sDirectory){
	m_Type = lt_Shell;
	m_iBegin = iBegin;
	m_iEnd = iEnd;
	m_sTitle = sTitle;
	m_sCommand = sCommand;
	m_sDirectory = sDirectory;
   // [i_a] used for lt_Message  
    m_hWnd = 0; 
    m_uMsg = 0; 
    m_wParam = 0; 
    m_lParam = 0; 
} // [/i_a] 

CHyperLink::CHyperLink(int iBegin, uint16 iEnd, const CString& sTitle, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
	m_Type = lt_Message;
	m_iBegin = iBegin;
	m_iEnd = iEnd;
	m_sTitle = sTitle;
	m_hWnd = hWnd;
	m_uMsg = uMsg;
	m_wParam = wParam;
	m_lParam = lParam;
}
 CHyperLink::CHyperLink(){  // [i_a] 
   m_Type = lt_Unknown; 
   m_iBegin = 0; 
   m_iEnd = 0; 
   m_sTitle.Empty(); 
   m_sCommand.Empty(); 
   m_sDirectory.Empty(); 
   m_hWnd = 0; 
   m_uMsg = 0; 
   m_wParam = 0; 
   m_lParam = 0; 
 } // [/i_a] 
CHyperLink::CHyperLink(const CHyperLink& Src){
	m_Type = Src.m_Type;
	m_iBegin = Src.m_iBegin;
	m_iEnd = Src.m_iEnd;
	m_sTitle = Src.m_sTitle;
	m_sCommand = Src.m_sCommand;
	m_sDirectory = Src.m_sDirectory;
	m_hWnd = Src.m_hWnd;
	m_uMsg = Src.m_uMsg;
	m_wParam = Src.m_wParam;
	m_lParam = Src.m_lParam;
}

void CHyperLink::Execute(){
	switch(m_Type)
	{
	case lt_Shell:
		ShellExecute(NULL, NULL, m_sCommand, NULL, m_sDirectory, SW_SHOWDEFAULT);
		break;

	case lt_Message:
		PostMessage(m_hWnd, m_uMsg, m_wParam, m_lParam);
		break;
	}
}

// CKeyWord
CKeyWord::CKeyWord(int iBegin, uint16 iEnd, COLORREF icolor){
	color = icolor;
	m_iBegin = iBegin;
	m_iEnd = iEnd;
}

// CPreparedHyperText
void CPreparedHyperText::PrepareText(const CString& sText)
{
	m_sText = sText;
	m_Links.clear();

	enum {
		unknown,
		space,
		http0,		/* http://		*/
		http1, http2, http3, http4, http5, http6,
		ftp0,		/* ftp://		*/
		ftp1, ftp2, ftp3, ftp4, ftp5,
		ftp,		/* ftp.			*/
		www0,		/* www.			*/
		www1, www2, www3,
		mailto0, 	/* mailto:		*/
		mailto1, mailto2, mailto3, mailto4, mailto5, mailto6,
		mail,		/* xxx@yyy		*/
		ed2k0,		/* ed2k://		*/
		ed2k1, ed2k2, ed2k3, ed2k4, ed2k5, ed2k6
	} state = space;

	int WordPos = 0;
	TCHAR sz[2];
	TCHAR& c = sz[0];
	sz[1] = 0;
	int last = m_sText.GetLength() -1;
	for(int i = 0; i <= last; i++)
	{
		c = m_sText[i];
		_tcslwr(sz);

		switch(state)
		{
		case unknown:
			if(tspace(c))
				state = space;
			else
				if(c == _T('@') && WordPos != i)
					state = mail;		
			break;

		case space:
			WordPos = i;
			switch(c)
			{
			case _T('h'): state = http0; break;
			case _T('f'): state = ftp0; break;
			case _T('w'): state = www0; break;
			case _T('m'): state = mailto0; break;
			case _T('e'): state = ed2k0; break;
			default:
				if(!tspace(c))
					state = unknown;
			}
			break;

			/*----------------- http -----------------*/
		case http0:
			if(c == _T('t'))
				state = http1;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http1:
			if(c == _T('t'))
				state = http2;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http2:
			if(c == _T('p'))
				state = http3;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http3:
			if(c == _T(':'))
				state = http4;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http4:
			if(c == _T('/'))
				state = http5;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http5:
			if(c == _T('/'))
				state = http6;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case http6:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;

			/*----------------- ed2k -----------------*/
		case ed2k0:
			if(c == _T('d'))
				state = ed2k1;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k1:
			if(c == _T('2'))
				state = ed2k2;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k2:
			if(c == _T('k'))
				state = ed2k3;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k3:
			if(c == _T(':'))
				state = ed2k4;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k4:
			if(c == _T('/'))
				state = ed2k5;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k5:
			if(c == _T('/'))
				state = ed2k6;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ed2k6:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;
			/*----------------- ftp -----------------*/
		case ftp0:
			if(c == _T('t'))
				state = ftp1;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ftp1:
			if(c == _T('p'))
				state = ftp2;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ftp2:
			if(c == _T(':'))
				state = ftp3;
			else
				if(c == _T('.'))
					state = ftp;
				else
					if(tspace(c))
						state = space;
					else
						state = unknown;
			break;

		case ftp3:
			if(c == _T('/'))
				state = ftp4;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ftp4:
			if(c == _T('/'))
				state = ftp5;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case ftp:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = CString(_T("ftp://")) + m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;

		case ftp5:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;

			/*----------------- www -----------------*/
		case www0:
			if(c == _T('w'))
				state = www1;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case www1:
			if(c == _T('w'))
				state = www2;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case www2:
			if(c == _T('.'))
				state = www3;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case www3:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = CString(_T("http://")) + m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;

			/*----------------- mailto -----------------*/
		case mailto0:
			if(c == _T('a'))
				state = mailto1;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto1:
			if(c == _T('i'))
				state = mailto2;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto2:
			if(c == _T('l'))
				state = mailto3;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto3:
			if(c == _T('t'))
				state = mailto4;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto4:
			if(c == _T('o'))
				state = mailto5;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto5:
			if(c == _T(':'))
				state = mailto6;
			else
				if(tspace(c))
					state = space;
				else
					state = unknown;
			break;

		case mailto6:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;

			/*----------------- mailto -----------------*/
		case mail:
			if(tspace(c) || i == last)
			{
				int len = i == last ? i - WordPos + 1 : i - WordPos;
				CString s = CString(_T("mailto:")) + m_sText.Mid(WordPos, len);
				RemoveLastSign(s);
				m_Links.push_back(CHyperLink(WordPos, WordPos + len - 1, s, s, (LPCTSTR)NULL));
				state = space;
			}
			break;
		}
	}

	m_Links.sort();
}

 void CPreparedHyperText::RemoveLastSign(CString& sLink)
{
	int len = sLink.GetLength();
	if(len > 0)
	{
		TCHAR c = sLink[len-1];
		switch(c)
		{
		case _T('.'):
		case _T(','):
		case _T(';'):
		case _T('\"'):
		case _T('\''):
		case _T('('):
		case _T(')'):
		case _T('['):
		case _T(']'):
		case _T('{'):
		case _T('}'):
			sLink.Delete(len -1, 1);
			break;
		}
	}
}

CPreparedHyperText::CPreparedHyperText(const CString& sText){
	PrepareText(sText);
}

CPreparedHyperText::CPreparedHyperText(const CPreparedHyperText& src){
	m_sText = src.m_sText;
	m_Links.assign(src.m_Links.begin(), src.m_Links.end());
}

void CPreparedHyperText::Clear(){
	m_sText.Empty();
	m_Links.erase(m_Links.begin(), m_Links.end());
}

void CPreparedHyperText::SetText(const CString& sText){
	Clear();
	PrepareText(sText);
}

void CPreparedHyperText::AppendText(const CString& sText){
	int len = m_sText.GetLength();
	////////////////////////////////////////////////
	//Top:The Original code didn't check to see if the buffer was full..
	////////////////////////////////////////////////
	bool flag = true;
	if( len > 60000 ){
		m_sText = m_sText.Right(50000);
		int shift = len - m_sText.GetLength();
		while( flag == true ){
			CHyperLink &test = m_Links.front();
			if( !m_Links.empty() ){
				if( test.Begin() < shift )
					m_Links.pop_front();
				else
					flag = false;
			}
			else
				flag = false;
		}
		flag = true;
		while( flag == true ){
			CKeyWord &test = m_KeyWords.front();
			if( !m_KeyWords.empty() ){
				if( test.Begin() < shift )
					m_KeyWords.pop_front();

⌨️ 快捷键说明

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