📄 syneditview.cpp
字号:
int nHorzPos = m_nHorzPos;
CalcHorzScrollPos();
if(nHorzPos != m_nHorzPos)
{
SendMessage(WM_PAINT, 0, 0);
}
}
void CSynEditView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRichEditView::OnLButtonDown(nFlags, point);
SendMessage(WM_PAINT, 0, 0);
}
void CSynEditView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CRichEditView::OnKeyUp(nChar, nRepCnt, nFlags);
SendMessage(WM_PAINT, 0, 0);
}
BOOL CSynEditView::IsSelectionInStr(int nFromHere, int nStrWidth, int nTop)
{
if( m_ptStart == m_ptEnd )
return FALSE;
if( m_ptStart.y != m_ptEnd.y ) //如果选定行不为单行,返回,因为字符不可能跨行
return FALSE;
if( m_ptStart.y != nTop ) //如果待测试行的顶部不等于选定行的顶部则返回
return FALSE;
if( (m_ptStart.x > nFromHere) && (m_ptEnd.x < nFromHere + nStrWidth) )
return TRUE;
else
return FALSE;
}
int CSynEditView::GetLanguage()
{
return m_nLanguage;
}
void CSynEditView::SetColor(int nColorIndex, COLORREF clrNew)
{
switch(nColorIndex) {
case COLORINDEX_BK:
m_clrBkColor = clrNew;
break;
case COLORINDEX_COMMENT:
m_clrCommentColor = clrNew;
break;
case COLORINDEX_SYNTAX:
m_clrSyntaxColor = clrNew;
break;
case COLORINDEX_NORMAL:
m_clrNormalColor = clrNew;
break;
case COLORINDEX_STRING:
m_clrStringColor = clrNew;
break;
case COLORINDEX_CHAR:
m_clrCharColor = clrNew;
break;
case COLORINDEX_NUMBER:
m_clrNumberColor = clrNew;
break;
case COLORINDEX_UNDERLINE:
m_clrUnderLine = clrNew;
break;
case COLORINDEX_LINEEND:
m_clrLineEnd = clrNew;
break;
case COLORINDEX_BKCURLINE:
m_clrBkCurLine = clrNew;
break;
case COLORINDEX_LINNUMBERBKCOLOR:
m_clrLinNumberBkColor = clrNew;
break;
case COLORINDEX_LINNUMBERNORMAL:
m_clrLinNumberNormal = clrNew;
break;
case COLORINDEX_CURLINNUMBER:
m_clrCurLinNumber = clrNew;
break;
case COLORINDEX_LINNUMBERSEP:
m_clrLinNumberSep = clrNew;
break;
case COLORINDEX_CROSS:
m_clrCross = clrNew;
break;
case COLORINDEX_TAB:
m_clrTab = clrNew;
break;
case COLORINDEX_BKSELTEXT:
m_clrBKSelText = clrNew;
break;
}
WriteSettings();
}
COLORREF CSynEditView::GetColor(int nColorIndex)
{
switch(nColorIndex) {
case COLORINDEX_BK:
return m_clrBkColor;
case COLORINDEX_COMMENT:
return m_clrCommentColor;
case COLORINDEX_SYNTAX:
return m_clrSyntaxColor;
case COLORINDEX_NORMAL:
return m_clrNormalColor;
case COLORINDEX_STRING:
return m_clrStringColor;
case COLORINDEX_CHAR:
return m_clrCharColor;
case COLORINDEX_NUMBER:
return m_clrNumberColor;
case COLORINDEX_UNDERLINE:
return m_clrUnderLine;
case COLORINDEX_LINEEND:
return m_clrLineEnd;
case COLORINDEX_BKCURLINE:
return m_clrBkCurLine;
case COLORINDEX_LINNUMBERBKCOLOR:
return m_clrLinNumberBkColor;
case COLORINDEX_LINNUMBERNORMAL:
return m_clrLinNumberNormal;
case COLORINDEX_CURLINNUMBER:
return m_clrCurLinNumber;
case COLORINDEX_LINNUMBERSEP:
return m_clrLinNumberSep;
case COLORINDEX_CROSS:
return m_clrCross;
case COLORINDEX_TAB:
return m_clrTab;
case COLORINDEX_BKSELTEXT:
return m_clrBKSelText;
default:
return m_clrNormalColor;
}
}
void CSynEditView::ReadColorInfo(int nLanguage)
{
CString strColorPos = _T("icrEdit_Color");
strColorPos += GetLanguageString(nLanguage);
CWinApp *app = AfxGetApp();
m_clrBkColor = app->GetProfileInt( strColorPos, _T("m_clrBkColor"), RGB(255, 255, 255));
m_clrCommentColor = app->GetProfileInt( strColorPos, _T("m_clrCommentColor"), RGB(0, 128, 0));
m_clrSyntaxColor = app->GetProfileInt( strColorPos, _T("m_clrSyntaxColor"), RGB(0, 0, 255));
m_clrNormalColor = app->GetProfileInt( strColorPos, _T("m_clrNormalColor"), RGB(0, 0, 0));
m_clrStringColor = app->GetProfileInt( strColorPos, _T("m_clrStringColor"), RGB(128, 0, 0));
m_clrCharColor = app->GetProfileInt( strColorPos, _T("m_clrCharColor"), RGB(128, 0, 0));
m_clrNumberColor = app->GetProfileInt( strColorPos, _T("m_clrNumberColor"), RGB(255, 0, 0));
m_clrUnderLine = app->GetProfileInt( strColorPos, _T("m_clrUnderLine"), RGB(200, 200, 200));
m_clrLineEnd = app->GetProfileInt( strColorPos, _T("m_clrLineEnd"), RGB(0, 0, 200));
m_clrBkCurLine = app->GetProfileInt( strColorPos, _T("m_clrBkCurLine"), RGB(200, 200, 200));
m_clrLinNumberBkColor = app->GetProfileInt( strColorPos, _T("m_clrLinNumberBkColor"), RGB(255, 255, 255));
m_clrLinNumberNormal = app->GetProfileInt( strColorPos, _T("m_clrLinNumberNormal"), RGB(192, 192, 192));
m_clrCurLinNumber = app->GetProfileInt( strColorPos, _T("m_clrCurLinNumber"), RGB(0, 0, 128));
m_clrLinNumberSep = app->GetProfileInt( strColorPos, _T("m_clrLinNumberSep"), RGB(192, 192, 192));
m_clrCross = app->GetProfileInt( strColorPos, _T("m_clrCross"), RGB(0, 0, 128));
m_clrTab = app->GetProfileInt( strColorPos, _T("m_clrTab"), RGB(128, 128, 128));
m_clrBKSelText = app->GetProfileInt( strColorPos, _T("m_clrBKSelText"), RGB(0, 0, 128));
}
BOOL CSynEditView::IsShowLineNumber()
{
return m_bShowLineNumber;
}
BOOL CSynEditView::IsShowSelectLine()
{
return m_bShowSelectLine;
}
BOOL CSynEditView::IsShowUnderLine()
{
return m_bShowUnderLine;
}
BOOL CSynEditView::IsShowReturnLineToken()
{
return m_bShowReturnLineToken;
}
int CSynEditView::GetTabSize()
{
return m_nTabSize;
}
CString CSynEditView::GetSingleCommentString(int nlanguage)
{
return GetLineCommentString(nlanguage);
}
void CSynEditView::DrawReturnLineToken(BOOL bRealReturn, CDC *cacheDC, CRect &rcline)
{
rcline.OffsetRect(-m_nCharSpaceWidth-2, 0);
int nlineheight = rcline.Height();
int nleft = rcline.left;
int ntop = rcline.top + nlineheight/4 + 1 ;
int nbottom = rcline.bottom - nlineheight/4;
if(bRealReturn) {
for(int i=ntop; i<nbottom; i++)
cacheDC->SetPixel( nleft + 5, i+1, m_clrLineEnd );
cacheDC->SetPixel( nleft + 2, nbottom - 3, m_clrLineEnd );
cacheDC->SetPixel( nleft + 3, nbottom - 2, m_clrLineEnd );
cacheDC->SetPixel( nleft + 4, nbottom - 1, m_clrLineEnd );
cacheDC->SetPixel( nleft + 6, nbottom - 1, m_clrLineEnd );
cacheDC->SetPixel( nleft + 7, nbottom - 2, m_clrLineEnd );
cacheDC->SetPixel( nleft + 8, nbottom - 3, m_clrLineEnd );
}
else {
int nhalfline = rcline.top + nlineheight/2;
for(int i=nleft+2; i<nleft+8; i++)
cacheDC->SetPixel( i, nhalfline, m_clrLineEnd );
cacheDC->SetPixel( nleft + 7, nhalfline-1, m_clrLineEnd );
cacheDC->SetPixel( nleft + 7, nhalfline+1, m_clrLineEnd );
cacheDC->SetPixel( nleft + 6, nhalfline-2, m_clrLineEnd );
cacheDC->SetPixel( nleft + 6, nhalfline+2, m_clrLineEnd );
cacheDC->SetPixel( nleft + 5, nhalfline-3, m_clrLineEnd );
cacheDC->SetPixel( nleft + 5, nhalfline+3, m_clrLineEnd );
}
}
void CSynEditView::GetSelLine(int &nfirstline, int &nendline)
{
CRichEditCtrl &SynCtrl = GetRichEditCtrl();
CHARRANGE cr;
SynCtrl.GetSel( cr );
//计算选定区域的第一行和最后一行
nfirstline = SynCtrl.LineFromChar(cr.cpMin);
nendline = SynCtrl.LineFromChar(cr.cpMax);
if(SynCtrl.LineFromChar(cr.cpMax-1)<nendline)
--nendline;
if(nendline<nfirstline)
nendline = nfirstline;
//////////////////////////////////
}
BOOL CSynEditView::IsReadOnly()
{
return m_bReadOnly;
}
void CSynEditView::SetReadOnly(BOOL bReadOnly)
{
m_bReadOnly = bReadOnly;
GetRichEditCtrl().SetReadOnly(m_bReadOnly);
WriteSettings();
}
//这个函数的作用是在粘贴时重置行nParseArraySize的语法解析缓冲区, 调用位置在CMainFrame的粘贴处理函数
void CSynEditView::SetParseCookieZeroFromGivenLine(int nParseArraySize)
{
memset(m_pdwParseCookies + nParseArraySize, 0xff, sizeof(DWORD) * (m_nParseArraySize - nParseArraySize));
}
int CSynEditView::GetUndoLimits()
{
return m_nUndoLimits;
}
void CSynEditView::SetUndoLimits(int nMax)
{
m_nUndoLimits = nMax;
SendMessage(EM_SETUNDOLIMIT, m_nUndoLimits, 0);
WriteSettings();
}
BOOL CSynEditView::IsAutoWordSelect()
{
const DWORD eco = SendMessage(EM_GETOPTIONS, 0, 0);
if(eco & ECO_AUTOWORDSELECTION)
return TRUE;
else
return FALSE;
}
void CSynEditView::SetAutoWordSelect(BOOL bAutoSelect)
{
if(IsAutoWordSelect()) {
if(!bAutoSelect)
SendMessage(EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOWORDSELECTION);
}
else {
if(bAutoSelect)
SendMessage(EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOWORDSELECTION);
}
}
void CSynEditView::DrawCross(CDC *cacheDC)
{
if(m_ptStart!=m_ptEnd)
return;
CPen NewPen(PS_SOLID, 1, m_clrCross);
CPen *OldPen = cacheDC->SelectObject(&NewPen);
cacheDC->MoveTo(m_nLeftMargin, m_ptStart.y+m_nLineHeight);
cacheDC->LineTo(m_rcClient.Width(), m_ptStart.y+m_nLineHeight);
cacheDC->MoveTo(m_ptStart.x, 0);
cacheDC->LineTo(m_ptStart.x, m_rcClient.Height());
cacheDC->SelectObject(OldPen);
}
void CSynEditView::ShowCross(BOOL bShow)
{
m_bShowCross = bShow;
}
BOOL CSynEditView::IsShowCross()
{
return m_bShowCross;
}
void CSynEditView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
InvalidateRect(m_rcClient, FALSE);
m_bAllowDraw = FALSE;
CRichEditView::OnVScroll(nSBCode, nPos, pScrollBar);
m_bAllowDraw = TRUE;
ValidateRect(m_rcClient);
SendMessage(WM_PAINT, 0, 0);
}
BOOL CSynEditView::IsShowTabSpace()
{
return m_bShowTab;
}
void CSynEditView::ShowTabSpace(BOOL bShow)
{
m_bShowTab = bShow;
}
int CSynEditView::GetVisibleLineCount()
{
return m_rcClient.Height() / m_nLineHeight;
}
int CSynEditView::GetSpaceWidth()
{
return m_nCharSpaceWidth;
}
void CSynEditView::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawSynEditView();
// Do not call CRichEditView::OnPaint() for painting messages
}
void CSynEditView::InitEditorFont()
{
SetWindowText(""); //此行不必要,因为初始化时内容必为空,同时会引导致启动程序时内容为空
SetSynEditViewFont(m_lf); //不会改文本内容
//将tab宽设置好
SetSynCtrlTabSize(m_nTabSize); //不会改文本内容
/////////////////
//EM_SETTEXTMODE必须要内容为空时才有效
SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT|TM_MULTILEVELUNDO|TM_SINGLECODEPAGE, 0);
}
void CSynEditView::OnSetFocus(CWnd* pOldWnd)
{
CRichEditView::OnSetFocus(pOldWnd);
SendMessage(WM_PAINT, 0, 0);
}
//从RichEditCtrl中流出文本
//文本流入到RichEditCtrl中
//dwCookie - 送入的一段文本的首地址,文本长度通常为2k
//pbBuff - 可以理解为RichEditCtrl的文本缓冲区
//cb - 送来的文本长度,通常为2k
//pcb - 送入的文本长度,将会回调给RichEditCtrl
DWORD CALLBACK EditStreamCallbackOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
/*
//下面的代码来自MFC Programmer's SourceBook
As noted in Article ID: Q136810 of Microsoft Knowlage Base: The EditStreamCallback
function is called until *pcb receives a zero value.
I found this problem only appear when work with win9x (in win2k EditStreamCallback
never called again for normal text if *pcb gets value less than cb)
So you can use next techniques for stream in (& out ) normal text:
*/
CString* strWholeString = reinterpret_cast<CString*>(dwCookie);
// I hope this allocation/deallocation better then manipulation with CStrings
char* szInThisCall = new char[cb+1];
memcpy( szInThisCall, reinterpret_cast<char*>(pbBuff), cb );
szInThisCall[cb] = '\0';
// This is the main trik! Control can call this function for just a part of string!
(*strWholeString ) += szInThisCall;
delete [] szInThisCall;
*pcb = cb;
return 0;
}
void CSynEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CRichEditCtrl &SynCtrl = GetRichEditCtrl();
CHARRANGE cr;
SynCtrl.GetSel( cr );
CRichEditView::OnChar(nChar, nRepCnt, nFlags);
if(cr.cpMax != cr.cpMin)
{
ReCalcCursorPostion();
}
else
{
SCROLLINFO si;
si.cbSize = sizeof(si);
GetScrollInfo(SB_HORZ, &si);
m_nHorzMaxOld = si.nMax;
}
}
void CSynEditView::ReCalcCursorPostion()
{
CRichEditCtrl &SynCtrl = GetRichEditCtrl();
SCROLLINFO si;
si.cbSize = sizeof(si);
GetScrollInfo(SB_HORZ, &si);
if(si.nMax != m_nHorzMaxOld)
{
m_nHorzMaxOld = si.nMax;
SendMessage(WM_KEYDOWN, 0xd, 0);
SendMessage(WM_KEYDOWN, VK_BACK, 0);
if(GetCurrentLine()!=0)
{
SendMessage(WM_KEYDOWN, VK_UP, 0);
SendMessage(WM_KEYDOWN, VK_DOWN, 0);
}
if(GetCurrentLine()!=SynCtrl.GetLineCount()-1)
{
SendMessage(WM_KEYDOWN, VK_DOWN, 0);
SendMessage(WM_KEYDOWN, VK_UP, 0);
}
}
}
LRESULT CSynEditView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
CHARRANGE cr;
if(WM_IME_CHAR == message)
{
CRichEditCtrl &SynCtrl = GetRichEditCtrl();
SynCtrl.GetSel( cr );
}
LRESULT lr = CRichEditView::WindowProc(message, wParam, lParam);
if(WM_IME_CHAR == message)
{
if(cr.cpMax != cr.cpMin)
{
ReCalcCursorPostion();
}
else
{
SCROLLINFO si;
si.cbSize = sizeof(si);
GetScrollInfo(SB_HORZ, &si);
m_nHorzMaxOld = si.nMax;
}
}
return lr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -