www.pudn.com > RichTextEx.rar > RichEditCtrlEx.cpp
//****************************************************************************** //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) // Copyright ?1999, SOFTIMAGE, Avid Technologies //------------------------------------------------------------------------------ // // @doc RICHEDITCTRLEX // // @module RichEditCtrlEx.cpp | // This file implements the rich edit control extended class //. // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New file. //****************************************************************************** //****************************************************************************** //****************************************************************************** // // Includes // //****************************************************************************** #include "StdAfx.h" #include "RichEditCtrlEx.h" #include ".\richeditctrlex.h" #include "afxctl.h" //****************************************************************************** // // Debugging // //****************************************************************************** #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @mfunc | _AFX_RICHEDITEX_STATE | _AFX_RICHEDITEX_STATE | // Constructor for . // // @syntax _AFX_RICHEDITEX_STATE() ; // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** _AFX_RICHEDITEX_STATE::_AFX_RICHEDITEX_STATE() { m_hInstRichEdit20 = NULL ; } //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @mfunc | _AFX_RICHEDITEX_STATE | ~_AFX_RICHEDITEX_STATE | // Destructor for . // // @syntax ~_AFX_RICHEDITEX_STATE() ; // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** _AFX_RICHEDITEX_STATE::~_AFX_RICHEDITEX_STATE() { if( m_hInstRichEdit20 != NULL ) { ::FreeLibrary( m_hInstRichEdit20 ) ; } } //****************************************************************************** // // Global Data // //****************************************************************************** _AFX_RICHEDITEX_STATE _afxRichEditStateEx ; //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @func BOOL PASCAL | AfxInitRichEditEx | // This function must be called prior to creating any dialog which // uses the version 2.0 rich edit control. For created classes, this // is called automatically. // // @syntax BOOL PASCAL AfxInitRichEditEx() ; // // @rdesc BOOL : A boolean value indicating: // @flag TRUE | Success. // @flag FALSE | Failure. // // @comm NOTE: This function will not work if AfxInitRichEdit() has been // called first and this will clash with the use of the CRichEditCtrl // class (including the CRichEditView class). // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** BOOL PASCAL AfxInitRichEditEx() { if( ! ::AfxInitRichEdit() ) { return FALSE ; } _AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx ; if( l_pState->m_hInstRichEdit20 == NULL ) { l_pState->m_hInstRichEdit20 = LoadLibraryA( "RICHED20.DLL" ) ; } return l_pState->m_hInstRichEdit20 != NULL ; } //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @mfunc | CRichEditCtrlEx | CRichEditCtrlEx | // Constructor for . // // @syntax CRichEditCtrlEx() ; // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** CRichEditCtrlEx::CRichEditCtrlEx() { m_hCursor = NULL; } //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @mfunc | CRichEditCtrlEx | ~CRichEditCtrlEx | // Destructor for . // // @syntax ~CRichEditCtrlEx() ; // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** CRichEditCtrlEx::~CRichEditCtrlEx() { } //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @msgmap CRichEditCtrl | CRichEditCtrlEx | // Message map for . // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** BEGIN_MESSAGE_MAP( CRichEditCtrlEx, CRichEditCtrl ) //{{AFX_MSG_MAP( CRichEditCtrlEx ) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_SETCURSOR() //}}AFX_MSG_MAP ON_NOTIFY_REFLECT(EN_LINK, OnLink) END_MESSAGE_MAP() //****************************************************************************** // Owner: Andrew Forget (AndrewFo,x3438) //------------------------------------------------------------------------------ // // @mfunc BOOL | CRichEditCtrlEx | Create | // This method is used to create the version 2.0 rich edit control. // // @syntax BOOL Create( // DWORD in_dwStyle, // const RECT& in_rcRect, // CWnd* in_pParentWnd, // UINT in_nID ) ; // // @parm DWORD | in_dwStyle | // The styles for the rich edit control. // // @parm const RECT& | in_rcRect | // The rectangle for the control window. // // @parm CWnd* | in_pParentWnd | // Pointer to the parent window. // // @parm UINT | in_nID | // The dialog control ID for the control. // // @rdesc BOOL : A boolean value indicating: // @flag TRUE | Sucess. // @flag FALSE | Failure. // // @version //------------------------------------------------------------------------------ //.Version: Date: Author: Comments: //.-------- ----------- ----------- -------------------------------------------- //. 1.0 01/18/99 AndrewFo New code. //****************************************************************************** BOOL CRichEditCtrlEx::Create( DWORD in_dwStyle, const RECT& in_rcRect, CWnd* in_pParentWnd, UINT in_nID ) { if( ! ::AfxInitRichEditEx() ) { return FALSE ; } CWnd* l_pWnd = this ; return l_pWnd->Create( _T( "RichEdit20A" ), NULL, in_dwStyle, in_rcRect, in_pParentWnd, in_nID ) ; } void CRichEditCtrlEx::OnLink(NMHDR *pNMHDR, LRESULT *result) { ENLINK *link = (ENLINK *) pNMHDR; *result = 0; if (link->msg == WM_LBUTTONDOWN) { CHARRANGE cr; GetSel(cr); SetSel(link->chrg); CString url = GetSelText(); SetSel(cr); ShellExecute(NULL, _T("open"), url, NULL,NULL, SW_SHOW); *result = 1; } } void CRichEditCtrlEx::AppendMsg(TCHAR chMsg[]) { // BOOL b = (GetStyle() & ES_READONLY); // SetReadOnly(FALSE); SetSel(-1, -1); // CHARRANGE cr; // GetSel(cr); CHARFORMAT defFormat; defFormat.cbSize = sizeof(defFormat); defFormat.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_FACE | CFM_SIZE | CFM_COLOR; GetDefaultCharFormat(defFormat); CHARFORMAT cf; cf.cbSize = sizeof(cf); cf = defFormat; cf.crTextColor = RGB(0,0,255); cf.dwEffects = 0; //SetSel(cr.cpMin, -1); SetSelectionCharFormat(cf); /* PARAFORMAT pf; pf.cbSize = sizeof(pf); pf.dwMask = PFM_STARTINDENT; pf.dxStartIndent = 200; SetParaFormat(pf);*/ CString strText; strText.Format("%s", chMsg); ReplaceSel(strText); // SetSel(-1, -1); HideSelection(FALSE, TRUE); SendMessage(EM_SCROLLCARET, 0, 0); SetSelectionCharFormat(defFormat); // ReplaceSel("\r\n\r\n"); // ScrollToBottom(); // ReplaceSel("\r\n"); //ScrollToBottom(); } void CRichEditCtrlEx::InsertMsg(TCHAR chMsg[], COLORREF color) { long start, end; SetSel(-1, -1); GetSel(start, end); CHARFORMAT defFormat; defFormat.cbSize = sizeof(defFormat); defFormat.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_FACE | CFM_SIZE | CFM_COLOR; GetDefaultCharFormat(defFormat); PARAFORMAT pf; pf.cbSize = sizeof(pf); pf.dwMask = PFM_STARTINDENT; pf.dxStartIndent = 0; SetParaFormat(pf); CHARFORMAT cf; cf.cbSize = sizeof(cf); CString strText; strText.Format("%s", chMsg); ReplaceSel(strText); SetSel(start, -1); cf = defFormat; cf.crTextColor = color; cf.dwEffects = 0; cf.dwEffects |= CFM_BOLD; SetSelectionCharFormat(cf); SetSel(-1, -1); ReplaceSel("\r\n"); // GetDefaultCharFormat(cf); // SetSel(-1, -1); // ReplaceSel(start); } void CRichEditCtrlEx::ScrollToBottom(void) { // get the current end of the window CPoint point = GetCharPos(GetTextLength()); CRect rect; GetClientRect(&rect); // scroll the bottom into view while (point.y > rect.bottom) { LineScroll(1); point = GetCharPos(GetTextLength()); } } void CRichEditCtrlEx::Clear(void) { SetWindowText(_T("")); } int CRichEditCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CRichEditCtrl ::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here m_iMaxWidth = 0; m_iLinesHeight = 0; m_bDontUpdateSizeInfo = false; m_iHorzPos = 0; m_iVertPos = 0; /* m_DefaultFont.CreatePointFont(100,_T("Times New Roman")); m_Font = m_DefaultFont;*/ m_LinkColor = RGB(0,0,255); m_HoverColor = RGB(255,0,0); m_BkColor = GetSysColor(COLOR_WINDOW); m_TextColor = GetSysColor(COLOR_WINDOWTEXT); m_LinkCursor = LoadCursor(NULL,IDC_ARROW); m_DefaultCursor = LoadCursor(NULL,IDC_ARROW); m_pActivePart = NULL; m_iWheelDelta = 0; // create a tool tip m_tip.Create((CWnd*)this); /* ASSERT(m_tip.IsWindow()); if(m_tip.IsWindow())*/ m_tip.Activate(TRUE); // UpdateFonts(); return 0; } void CRichEditCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRichEditCtrl ::OnLButtonDown(nFlags, point); CRect rcClient; GetClientRect(rcClient); if(PtInRect(rcClient, point)) { std::list m_Links = m_Text.GetLinks(); std::list ::iterator it; for (it = m_Links.begin(); it != m_Links.end(); it++) { CHyperLink hl = *it; hl.End(); TRACE("CRichEditCtrlEx::OnLButtonDown HyperLink begin pos is:%d, end pos is:%d\n", hl.Begin(), hl.End()); CPoint pt1 = GetCharPos(hl.Begin()); CPoint pt2 = GetCharPos(hl.End()); TRACE("Link Text Begin x:%d\n", pt1.x); TRACE("Link Text End x:%d\n", pt2.x); TRACE("CRichEditCtrlEx::OnLButtonDown Cur Point x:%d\n", point.x); if (pt1.x < point.x && point.x< pt2.x ) { TRACE("Mouse Down Over link text!!!!\n"); hl.Execute(); break; } } } } void CRichEditCtrlEx::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRichEditCtrl ::OnMouseMove(nFlags, point); CRect rcClient; GetClientRect(rcClient); if(PtInRect(rcClient, point)) { /* if(GetCapture() != m_hWnd) SetCapture();*/ std::list m_Links = m_Text.GetLinks(); std::list ::iterator it; for (it = m_Links.begin(); it != m_Links.end(); it++) { CHyperLink hl = *it; hl.End(); TRACE("HyperLink begin pos is:%d, end pos is:%d\n", hl.Begin(), hl.End()); CPoint pt1 = GetCharPos(hl.Begin()); CPoint pt2 = GetCharPos(hl.End()); TRACE("Link Text Begin x:%d,y:%d\n", pt1.x, pt1.y); TRACE("Link Text End x:%d,y:%d\n", pt2.x, pt2.y); TRACE("Cur Point x:%d,y:%d\n", point.x, point.y); if (pt1.x < point.x && point.x< pt2.x) { TRACE("Mouse over link text!\n"); if (m_hCursor == NULL) SetDefaultCursor(); if (m_hCursor != NULL) ::SetCursor(m_hCursor); break; } } /* int n = this->CharCharFromPos(point); TRACE("CRichEditCtrlEx::OnMouseMove:%d", n);*/ } } void CRichEditCtrlEx::RestoreLink() { /* if(m_pActivePart == NULL) return; CClientDC dc(this); // CFontHandle hOldFont = dc.SelectFont(m_LinksFont); dc.SetBkColor(m_BkColor); dc.SetTextColor(m_LinkColor); LPCTSTR s = m_Text.GetText(); CVisPart* p = m_pActivePart; while(p != NULL) { TextOut(dc, p->m_rcBounds.left, p->m_rcBounds.top, s + p->m_iRealBegin, p->m_iRealLen); p = p->m_pNext; } // dc.SelectFont(hOldFont); m_pActivePart = NULL; SetCursor(m_DefaultCursor);*/ } void CRichEditCtrlEx::HighlightLink(CVisPart* Part, const CPoint& MouseCoords) { } void CRichEditCtrlEx::SetDefaultCursor() { if (m_hCursor == NULL) // No cursor handle - load our own { // Get the windows directory CString strWndDir; GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH); strWndDir.ReleaseBuffer(); strWndDir += _T("\\winhlp32.exe"); // This retrieves cursor #106 from winhlp32.exe, which is a hand pointer HMODULE hModule = LoadLibrary(strWndDir); if (hModule != NULL) { HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106)); if (hHandCursor != NULL) m_hCursor = CopyCursor(hHandCursor); } FreeLibrary(hModule); } } BOOL CRichEditCtrlEx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if (m_hCursor == NULL) SetDefaultCursor(); // if (m_hCursor != NULL) // ::SetCursor(m_hCursor); // return TRUE; return CRichEditCtrl ::OnSetCursor(pWnd, nHitTest, message); }