📄 customeditctrl.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a sample for BCGControlBar Library Professional Edition
// Copyright (C) 1998-2007 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions
// of the accompanying license agreement.
//*******************************************************************************
//
// CustomEditCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "NCSimulaSys.h"
#include "CustomEditCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
struct TipString //定义Tip(提示)结构.
{
LPCTSTR lpszTip;
LPCTSTR lpszContent;
};
static TipString g_aTipText[] =
{
{_T("CMyClass"),_T("class CMyClass")},
{_T("ind"),_T("int ind = -1")},
{_T("memset"),_T("void * memset(void *, int, size_t)")},
{_T("m_lf"),_T("LOGFONT CMyClass::m_lf")},
{_T("m_bTrace"),_T("BOOL CMyClass::m_bTrace")},
{_T("OnDestroy"),_T("void CMyClass::OnDestroy ()")},
{_T("DoMain"),_T("int CMyClass::DoMain ()")},
{_T("printf"),_T("int printf (const char *, ...)")},
{_T("GetAppName"),_T("const char* CMyClass::GetAppName()")},
{_T("EnableTrace"),_T("void CMyClass::EnableTrace(BOOL bTrace = TRUE)")},
{_T("bTrace"),_T("BOOL bTrace = TRUE")},
{_T("DO_TRACE"),_T("#define DO_TRACE(bTrace, lpszText) { if (bTrace) { printf(\"%s\\n\",lpszText); } }")},
{_T("main"),_T("int main(int argc, char* argv[])")},
{_T("pMyClass"),_T("CMyClass* pMyClass = new CMyClass(argc, argv)")},
{_T("nRet"),_T("int nRet = pMyClass->DoMain()")}
};
// 该结构定义了类型与标志符号的关系,即该类型用序号为N的符号.
struct StringIndex
{
LPCTSTR lpszName;
int nIndex;
};
static StringIndex g_aStringIndex1[] =
{
{_T("CMyClass"), 3}, //说明CMyClass用第3个图标标志其类型.
{_T("DoMain"), 3},
{_T("EnableTrace"), 3},
{_T("GetAppName"), 3},
{_T("m_argc"), 5},
{_T("m_argv"), 5},
{_T("m_bTrace"), 4},
{_T("m_lf"), 4},
{_T("OnDestroy"), 6},
{ NULL }
};
static StringIndex g_aStringIndex2[] =
{
{_T("lfHeight"), 7},
{_T("lfWidth"), 7},
{_T("lfEscapement"), 7},
{_T("lfOrientation"), 7},
{_T("lfWeight"), 7},
{_T("lfItalic"), 7},
{_T("lfUnderline"), 7},
{_T("lfStrikeOut"), 7},
{_T("lfCharSet"), 7},
{_T("lfOutPrecision"), 7},
{_T("lfClipPrecision"), 7},
{_T("lfQuality"), 7},
{_T("lfPitchAndFamily"), 7},
{_T("lfFaceName"), 7},
{ NULL }
};
// 该结构说明如果输入lpszName将联想起的类型及其符号列表.
struct IntelliStringArray
{
LPCTSTR lpszName;
StringIndex* ptr;
};
static IntelliStringArray g_aIntelliStringArray[] =
{
{_T("this->"), g_aStringIndex1},
{_T("pMyClass->"), g_aStringIndex1},
{_T("CMyClass::"), g_aStringIndex1},
{_T("this->m_lf."), g_aStringIndex2},
{_T("pMyClass->m_lf."), g_aStringIndex2},
{_T("CMyClass::m_lf."), g_aStringIndex1},
{_T ("this->m_lf.lfFaceName->"), NULL},
{_T ("pMyClass->m_lf.lfFaceName->"), NULL},
{_T ("this->m_argv->"), NULL},
{_T ("pMyClass->m_argv->"), NULL},
};
/////////////////////////////////////////////////////////////////////////////
// CCustomEditCtrl
CCustomEditCtrl::CCustomEditCtrl()
{
m_bEnableBreakpoints = FALSE;
m_bCheckColorTags = FALSE;
m_bCopyRTFToClipboard = TRUE;
PrepareIntelliSense();
EnableGradientMarkers (TRUE); //Draws markers with gradient color.
}
CCustomEditCtrl::~CCustomEditCtrl()
{
}
BEGIN_MESSAGE_MAP(CCustomEditCtrl, CBCGPEditCtrl)
//{{AFX_MSG_MAP(CCustomEditCtrl)
ON_WM_CREATE()
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCustomEditCtrl message handlers
int CCustomEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CBCGPEditCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
m_ImageBreak.Load (IDB_BREAK);
m_ImageBreak.SetSingleImage (); //设置断点图片样式.
return 0;
}
void CCustomEditCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (IsEnableBreakpoints() &&
point.x < m_nLeftMarginWidth)
{
ToggleBreakpoint();
}
CBCGPEditCtrl::OnLButtonDblClk(nFlags, point);
}
// 该函数标志符号的颜色.具体实现的是<... ...>的颜色:<和>用蓝色,... ...用红色.
void CCustomEditCtrl::OnGetCharColor (TCHAR ch, int nOffset, COLORREF& clrText, COLORREF& clrBk)
{
if (m_bCheckColorTags)
{
TCHAR chOpen = _T ('<');
TCHAR chClose = _T ('>');
if (ch == chOpen || ch == chClose || ch == _T ('/'))
{
clrText = RGB (0, 0, 255);
}
else
{
COLORREF clrDefaultBack = GetDefaultBackColor ();
COLORREF clrDefaultTxt = GetDefaultTextColor ();
int nBlockStart, nBlockEnd;
if (!IsInBlock (nOffset, chOpen, chClose, nBlockStart, nBlockEnd))
{
clrText = clrDefaultTxt;
clrBk = clrDefaultBack;
}
else if (GetCharAt (nBlockStart + 1) == _T ('%') &&
GetCharAt (nBlockEnd - 1) == _T ('%'))
{
}
else if (clrText == clrDefaultTxt)
{
if (ch == _T ('='))
{
clrText = RGB (0, 0, 255);
}
else
{
clrText = RGB (255, 0, 0);
}
}
}
}
}
// 该函数主要完成"断点"等标志的绘制.
void CCustomEditCtrl::OnDrawMarker (CDC* pDC, CRect rectMarker, const CBCGPEditMarker* pMarker)
{
if (pMarker->m_dwMarkerType & g_dwBreakPointType)
{
if (globalData.m_nBitsPerPixel >= 32)
{
m_ImageBreak.DrawEx (pDC, rectMarker, 0,
CBCGPToolBarImages::ImageAlignHorzCenter,
CBCGPToolBarImages::ImageAlignVertTop);
}
else
{
CBrush br (RGB (127, 0, 0));
CPen pen (PS_SOLID, 1, RGB (127, 0, 0));
CBrush* pBrOld = pDC->SelectObject (&br);
CPen* pOldPen = pDC->SelectObject (&pen);
rectMarker.DeflateRect (1, 1);
int nD = min (rectMarker.Width (), rectMarker.Height());
int nR = nD / 2;
CPoint ptCenter = rectMarker.CenterPoint ();
rectMarker.SetRect( ptCenter.x - nR, ptCenter.y - nR,
ptCenter.x + nR, ptCenter.y + nR);
pDC->Ellipse (rectMarker);
pDC->SelectObject (pBrOld);
pDC->SelectObject (pOldPen);
}
}
else
{
CBCGPEditCtrl::OnDrawMarker (pDC, rectMarker, pMarker);
}
}
//显示Tip(提示).
BOOL CCustomEditCtrl::OnGetTipText (CString& strTipString) //strTipString为程序捕捉的字符串.
{
CPoint point;
::GetCursorPos (&point);
ScreenToClient (&point);
CString strText;
BOOL bIsHyperlink = m_bEnableHyperlinkSupport && GetHyperlinkToolTip (strText);
BOOL bIsHiddenTextFromPoint = !bIsHyperlink && m_bEnableOutlining && GetHiddenTextFromPoint (point, strText);
BOOL bIsWordFromPoint = !bIsHyperlink && !bIsHiddenTextFromPoint && GetWordFromPoint (point, strText);
if ((bIsHiddenTextFromPoint || bIsHyperlink) && strText == strTipString)
{
return TRUE;
}
else if (m_mTipString.Lookup(strTipString,strTipString))
{
return TRUE;
}
else if (IsIntelliSenseEnabled() && !bIsWordFromPoint)
{
return TRUE;
}
return FALSE;
}
BOOL CCustomEditCtrl::EnableBreakpoints(BOOL bFl /* = TRUE */)
{
const BOOL bEnableBreakpoints = m_bEnableBreakpoints;
m_bEnableBreakpoints = bFl;
return bEnableBreakpoints;
}
// 标志断点及断点所在的行.
BOOL CCustomEditCtrl::ToggleBreakpoint(int nCurrRow /* = -1 */)
{
if (nCurrRow == -1)
{
nCurrRow = GetCurRow();
}
BOOL bMarkerSet = ToggleMarker (nCurrRow, g_dwBreakPointType, NULL, FALSE);
if (bMarkerSet)
{
SetLineColorMarker (nCurrRow, RGB (255, 255, 255),
RGB (127, 0, 0), TRUE, 0, g_dwColorBreakPointType);
}
else
{
DeleteMarker (nCurrRow, g_dwColorBreakPointType);
}
return bMarkerSet;
}
// 删除所有断点标志及所在行标志.
void CCustomEditCtrl::RemoveAllBreakpoints()
{
DeleteAllMarkers(g_dwBreakPointType | g_dwColorBreakPointType);
}
/////////////////////////////////////////////////////////////////////////////
// IntelliSense Support
// 初始化检索字符串,以便为后来的查找工作做好准备.
void CCustomEditCtrl::PrepareIntelliSense()
{
int ind = 0;
for (ind = sizeof(g_aIntelliStringArray) / (sizeof(IntelliStringArray));
ind-- != 0;
m_mIntelliString.SetAt(g_aIntelliStringArray[ind].lpszName,g_aIntelliStringArray[ind].ptr));
for (ind = sizeof(g_aTipText) / sizeof(TipString);
ind-- != 0;
m_mTipString.SetAt(g_aTipText[ind].lpszTip,g_aTipText[ind].lpszContent));
}
// 利用检索字符串进行查找,如果存在于检索字符串则返回TRUE,如果没有检索到则返回FALSE.
BOOL CCustomEditCtrl::IsIntelliSenceWord(const CString& strWord) const
{
if (!IsIntelliSenseEnabled())
{
return FALSE;
}
StringIndex* pStringIndex;
if (m_mIntelliString.Lookup(strWord, (void*&)pStringIndex))
{
return TRUE;
}
return FALSE;
}
// 填充联想浮动窗口.
BOOL CCustomEditCtrl::FillIntelliSenseList (CObList& lstIntelliSenseData,
LPCTSTR lpszIntelliSense /* = NULL */) const
{
if (lpszIntelliSense == NULL)
{
BOOL bRet;
CString strIntelliSence;
int nCurrOffset = m_nCurrOffset;
if (!OnBeforeInvokeIntelliSense(m_strBuffer, nCurrOffset, strIntelliSence))
{
return FALSE;
}
bRet = FillIntelliSenseList(lstIntelliSenseData, strIntelliSence.GetBuffer(0));
ASSERT(bRet);
return bRet;
}
if (!IsIntelliSenseEnabled() ||
!IsIntelliSenceWord(lpszIntelliSense))
{
return FALSE;
}
StringIndex* pStringIndex;
if (!m_mIntelliString.Lookup(lpszIntelliSense, (void*&)pStringIndex))
{
return FALSE;
}
CBCGPIntelliSenseData* pData;
lstIntelliSenseData.RemoveAll();
for (int ind = 0; pStringIndex[ind].lpszName != NULL; ind++)
{
pData = new CBCGPIntelliSenseData;
pData->m_strItemName = pStringIndex[ind].lpszName;
pData->m_nImageListIndex = pStringIndex[ind].nIndex;
lstIntelliSenseData.AddTail (pData);
}
return TRUE;
}
BOOL CCustomEditCtrl::IntelliSenseCharUpdate(const CString& strBuffer, int nCurrOffset, TCHAR nChar, CString& strIntelliSense)
{
if (!IsIntelliSenseEnabled())
{
return FALSE;
}
if (nChar == _T('.'))
{
if ((nCurrOffset > 0) && (nCurrOffset <= strBuffer.GetLength()) &&
strBuffer.GetAt(nCurrOffset - 1) == nChar)
{
CString strWord;
int nOffset = nCurrOffset;
if (!OnBeforeInvokeIntelliSense(strBuffer, nOffset, strWord))
{
nOffset = strWord.GetLength();
if ((nOffset > 1) && (strWord.GetAt(nOffset - 1) == nChar))
{
strWord.SetAt(nOffset - 1, _T('-'));
strWord += _T('>');
nOffset++;
if (IsIntelliSenceWord(strWord))
{
strIntelliSense = _T("->");
return TRUE;
}
}
}
}
else
{
ASSERT(FALSE);
}
}
return FALSE;
}
BOOL CCustomEditCtrl::OnBeforeInvokeIntelliSense (const CString& strBuffer, int& nCurrOffset, CString& strIntelliSence) const
{
if (!IsIntelliSenseEnabled())
{
return FALSE;
}
strIntelliSence.Empty();
int nOffset = nCurrOffset;
if (nOffset > strBuffer.GetLength())
{
nOffset = strBuffer.GetLength();
}
if (nOffset >= 0)
{
for (--nOffset;
nOffset >= 0 &&
m_strIntelliSenseChars.Find(strBuffer.GetAt(nOffset)) == -1 &&
(m_strNonSelectableChars.Find(strBuffer.GetAt(nOffset)) >= 0 ||
m_strWordDelimeters.Find(strBuffer.GetAt(nOffset)) == -1);
nOffset--);
if (nOffset >= 0 &&
FillIntelliSenceWord(strBuffer,nOffset,strIntelliSence) &&
IsIntelliSenceWord(strIntelliSence))
{
nCurrOffset = nOffset + 1;
return TRUE;
}
}
else
{
ASSERT(FALSE);
}
return FALSE;
}
BOOL CCustomEditCtrl::FillIntelliSenceWord(const CString& strBuffer, int nOffset, CString& strIntelliSence) const
{
CString strISWord, strWordSuffix;
if (!CheckIntelliMark(strBuffer,nOffset,strWordSuffix) || nOffset >= 0)
{
do
{
int nStartOffset = -1,
nEndOffset = -1;
FindWordStartFinish (nOffset, strBuffer, nStartOffset, nEndOffset);
if ((nStartOffset < nEndOffset) && (nStartOffset >= 0))
{
const CString& strWord = strBuffer.Mid(nOffset = nStartOffset, nEndOffset - nStartOffset);
strISWord = strWord + strWordSuffix + strISWord;
}
else
{
strISWord = strWordSuffix + strISWord;
break;
}
strWordSuffix.Empty();
}
while (GetNextPos(strBuffer, m_strNonSelectableChars, nOffset, FALSE) >= 0 &&
CheckIntelliMark(strBuffer,nOffset,strWordSuffix) &&
nOffset >= 0);
}
if ((strISWord = strWordSuffix + strISWord).IsEmpty())
{
return FALSE;
}
strIntelliSence = strISWord;
return TRUE;
}
void CCustomEditCtrl::ReleaseIntelliSenseList(CObList& lstIntelliSenseData)
{
for (POSITION pos = lstIntelliSenseData.GetHeadPosition();
pos != NULL;
delete lstIntelliSenseData.GetNext(pos));
lstIntelliSenseData.RemoveAll();
}
BOOL CCustomEditCtrl::CheckIntelliMark(const CString& strBuffer, int& nOffset, CString& strWordSuffix) const
{
BOOL bIntelliMark = (strBuffer.GetAt (nOffset) == _T ('.'));
if (bIntelliMark)
{
strWordSuffix = _T('.');
}
else if (strBuffer.GetAt (nOffset) == _T ('>'))
{
int nTempOffset = nOffset;
if (GetNextPos(strBuffer, m_strNonSelectableChars, nTempOffset, FALSE) >= 0)
{
if (strBuffer.GetAt (nTempOffset) == _T ('-'))
{
strWordSuffix = _T("->");
nOffset = nTempOffset;
bIntelliMark = TRUE;
}
}
}
else if (strBuffer.GetAt (nOffset) == _T (':'))
{
int nTempOffset = nOffset;
if (GetNextPos(strBuffer, m_strNonSelectableChars, nTempOffset, FALSE) >= 0)
{
if (strBuffer.GetAt (nTempOffset) == _T (':'))
{
strWordSuffix = _T("::");
nOffset = nTempOffset;
bIntelliMark = TRUE;
}
}
}
if (bIntelliMark)
{
nOffset--;
}
return bIntelliMark;
}
int CCustomEditCtrl::GetNextPos(const CString& strBuffer, const CString& strSkipChars, int& nPos, BOOL bForward)
{
if (bForward)
{
for (int nLen = strBuffer.GetLength();
nPos < nLen &&
strSkipChars.Find(strBuffer.GetAt(nPos)) >= 0;
nPos++);
}
else
{
for (--nPos;
nPos >= 0 &&
strSkipChars.Find(strBuffer.GetAt(nPos)) >= 0;
nPos--);
}
return nPos;
}
BOOL CCustomEditCtrl::CopyAsHTML ()
{
CString strBuffer;
ExportToHTML (strBuffer);
return CopyTextToClipboard (strBuffer, strBuffer.GetLength ());
}
BOOL CCustomEditCtrl::IsToggleOutliningEnabled ()
{
int iStartSel = min (m_iStartSel, m_iEndSel);
int iEndSel = max (m_iStartSel, m_iEndSel) - 1;
if (iStartSel >= 0 && iEndSel < m_strBuffer.GetLength () && iStartSel <= iEndSel)
{
CObList lstBlocks;
m_OutlineNodes.GetBlocksInRange (iStartSel, iEndSel, lstBlocks, FALSE, FALSE);
return (lstBlocks.GetCount () > 0);
}
if (m_nCurrOffset < 0 || m_nCurrOffset >= m_strBuffer.GetLength ())
{
return FALSE;
}
CBCGPOutlineBaseNode* pOutlineNode = m_OutlineNodes.GetInnermostBlock (m_nCurrOffset);
return (pOutlineNode != NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -