www.pudn.com > messagerfairyfhfhfhgf.zip > RichEditCtrlEx.cpp


// richeditctrlex.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "richeditctrlex.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
/////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////// 
//菜单 ID 
#define ID_RICH_UNDO			(WM_USER + 101) 
#define ID_RICH_CUT             (WM_USER + 102) 
#define ID_RICH_COPY            (WM_USER + 103) 
#define ID_RICH_PASTE           (WM_USER + 104) 
#define ID_RICH_CLEAR           (WM_USER + 105) 
#define ID_RICH_SELECTALL       (WM_USER + 106) 
#define ID_RICH_SETFONT         (WM_USER + 107) 
 
//设置鼠标形状触发器 ID 
#define SETCURSOR_TIMER			(WM_USER + 201) 
///////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////// 
// CRichEditCtrlEx 
 
CRichEditCtrlEx::CRichEditCtrlEx() 
{ 
} 
 
CRichEditCtrlEx::~CRichEditCtrlEx() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CRichEditCtrlEx, CRichEditCtrl) 
	//{{AFX_MSG_MAP(CRichEditCtrlEx) 
	ON_WM_KILLFOCUS() 
	ON_WM_CREATE() 
	ON_WM_RBUTTONDOWN() 
	ON_WM_RBUTTONUP() 
	ON_COMMAND(ID_RICH_COPY, OnCopy) 
	ON_COMMAND(ID_RICH_CUT, OnCut) 
	ON_COMMAND(ID_RICH_PASTE, OnPaste) 
	ON_COMMAND(ID_RICH_SELECTALL, OnSelectAll) 
	ON_COMMAND(ID_RICH_UNDO, OnUndo) 
	ON_COMMAND(ID_RICH_CLEAR, OnClear) 
	ON_COMMAND(ID_RICH_SETFONT, OnSelectFont) 
	ON_WM_TIMER() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CRichEditCtrlEx message handlers 
int CRichEditCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here	 
	SetScrollRange(SB_VERT, 0, MAX_LINECOUNT); 
	 
	return 0; 
} 
 
void CRichEditCtrlEx::OnKillFocus(CWnd* pNewWnd)  
{ 
	CRichEditCtrl::OnKillFocus(pNewWnd); 
	 
	if( (NULL != m_hWnd) && (::IsWindow(m_hWnd)) ) 
	{ 
		UnSelect(); 
	} 
} 
 
void CRichEditCtrlEx::OnCopyEx() 
{ 
	long lTextLen = GetTextLength(); 
	UINT nSelText = ( (lTextLen > 0) && (GetSelectionType() != SEL_EMPTY) ); 
	if(nSelText) 
	{ 
		Copy(); 
	} 
} 
 
void CRichEditCtrlEx::OnCopy()  
{ 
	Copy(); 
} 
 
void CRichEditCtrlEx::OnCut() 
{ 
	Cut(); 
} 
 
void CRichEditCtrlEx::OnPaste() 
{ 
	Paste(); 
} 
 
void CRichEditCtrlEx::OnSelectAll() 
{ 
	SetSel(0, -1);  
} 
 
void CRichEditCtrlEx::OnUndo() 
{ 
	Undo();  
} 
 
void CRichEditCtrlEx::OnClear() 
{	 
	HideSelection(TRUE, FALSE); 
	SetReadOnly(FALSE); 
 
	try  
	{		 
		OnSelectAll(); 
		Clear(); 
		 
		UnSelect(); 
	} 
	catch(...) {} 
 
	SetReadOnly(); 
	HideSelection(FALSE, FALSE); 
} 
 
void CRichEditCtrlEx::OnSelectFont()  
{ 
	// TODO: Add your command handler code here 
	CHARFORMAT cf; 
	LOGFONT lf; 
	memset(&cf, 0, sizeof(CHARFORMAT)); 
	memset(&lf, 0, sizeof(LOGFONT)); 
 
	//判断是否选择了内容 
	BOOL bSelect = (GetSelectionType() != SEL_EMPTY) ? TRUE : FALSE; 
	if (bSelect) 
	{ 
		GetSelectionCharFormat(cf); 
	} 
	else 
	{ 
		GetDefaultCharFormat(cf); 
	} 
 
	//得到相关字体属性 
	BOOL bIsBold = cf.dwEffects & CFE_BOLD; 
	BOOL bIsItalic = cf.dwEffects & CFE_ITALIC; 
	BOOL bIsUnderline = cf.dwEffects & CFE_UNDERLINE; 
	BOOL bIsStrickout = cf.dwEffects & CFE_STRIKEOUT; 
 
	//设置属性 
	lf.lfCharSet = cf.bCharSet; 
	lf.lfHeight = cf.yHeight/15; 
	lf.lfPitchAndFamily = cf.bPitchAndFamily; 
	lf.lfItalic = bIsItalic; 
	lf.lfWeight = (bIsBold ? FW_BOLD : FW_NORMAL); 
	lf.lfUnderline = bIsUnderline; 
	lf.lfStrikeOut = bIsStrickout; 
	sprintf(lf.lfFaceName, cf.szFaceName); 
	 
	CFontDialog dlg(&lf); 
	dlg.m_cf.rgbColors = cf.crTextColor; 
	if (dlg.DoModal() == IDOK) 
	{ 
		dlg.GetCharFormat(cf);			//获得所选字体的属性 
		if (bSelect) 
		{ 
			SetSelectionCharFormat(cf);	//为选定的内容设定所选字体 
		} 
		else 
		{ 
			SetWordCharFormat(cf);		//为将要输入的内容设定字体 
		} 
	} 
} 
 
void CRichEditCtrlEx::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	//设置为焦点 
	SetFocus(); 
 
	CRichEditCtrl::OnRButtonDown(nFlags, point); 
} 
 
void CRichEditCtrlEx::OnRButtonUp(UINT nFlags, CPoint point)  
{ 
	//设置为焦点 
	SetFocus(); 
 
	//创建一个弹出式菜单 
	CMenu tPopmenu; 
	tPopmenu.CreatePopupMenu(); 
 
	//添加菜单项目 
	//tPopmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo"); 
	//tPopmenu.AppendMenu(0, MF_SEPARATOR); 
	//tPopmenu.AppendMenu(0, ID_RICH_CUT, "&Cut"); 
	tPopmenu.AppendMenu(0, ID_RICH_COPY, "复制 (&C)"); 
	//tPopmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste"); 
	tPopmenu.AppendMenu(0, MF_SEPARATOR); 
	tPopmenu.AppendMenu(0, ID_RICH_CLEAR, "清除 (&R)"); 
	tPopmenu.AppendMenu(0, MF_SEPARATOR); 
	tPopmenu.AppendMenu(0, ID_RICH_SELECTALL, "全选 (&A)"); 
	//tPopmenu.AppendMenu(0, MF_SEPARATOR); 
	//tPopmenu.AppendMenu(0, ID_RICH_SETFONT, "Select &Font"); 
 
	//初始化菜单项 
	long lTextLen = GetTextLength(); 
 
	//UINT nUndo=(CanUndo() ? 0 : MF_GRAYED ); 
	//tPopmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo); 
	//UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ; 
	//tPopmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);	 
 
	UINT nSelText = ( (lTextLen > 0) && (GetSelectionType() != SEL_EMPTY) ) ? MF_ENABLED : MF_GRAYED; 
	//tPopmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSelText); 
	tPopmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSelText); 
 
	UINT nClear = (lTextLen > 0) ? MF_ENABLED : MF_GRAYED; 
	tPopmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nClear); 
 
	long lStartChar = 0; 
	long lEndChar = 0; 
	GetSel(lStartChar, lEndChar); 
	long lSelTextLen = lEndChar - lStartChar; 
	UINT nSelAll = ( (lTextLen > 0) && (lSelTextLen < lTextLen) ) ? MF_ENABLED : MF_GRAYED; 
	tPopmenu.EnableMenuItem(ID_RICH_SELECTALL, MF_BYCOMMAND|nSelAll); 
 
	//把鼠标形状设置为标准箭头 
	SetTimer(SETCURSOR_TIMER, 0, NULL); 
 
	//显示菜单 
	CPoint pt; 
	GetCursorPos(&pt);	 
	tPopmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this); 
	tPopmenu.DestroyMenu(); 
 
	CRichEditCtrl::OnRButtonUp(nFlags, point); 
} 
 
void CRichEditCtrlEx::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if( SETCURSOR_TIMER == nIDEvent ) 
	{ 
		KillTimer(nIDEvent); 
 
		SetFocus(); 
		SetCursor(::LoadCursor(NULL, IDC_ARROW)); 
	} 
	 
	CRichEditCtrl::OnTimer(nIDEvent); 
} 
 
/////////////////////////////////////////////////////////////////////// 
BOOL CRichEditCtrlEx::AppendText(LPCTSTR lpszText, COLORREF clrText,  
								 BOOL bAddDateTime /*= TRUE*/) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
 
	if( (NULL == lpszText) || (0 == strlen(lpszText)) ) return FALSE; 
	 
	if( (NULL != m_hWnd) && (::IsWindow(m_hWnd)) ) 
	{ 
		CHARFORMAT   tCharFormat; 
		memset(&tCharFormat,0,sizeof(CHARFORMAT)); 
		 
		tCharFormat.cbSize=sizeof(CHARFORMAT); 
		tCharFormat.dwMask=CFM_COLOR; 
		tCharFormat.crTextColor=clrText; 
		//SetWordCharFormat(tCharFormat); 
 
		CString strDateTime(""); 
 
		if( bAddDateTime ) 
		{ 
			SYSTEMTIME tSysTime; 
			GetLocalTime(&tSysTime);		 
			strDateTime.Format("==> %04ld-%02ld-%02ld   %02ld:%02ld:%02ld.%03ld -- ",  
				tSysTime.wYear, tSysTime.wMonth, tSysTime.wDay, 
				tSysTime.wHour, tSysTime.wMinute, tSysTime.wSecond,  
				tSysTime.wMilliseconds); 
		} 
 
		CString strText = (CString)lpszText; 
		if( strText.FindOneOf("\r\n") == -1 ) 
		{ 
			strText += (CString)"\n"; 
		} 
 
		CString strLogInfo = strDateTime + strText; 
		CString strTextOut = strLogInfo; 
		 
		//首先记住当前选择的位置, 
		//如果光标处于末尾且没有选择文字,就让光标一直处于末尾 
		//如果已经选择了文字,选择的范围不变 
		long lStartChar = 0; 
		long lEndChar = 0; 
		GetSel(lStartChar, lEndChar); 
		long lTextLen = GetTextLength();		 
		if( lEndChar > lTextLen )  
		{ 
			UnSelect(); 
			lEndChar = lTextLen;			 
		} 
		BOOL bAtTheEndOf = (lEndChar == lTextLen); 
 
		UnSelect(); 
		SetWordCharFormat(tCharFormat); 
		ReplaceSel(strTextOut, FALSE); 
		 
		if( bAtTheEndOf ) 
		{ 
			lTextLen = GetTextLength();			 
			lStartChar = lTextLen; 
			lEndChar = lStartChar;			 
		} 
		 
		SetSel(lStartChar, lEndChar); 
		//// 
	 
		if( bAtTheEndOf ) 
		{ 
			LineScroll(3); 
		} 
		else 
		{ 
			LineScroll(0); 
		} 
 
		int nLineCount = GetLineCount(); 
		if( nLineCount > MAX_LINECOUNT-1 ) 
		{ 
			OnClear(); 
		} 
	} 
 
	return TRUE; 
} 
 
void CRichEditCtrlEx::UnSelect() 
{ 
	SetSel(-1,-1); 
}