SynEditView.cpp 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973
  1. #include "stdafx.h"
  2. #include <malloc.h>
  3. #include "SynEditView.h"
  4. #include "Mainfrm.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. DWORD CALLBACK EditStreamCallbackReadFromFile(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
  11. DWORD CALLBACK EditStreamCallbackWriteToFile(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
  12. DWORD CALLBACK EditStreamCallbackOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CSynEditView
  15. IMPLEMENT_DYNCREATE(CSynEditView, CRichEditView)
  16. BEGIN_MESSAGE_MAP(CSynEditView, CRichEditView)
  17. //{{AFX_MSG_MAP(CSynEditView)
  18. ON_WM_SIZE()
  19. ON_WM_CREATE()
  20. ON_WM_DESTROY()
  21. ON_WM_HSCROLL()
  22. ON_WM_KEYDOWN()
  23. ON_WM_LBUTTONDOWN()
  24. ON_WM_KEYUP()
  25. ON_WM_VSCROLL()
  26. ON_WM_PAINT()
  27. ON_WM_SETFOCUS()
  28. ON_WM_CHAR()
  29. //}}AFX_MSG_MAP
  30. // Standard printing commands
  31. ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
  32. ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
  33. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
  34. END_MESSAGE_MAP()
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CSynEditView construction/destruction
  37. CSynEditView::CSynEditView()
  38. {
  39. ReadSettings();
  40. m_nLineNumberCharNumber = 0;
  41. m_nLineCount = 0;
  42. m_nCharTabWidth = 1;
  43. m_nCharSpaceWidth = 1;
  44. m_nParseArraySize = 0;
  45. m_nHorzPos = 0;
  46. m_nCharNumberWidth = 1;
  47. m_nLineHeight = 17;
  48. m_nLeftMargin = 1;
  49. m_nCurrentLine = 0;
  50. m_bAllowDraw = TRUE;
  51. m_bRealReturn = TRUE;
  52. m_nDefaultLeftMargin = 0;
  53. m_nBookMarksCount = 0;
  54. m_bTrack = FALSE;
  55. m_pdwParseCookies = NULL;
  56. m_rcClient = NULL;
  57. m_pCacheBitmap = NULL;
  58. memset(anBookMarks, 0, sizeof(int)*256);
  59. m_nHorzMaxOld = 0;
  60. }
  61. CSynEditView::~CSynEditView()
  62. {
  63. if (m_pCacheBitmap != NULL)
  64. delete m_pCacheBitmap;
  65. if (m_pdwParseCookies != NULL)
  66. delete m_pdwParseCookies;
  67. }
  68. BOOL CSynEditView::PreCreateWindow(CREATESTRUCT& cs)
  69. {
  70. //*
  71. if (LoadLibraryA("RICHED20.DLL") == NULL)
  72. {
  73. AfxMessageBox(_T("Fail to load \"riched20.dll\"."),
  74. MB_OK | MB_ICONERROR);
  75. PostMessage(WM_QUIT,0,0);
  76. }
  77. m_strClass = RICHEDIT_CLASSA; //for 2.0 class
  78. //*/
  79. return CRichEditView::PreCreateWindow(cs);
  80. }
  81. void CSynEditView::OnInitialUpdate()
  82. {
  83. CRichEditView::OnInitialUpdate();
  84. // Set the printing margins (720 twips = 1/2 inch).
  85. SetMargins(CRect(1000, 800, 800, 800));
  86. ResetParseCookie();
  87. //SelectLanguage(m_nLanguage);
  88. SelectLanguage(3); //vb
  89. GetRichEditCtrl().HideSelection(TRUE, FALSE);
  90. SetWrapMode(m_nWrapMode);
  91. GetRichEditCtrl().SetReadOnly(m_bReadOnly);
  92. SendMessage(EM_SETUNDOLIMIT, m_nUndoLimits, 0);
  93. SetAutoWordSelect(m_bAutoWordSelect);
  94. CSynEditView::m_nWordWrap = m_nWrapMode;
  95. CSynEditView::WrapChanged();
  96. ResetParseCookie();
  97. if(m_nWrapMode == WrapNone)
  98. GetRichEditCtrl().ShowScrollBar(SB_HORZ, TRUE);
  99. else
  100. GetRichEditCtrl().ShowScrollBar(SB_HORZ, FALSE);
  101. InitEditorFont();
  102. PostMessage( WM_PAINT, 0, 0 );
  103. }
  104. /////////////////////////////////////////////////////////////////////////////
  105. // CSynEditView printing
  106. BOOL CSynEditView::OnPreparePrinting(CPrintInfo* pInfo)
  107. {
  108. // default preparation
  109. return DoPreparePrinting(pInfo);
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. // CSynEditView diagnostics
  113. #ifdef _DEBUG
  114. void CSynEditView::AssertValid() const
  115. {
  116. CRichEditView::AssertValid();
  117. }
  118. void CSynEditView::Dump(CDumpContext& dc) const
  119. {
  120. CRichEditView::Dump(dc);
  121. }
  122. #endif //_DEBUG
  123. /////////////////////////////////////////////////////////////////////////////
  124. // CSynEditView message handlers
  125. void CSynEditView::LoadFile(CString strFile)
  126. {
  127. SetWindowText(_T(""));
  128. ResetParseCookie();
  129. SetSynEditViewFont(m_lf);
  130. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  131. CFile* pInputFile = NULL;
  132. try
  133. {
  134. pInputFile = new CFile(strFile, CFile::modeRead | CFile::shareDenyNone);
  135. EDITSTREAM strm;
  136. strm.dwCookie = (DWORD) pInputFile;
  137. strm.pfnCallback = EditStreamCallbackReadFromFile;
  138. long lResult = SynCtrl.StreamIn(SF_TEXT, strm);
  139. pInputFile->Close();
  140. }
  141. catch (CFileException* pEx)
  142. {
  143. pEx->Delete();
  144. }
  145. delete pInputFile;
  146. SynCtrl.SetModify(FALSE);
  147. return;
  148. }
  149. //将文件中的内容装入到richeditctrl中,正常工作
  150. DWORD CALLBACK EditStreamCallbackReadFromFile(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  151. {
  152. CFile* pFile = (CFile*) dwCookie;
  153. ASSERT_KINDOF(CFile, pFile);
  154. *pcb = pFile->Read(pbBuff, cb);
  155. return 0;
  156. }
  157. //将richeditctrl中的内容写入到文件中,正常工作
  158. DWORD CALLBACK EditStreamCallbackWriteToFile(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  159. {
  160. CFile* pFile = (CFile*) dwCookie;
  161. pFile->Write(pbBuff, cb);
  162. *pcb = cb;
  163. return 0;
  164. }
  165. BOOL CSynEditView::IsFileExist(CString &strFile)
  166. {
  167. if(strFile.IsEmpty())
  168. return FALSE;
  169. FILE *file;
  170. if((file=fopen(strFile, _T("r")))==NULL)
  171. return FALSE;
  172. fclose(file);
  173. return TRUE;
  174. }
  175. void CSynEditView::SetSynEditViewFont(LOGFONT lf)
  176. {
  177. ResetParseCookie();
  178. SetSynCtrlFont(lf);
  179. WriteSettings();
  180. }
  181. void CSynEditView::SetSynCtrlFont(LOGFONT lf)
  182. {
  183. ShowWindow(SW_HIDE);
  184. CString str;
  185. EDITSTREAM stream;
  186. stream.dwCookie = (DWORD)&str;
  187. stream.pfnCallback = EditStreamCallbackOut;
  188. GetRichEditCtrl().StreamOut(SF_TEXT, stream);
  189. BOOL bModify = GetRichEditCtrl().GetModify();
  190. m_font.DeleteObject();
  191. m_font.CreateFontIndirect(&lf);
  192. //先设置视的字体
  193. SetFont(&m_font);
  194. m_lf = lf;
  195. /*
  196. SetWindowText((" "));
  197. GetRichEditCtrl().SetSel(0, 1);
  198. CHARFORMAT cr = GetCharFormatSelection();
  199. //设置视的字体可能改变,所以还要取其字体,看真正的结果,用GetFont不管用
  200. m_lf.lfCharSet = cr.bCharSet;
  201. m_lf.lfHeight = cr.yHeight/14;
  202. strcpy(m_lf.lfFaceName, cr.szFaceName);
  203. //*/
  204. SetCharWidth();
  205. SetLineHeight();
  206. SetLeftMargin();
  207. WriteSettings();
  208. SetWindowText(str);
  209. GetRichEditCtrl().SetModify(bModify);
  210. ShowWindow(SW_SHOW);
  211. }
  212. void CSynEditView::SetSynCtrlTabSize(int nSize)
  213. {
  214. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  215. CString str;
  216. EDITSTREAM stream;
  217. stream.dwCookie = (DWORD)&str;
  218. stream.pfnCallback = EditStreamCallbackOut;
  219. SynCtrl.StreamOut(SF_TEXT, stream);
  220. //因为tab宽度一直是固定的,所以开始就取tab宽度
  221. //又因为要计算最开始tab相当于几个数字宽,所以下面几行必须放在上面一行之后
  222. //RichEditView开始时tab宽为一常数,即0.5英寸=720 points
  223. SynCtrl.SetWindowText(_T("\t"));
  224. CPoint p1 = SynCtrl.GetCharPos(0);
  225. CPoint p2 = SynCtrl.GetCharPos(1);
  226. m_nCharTabWidth = p2.x - p1.x; //取tab在字体m_lf下的以point表示的宽度
  227. //设置TAB间隔
  228. PARAFORMAT pf ;
  229. pf.cbSize = sizeof(PARAFORMAT);
  230. pf.dwMask = PFM_TABSTOPS ;
  231. pf.cTabCount = MAX_TAB_STOPS;
  232. SynCtrl.GetParaFormat( pf );
  233. int nSynCtrlTabSize = pf.rgxTabs[0];
  234. if(nSynCtrlTabSize == 0)
  235. nSynCtrlTabSize = 720;
  236. /*
  237. Tab的计算方法:
  238. 1、先取SynCtrl默认的Tab宽度nSynCtrlTabSize(用英寸表示)
  239. 2、计算SynCtrl默认的Tab宽度对应几个数字m_nCharTabWidth / m_nCharNumberWidth
  240. 2、根据以上值计算每个数字的宽度nSynCtrlTabSize / (m_nCharTabWidth / m_nCharNumberWidth)
  241. 3、根据每个数字的宽度计算新的Tab宽度
  242. */
  243. SetWindowText(""); //此行不能删除,不然设置tab宽度会失败
  244. int nNewTab = int(nSynCtrlTabSize * 1.0 * nSize * m_nCharNumberWidth / m_nCharTabWidth);
  245. pf.cTabCount = MAX_TAB_STOPS;
  246. pf.dwMask = PFM_TABSTOPS;
  247. for(int itab = 0; itab < pf.cTabCount; itab++ )
  248. pf.rgxTabs[itab] = (itab+1) * nNewTab ;
  249. SynCtrl.SetParaFormat( pf );
  250. m_nTabSize = nSize;
  251. m_nCharTabWidth = nSize * m_nCharNumberWidth;
  252. WriteSettings();
  253. SetWindowText(str);
  254. }
  255. void CSynEditView::OnSize(UINT nType, int cx, int cy)
  256. {
  257. CRichEditView::OnSize(nType, cx, cy);
  258. GetClientRect(&m_rcClient);
  259. if (m_pCacheBitmap != NULL)
  260. {
  261. delete m_pCacheBitmap;
  262. m_pCacheBitmap = NULL;
  263. }
  264. SetLeftMargin();
  265. PostMessage(WM_PAINT, 0, 0);
  266. }
  267. void CSynEditView::LoadText(CString &strText)
  268. {
  269. ResetParseCookie();
  270. SetSynEditViewFont(m_lf);
  271. SetWindowText(strText);
  272. GetRichEditCtrl().SetModify( FALSE );
  273. }
  274. void CSynEditView::DrawSingleLineColorText( CDC *cacheDC, int nLine, CRect rcLine)
  275. {
  276. COLORREF clrBkColor = m_clrBkColor;
  277. CRect rtSrc(rcLine);
  278. //显示当前行
  279. if(m_bShowSelectLine) {
  280. if(nLine == m_nCurrentLine && m_ptStart == m_ptEnd)
  281. clrBkColor = m_clrBkCurLine;
  282. else
  283. clrBkColor = m_clrBkColor;
  284. cacheDC->FillSolidRect(rcLine, clrBkColor);
  285. }
  286. ////////////
  287. CFont cf;
  288. cf.CreateFontIndirect(&m_lf);
  289. CFont *pOldFont = cacheDC->SelectObject(&cf);
  290. CString strLine;
  291. BOOL bRealReturn = GetLineString(nLine, strLine); //取指定行文本,并返回是否为硬回车标志
  292. int nLength = strLine.GetLength();
  293. int nActualItems = 0;
  294. COLORINFO *ColorInfo = (COLORINFO *)_alloca( sizeof(COLORINFO) * (nLength + 1) );
  295. DWORD dwCookie = GetParseCookie(nLine-1);
  296. CString str;
  297. if( m_bRealReturn && (m_nLanguage != _HTML) && (m_nLanguage != _XML))
  298. dwCookie &= COOKIE_EXT_COMMENT;
  299. m_bRealReturn = bRealReturn;
  300. dwCookie = ParseLine(m_strArrayKeyWords, dwCookie, strLine, ColorInfo, nActualItems);
  301. m_pdwParseCookies[nLine] = dwCookie;
  302. COLORREF clr;
  303. CSize sizeContinueStr(0, 0);
  304. int nlen, nTabCount = 0;
  305. if (nActualItems > 0)
  306. {
  307. ASSERT(ColorInfo[0].Pos >= 0 && ColorInfo[0].Pos <= nLength);
  308. for (int I = 0; I < nActualItems; I ++)
  309. {
  310. nlen = ColorInfo[I + 1].Pos - ColorInfo[I].Pos;
  311. if( I == nActualItems - 1 )
  312. str = strLine.Mid(ColorInfo[I].Pos, strLine.GetLength() - ColorInfo[I].Pos);
  313. else
  314. str = strLine.Mid(ColorInfo[I].Pos, nlen);
  315. if(str.IsEmpty())
  316. continue;
  317. clr = GetColor(ColorInfo[I].Color);
  318. int nPos = str.Find(_T("\t"));
  319. while(-1 != nPos)
  320. {
  321. //遇到一个tab字符时,先将前面的字符画出来
  322. CString strTemp = str.Left(nPos);
  323. JudgeInSeletioAndDrawText( cacheDC, rcLine, strTemp, clrBkColor, clr );
  324. CSize sizeTemp = cacheDC->GetTextExtent(strTemp);
  325. nTabCount += 1; //既然找到了tab,那么就加1吧
  326. //把前面已经输出的字符串宽度换算成相应的tab个数
  327. nTabCount += int((sizeTemp.cx+sizeContinueStr.cx) / m_nCharTabWidth);
  328. int nOldLeft = rcLine.left;
  329. //然后直接定位到下一个tab位置
  330. rcLine.left = rtSrc.left + nTabCount * m_nCharTabWidth;
  331. //开始画tab////////////////////////
  332. BOOL bLeftInSel = IsStrInSelection(nOldLeft, rcLine.top, TRUE);
  333. BOOL bRightInSel = IsStrInSelection(rcLine.left, rcLine.top, FALSE);
  334. if(bLeftInSel && bRightInSel)
  335. {
  336. //如果tab在选择区域内,则要画背景
  337. CRect rtTab(nOldLeft, rcLine.top, rcLine.left, rcLine.bottom);
  338. cacheDC->FillSolidRect( &rtTab, m_clrBKSelText );
  339. }
  340. if(m_bShowTab)
  341. {
  342. int nleft = nOldLeft;
  343. int nCenterY = rcLine.top + (rcLine.bottom-rcLine.top)/2;
  344. for(int pos=1; pos<4; pos++)
  345. {
  346. cacheDC->SetPixel( nleft + pos + 0, pos + nCenterY - 4, m_clrTab );
  347. cacheDC->SetPixel( nleft + pos + 3, pos + nCenterY - 4, m_clrTab );
  348. cacheDC->SetPixel( nleft + pos + 0, -pos + nCenterY + 2, m_clrTab );
  349. cacheDC->SetPixel( nleft + pos + 3, -pos + nCenterY + 2, m_clrTab );
  350. }
  351. }
  352. //////////////////////////////////////
  353. str = str.Right(str.GetLength()-nPos-1);
  354. nPos = str.Find(_T("\t"));
  355. //重置输出字符串宽度
  356. sizeContinueStr.cx = 0;
  357. }
  358. JudgeInSeletioAndDrawText( cacheDC, rcLine, str, clrBkColor, clr );
  359. //保存已输出的字符中宽度
  360. CSize sizeTemp = cacheDC->GetTextExtent(str);
  361. sizeContinueStr += sizeTemp;
  362. }
  363. }
  364. if(m_bShowReturnLineToken)
  365. DrawReturnLineToken( m_bRealReturn, cacheDC, rcLine );
  366. //显示下划线
  367. if(m_bShowUnderLine) {
  368. CPen NewPen(PS_SOLID, 1, m_clrUnderLine);
  369. CPen *OldPen = cacheDC->SelectObject(&NewPen);
  370. cacheDC->MoveTo( rtSrc.left, rtSrc.bottom-1);
  371. cacheDC->LineTo( rtSrc.right, rtSrc.bottom-1);
  372. cacheDC->SelectObject(OldPen);
  373. }
  374. cacheDC->SelectObject(pOldFont);
  375. }
  376. void CSynEditView::SetWrapMode(int nWrapMode)
  377. {
  378. ShowWindow(SW_HIDE);
  379. //m_nCurrentLine = 0;
  380. //m_nParseArraySize = 0;//改变后需要重新计算
  381. m_nWrapMode = nWrapMode;
  382. CSynEditView::m_nWordWrap = m_nWrapMode;
  383. CSynEditView::WrapChanged();
  384. ResetParseCookie();
  385. ShowWindow(SW_SHOW);
  386. if(m_nWrapMode == WrapNone)
  387. GetRichEditCtrl().ShowScrollBar(SB_HORZ, TRUE);
  388. else
  389. GetRichEditCtrl().ShowScrollBar(SB_HORZ, FALSE);
  390. WriteSettings();
  391. CWinApp *app = AfxGetApp();
  392. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nWrapMode"), m_nWrapMode);
  393. }
  394. int CSynEditView::GetWrapMode()
  395. {
  396. return m_nWrapMode;
  397. }
  398. void CSynEditView::SetLeftMargin()
  399. {
  400. if(m_bShowLineNumber)
  401. m_nLeftMargin = m_nLineNumberCharNumber * m_nCharNumberWidth + m_nDefaultLeftMargin + 4;
  402. else
  403. m_nLeftMargin = m_nDefaultLeftMargin;
  404. GetClientRect(&m_rcClient);
  405. CRect rect(m_rcClient);
  406. rect.left = m_nLeftMargin;
  407. int nRightMargin;
  408. if(m_bShowReturnLineToken && GetWrapMode()==CSynEditView::WrapToWindow)
  409. nRightMargin = 12; //为行末标志留出空间
  410. else
  411. nRightMargin= 0;
  412. rect.right -= nRightMargin;
  413. GetRichEditCtrl().SetRect(&rect);
  414. if(GetWrapMode()==CSynEditView::WrapToWindow) {
  415. ResetParseCookie();
  416. }
  417. }
  418. int CSynEditView::GetLinesTop(int nline)
  419. {
  420. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  421. if( nline > SynCtrl.GetLineCount()-1 ) {
  422. int nOffset = SynCtrl.LineIndex( nline-1 );
  423. CPoint p = SynCtrl.GetCharPos( nOffset );
  424. return p.y+m_nLineHeight;
  425. }
  426. int nOffset = SynCtrl.LineIndex( nline );
  427. CPoint p = SynCtrl.GetCharPos( nOffset );
  428. return p.y;
  429. }
  430. void CSynEditView::SetLineHeight()
  431. {
  432. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  433. SynCtrl.SetWindowText(_T("\n "));
  434. CPoint ps, pe;
  435. ps = SynCtrl.GetCharPos(0);
  436. pe = SynCtrl.GetCharPos(3);
  437. m_nLineHeight = pe.y - ps.y;
  438. }
  439. void CSynEditView::SetCharWidth()
  440. {
  441. CPoint p1, p2;
  442. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  443. SynCtrl.SetWindowText(_T("8")); //数字宽度
  444. p1 = SynCtrl.GetCharPos(0);
  445. p2 = SynCtrl.GetCharPos(1);
  446. m_nCharNumberWidth = p2.x - p1.x;
  447. m_nDefaultLeftMargin = 15; //设为15主要是为书签留出空间
  448. SynCtrl.SetWindowText(_T(" ")); //空格宽度
  449. p1 = SynCtrl.GetCharPos(0);
  450. p2 = SynCtrl.GetCharPos(1);
  451. m_nCharSpaceWidth = p2.x - p1.x;
  452. }
  453. void CSynEditView::SelectLanguage(int nLanguage)
  454. {
  455. CWinApp *app = AfxGetApp();
  456. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nLanguage"), nLanguage);
  457. m_nLanguage = nLanguage;
  458. SetCurLanguage(nLanguage);
  459. ReadColorInfo( m_nLanguage );
  460. LoadSynWord( m_strArrayKeyWords, m_nLanguage );
  461. ResetParseCookie();
  462. SendMessage( WM_PAINT, 0, 0 );
  463. }
  464. void CSynEditView::DrawLineNumber(CDC *cacheDC, int nline, CRect rect)
  465. {
  466. int nHalfHeight = rect.top + rect.Height()/2;
  467. int nLeft;
  468. if(m_bShowLineNumber)
  469. {
  470. nLeft = rect.right+1;
  471. }
  472. else
  473. {
  474. nLeft = rect.left-1;
  475. }
  476. //*
  477. //画书签
  478. for(int i=0; i<m_nBookMarksCount; i++)
  479. {
  480. if(nline+1 == anBookMarks[i])
  481. {
  482. int j;
  483. for(j=0; j<6; j++)
  484. cacheDC->SetPixel(nLeft+7+j, nHalfHeight-j, m_clrCurLinNumber);
  485. for(j=0; j<6; j++)
  486. cacheDC->SetPixel(nLeft+7-j, nHalfHeight+j, m_clrCurLinNumber);
  487. for(j=0; j<5; j++)
  488. cacheDC->SetPixel(nLeft+8, nHalfHeight+j, m_clrCurLinNumber);
  489. for(j=-1; j<6; j++)
  490. cacheDC->SetPixel(nLeft+9, nHalfHeight+j, m_clrCurLinNumber);
  491. for(j=-2; j<7; j++)
  492. cacheDC->SetPixel(nLeft+10, nHalfHeight+j, m_clrCurLinNumber);
  493. for(j=-3; j<7; j++)
  494. cacheDC->SetPixel(nLeft+11, nHalfHeight+j, m_clrCurLinNumber);
  495. for(j=-2; j<7; j++)
  496. cacheDC->SetPixel(nLeft+12, nHalfHeight+j, m_clrCurLinNumber);
  497. for(j=1; j<6; j++)
  498. cacheDC->SetPixel(nLeft+13, nHalfHeight+j, m_clrCurLinNumber);
  499. for(j=2; j<4; j++)
  500. cacheDC->SetPixel(nLeft+14, nHalfHeight+j, m_clrCurLinNumber);
  501. }
  502. }
  503. //*/
  504. if(!m_bShowLineNumber)
  505. return;
  506. CFont newFont;
  507. newFont.CreateFontIndirect(&m_lf);
  508. CFont *pOldFont = cacheDC->SelectObject(&newFont);
  509. CString str, str1;
  510. str1.Format(_T("%%0%d"), m_nLineNumberCharNumber);
  511. str.Format(str1+_T("d"), nline+1);
  512. CSize size = cacheDC->GetTextExtent(str);
  513. int nOffsetY = (rect.Height()-size.cy)/2;
  514. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  515. if( (nline == m_nCurrentLine) && (m_ptStart == m_ptEnd) ) {
  516. cacheDC->SetTextColor(m_clrCurLinNumber);
  517. cacheDC->TextOut(rect.left, rect.top+nOffsetY, str);
  518. }
  519. else {
  520. cacheDC->SetTextColor(m_clrLinNumberNormal);
  521. cacheDC->TextOut(rect.left, rect.top+nOffsetY, str);
  522. }
  523. cacheDC->SelectObject(pOldFont);
  524. }
  525. int CSynEditView::GetCurrentLine()
  526. {
  527. CRichEditCtrl &SynCtrl=GetRichEditCtrl();
  528. CHARRANGE cr;
  529. SynCtrl.GetSel(cr);
  530. if( cr.cpMin == cr.cpMax )
  531. return SynCtrl.LineFromChar( cr.cpMax );
  532. else
  533. return m_nCurrentLine;
  534. }
  535. DWORD CSynEditView::GetParseCookie(int nLineIndex)
  536. {
  537. CRichEditCtrl &SynCtrl=GetRichEditCtrl();
  538. if (m_pdwParseCookies == NULL)
  539. {
  540. m_nParseArraySize = m_nLineCount;
  541. m_pdwParseCookies = new DWORD[m_nLineCount];
  542. memset(m_pdwParseCookies, 0xff, m_nLineCount * sizeof(DWORD));
  543. }
  544. if (nLineIndex < 0)
  545. return 0;
  546. if (m_pdwParseCookies[nLineIndex] != (DWORD) -1)
  547. return m_pdwParseCookies[nLineIndex];
  548. register int L = nLineIndex;
  549. while (L >= 0 && m_pdwParseCookies[L] == (DWORD) -1)
  550. L --;
  551. L ++;
  552. int nBlocks = 0;
  553. CString strLine;
  554. BOOL bRealReturn = m_bRealReturn;
  555. while (L <= nLineIndex)
  556. {
  557. DWORD dwCookie = 0;
  558. if (L > 0) {
  559. dwCookie = m_pdwParseCookies[L - 1];
  560. if(bRealReturn && m_nLanguage != _HTML && m_nLanguage != _XML)
  561. dwCookie &= COOKIE_EXT_COMMENT;
  562. }
  563. ASSERT(dwCookie != (DWORD) -1);
  564. bRealReturn = GetLineString(L, strLine);
  565. m_pdwParseCookies[L] = ParseLine(m_strArrayKeyWords, dwCookie, strLine, NULL, nBlocks);
  566. ASSERT(m_pdwParseCookies[L] != (DWORD) -1);
  567. L ++;
  568. }
  569. return m_pdwParseCookies[nLineIndex];
  570. }
  571. void CSynEditView::ShowUnderLine(BOOL bShowUnderLine)
  572. {
  573. m_bShowUnderLine = bShowUnderLine;
  574. WriteSettings();
  575. }
  576. void CSynEditView::ShowReturnLineToken(BOOL bShowReturnLineToken)
  577. {
  578. ShowWindow(SW_HIDE);
  579. m_bShowReturnLineToken = bShowReturnLineToken;
  580. if(GetWrapMode()==WrapToWindow) {
  581. SetLeftMargin();
  582. ResetParseCookie();
  583. }
  584. WriteSettings();
  585. ShowWindow(SW_SHOW);
  586. SetFocus();
  587. }
  588. void CSynEditView::ShowSelectLine(BOOL bShowSelectLine)
  589. {
  590. m_bShowSelectLine = bShowSelectLine;
  591. WriteSettings();
  592. }
  593. //*
  594. BOOL CSynEditView::GetLineString(int nLine, CString &strLine)
  595. {
  596. strLine = _T("");
  597. CRichEditCtrl &SynCtrl=GetRichEditCtrl();
  598. if(nLine > m_nLineCount - 1 || nLine < 0)
  599. return TRUE;
  600. int nTemp = SynCtrl.LineIndex(nLine);
  601. nTemp = SynCtrl.LineLength(nTemp)*16+32; //缓冲区必须足够大,否则读取中文时可能会有乱码
  602. TCHAR *achLine = new TCHAR[nTemp];
  603. int nLen = SynCtrl.GetLine(nLine, achLine, nTemp);
  604. //检查实际读出的字符数,一个中文应换算成两个字符
  605. int i = 0;
  606. nTemp = 0;
  607. while(nTemp != nLen)
  608. {
  609. if(IsDBCSLeadByte(achLine[i++]))
  610. i++;
  611. ++nTemp;
  612. }
  613. /////////////////////////////////////////////////
  614. BOOL bRealReturn;
  615. achLine[i] = 0;
  616. //检查是不是真的换行
  617. if(0xd == achLine[i-1])
  618. {
  619. achLine[--i] = 0;
  620. bRealReturn=TRUE;
  621. }
  622. else
  623. {
  624. achLine[i] = 0;
  625. bRealReturn=FALSE;
  626. }
  627. ////////////////////
  628. //尾部加一个空格,以送给语法解析器
  629. lstrcat(achLine, _T(" "));
  630. strLine = achLine;
  631. if(achLine)
  632. delete achLine;
  633. return bRealReturn;
  634. }
  635. //*/
  636. /*
  637. BOOL CSynEditView::GetLineString(int nLine, CString &strLine)
  638. {
  639. strLine = _T("");
  640. CRichEditCtrl &SynCtrl=GetRichEditCtrl();
  641. if(nLine > m_nLineCount - 1 || nLine < 0)
  642. return TRUE;
  643. int nTemp = SynCtrl.LineIndex(nLine);
  644. nTemp = SynCtrl.LineLength(nTemp) * sizeof(WCHAR);
  645. if(nTemp<=1) {
  646. strLine=_T(" ");
  647. return TRUE;
  648. }
  649. nTemp += 4 * sizeof(WCHAR);
  650. int nLen = SynCtrl.GetLine(nLine, strLine.GetBuffer(nTemp), nTemp);
  651. strLine.ReleaseBuffer();
  652. BOOL bRealReturn;
  653. if(nLen > strLine.GetLength())
  654. nLen = strLine.GetLength();
  655. if(nLen>=1 && strLine[nLen-1]==0xd ) {
  656. strLine = strLine.Left(--nLen);
  657. bRealReturn=TRUE;
  658. }
  659. else {
  660. strLine = strLine.Left(nLen);
  661. bRealReturn=FALSE;
  662. }
  663. strLine += _T(" ");
  664. return bRealReturn;
  665. }
  666. //*/
  667. void CSynEditView::ResetParseCookie()
  668. {
  669. m_nParseArraySize = 0;
  670. m_nHorzPos = 0;
  671. if(m_pdwParseCookies != NULL) {
  672. delete m_pdwParseCookies;
  673. m_pdwParseCookies = NULL;
  674. }
  675. if(m_pCacheBitmap!=NULL) {
  676. delete m_pCacheBitmap;
  677. m_pCacheBitmap = NULL;
  678. }
  679. return;
  680. }
  681. void CSynEditView::GotoLine(int nLine)
  682. {
  683. CRichEditCtrl &SynCtrl=GetRichEditCtrl();
  684. m_nLineCount = SynCtrl.GetLineCount();
  685. if(nLine>m_nLineCount)
  686. nLine = m_nLineCount;
  687. --nLine;
  688. int nFirstLine = SynCtrl.GetFirstVisibleLine();
  689. if( nLine < 1)
  690. nLine = 0;
  691. int nLineCount = GetVisibleLineCount();
  692. if(nLine >= nFirstLine && nLine < nFirstLine + nLineCount ) {
  693. int nLineIndex = SynCtrl.LineIndex(nLine);
  694. SynCtrl.SetSel(nLineIndex, nLineIndex);
  695. PostMessage(WM_PAINT, 0, 0); //可能要重画行号和光标
  696. return; //如果当前行在视界内则返回
  697. }
  698. int nTemp = nLine;
  699. if(nTemp > m_nLineCount - nLineCount)
  700. nTemp = m_nLineCount - nLineCount;
  701. int nScrollLines = nTemp - nFirstLine;
  702. SynCtrl.LineScroll(nScrollLines, 0);
  703. SetFocus();
  704. }
  705. void CSynEditView::ShowLineNumber(BOOL bShow)
  706. {
  707. ShowWindow(SW_HIDE);
  708. m_bShowLineNumber = bShow;
  709. SetLeftMargin();
  710. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  711. if(bShow)
  712. SynCtrl.SetBackgroundColor(FALSE, m_clrLinNumberBkColor);
  713. else
  714. SynCtrl.SetBackgroundColor(FALSE, m_clrBkColor);
  715. if(GetWrapMode()==WrapToWindow)
  716. ResetParseCookie();
  717. WriteSettings();
  718. ShowWindow(SW_SHOW);
  719. }
  720. int CSynEditView::OnCreate( LPCREATESTRUCT lpCreateStruct )
  721. {
  722. if (CRichEditView::OnCreate(lpCreateStruct) == -1)
  723. return -1;
  724. GetRichEditCtrl().HideSelection(TRUE, FALSE);
  725. return 0;
  726. }
  727. void CSynEditView::OnDestroy()
  728. {
  729. WriteSettings();
  730. DeleteAllocString();
  731. CRichEditView::OnDestroy();
  732. }
  733. LOGFONT CSynEditView::GetSynEditViewFont()
  734. {
  735. return m_lf;
  736. }
  737. void CSynEditView::ReadSettings()
  738. {
  739. CWinApp *app = AfxGetApp();
  740. m_nWrapMode = app->GetProfileInt(_T("icrEdit_Values"), _T("m_nWrapMode"), WrapNone);
  741. m_bShowLineNumber = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowLineNumber"), TRUE);
  742. m_bShowSelectLine = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowSelectLine"), FALSE);
  743. m_bShowUnderLine = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowUnderLine"), FALSE);
  744. m_bShowReturnLineToken = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowReturnLineToken"), FALSE);
  745. m_bShowCross = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowCross"), FALSE);
  746. m_bShowTab = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bShowTabSpace"), FALSE);
  747. m_nLanguage = app->GetProfileInt(_T("icrEdit_Values"), _T("m_nLanguage"), _CPP);
  748. m_nTabSize = app->GetProfileInt(_T("icrEdit_Values"), _T("m_nTabSize"), 4);
  749. m_bReadOnly = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bReadOnly"), FALSE);
  750. m_bAutoWordSelect = app->GetProfileInt(_T("icrEdit_Values"), _T("m_bAutoWordSelect"), FALSE);
  751. m_nUndoLimits = app->GetProfileInt(_T("icrEdit_Values"), _T("m_nUndoLimits"), 100);
  752. if(m_nUndoLimits<0)
  753. m_nUndoLimits=0;
  754. ReadColorInfo( m_nLanguage );
  755. //设置icrEditor默认字体
  756. m_lf.lfHeight = 0xfffffff4;
  757. m_lf.lfWidth = 0;
  758. m_lf.lfEscapement = 0;
  759. m_lf.lfOrientation = 0;
  760. m_lf.lfWeight = FW_NORMAL;
  761. m_lf.lfItalic = 0;
  762. m_lf.lfUnderline = 0;
  763. m_lf.lfStrikeOut = 0;
  764. m_lf.lfCharSet = ANSI_CHARSET;
  765. m_lf.lfOutPrecision = 1;
  766. m_lf.lfClipPrecision = 1;
  767. m_lf.lfQuality = 2;
  768. m_lf.lfPitchAndFamily = 0;
  769. strcpy(m_lf.lfFaceName, _T("Courier New"));
  770. m_lf.lfHeight = app->GetProfileInt(_T("icrEdit_Font"), _T("lfHeight"), m_lf.lfHeight);
  771. m_lf.lfWeight = app->GetProfileInt(_T("icrEdit_Font"), _T("lfWeight"), m_lf.lfWeight);
  772. m_lf.lfEscapement = app->GetProfileInt(_T("icrEdit_Font"), _T("lfEscapement"), m_lf.lfEscapement);
  773. m_lf.lfOrientation = app->GetProfileInt(_T("icrEdit_Font"), _T("lfOrientation"), m_lf.lfOrientation);
  774. m_lf.lfWeight = app->GetProfileInt(_T("icrEdit_Font"), _T("lfWeight"), m_lf.lfWeight);
  775. m_lf.lfItalic = app->GetProfileInt(_T("icrEdit_Font"), _T("lfItalic"), m_lf.lfItalic);
  776. m_lf.lfUnderline = app->GetProfileInt(_T("icrEdit_Font"), _T("lfUnderline"), m_lf.lfUnderline);
  777. m_lf.lfStrikeOut = app->GetProfileInt(_T("icrEdit_Font"), _T("lfStrikeOut"), m_lf.lfStrikeOut);
  778. m_lf.lfCharSet = app->GetProfileInt(_T("icrEdit_Font"), _T("lfCharSet"), m_lf.lfCharSet);
  779. m_lf.lfOutPrecision = app->GetProfileInt(_T("icrEdit_Font"), _T("lfOutPrecision"), m_lf.lfOutPrecision);
  780. m_lf.lfClipPrecision = app->GetProfileInt(_T("icrEdit_Font"), _T("lfClipPrecision"), m_lf.lfClipPrecision);
  781. m_lf.lfQuality = app->GetProfileInt(_T("icrEdit_Font"), _T("lfQuality"), m_lf.lfQuality);
  782. m_lf.lfPitchAndFamily = app->GetProfileInt(_T("icrEdit_Font"), _T("lfPitchAndFamily"), m_lf.lfPitchAndFamily);
  783. CString strFaceName = app->GetProfileString(_T("icrEdit_Font"), _T("lfFaceName"), m_lf.lfFaceName);
  784. strcpy(m_lf.lfFaceName, strFaceName);
  785. }
  786. void CSynEditView::WriteSettings()
  787. {
  788. CWinApp *app = AfxGetApp();
  789. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nWrapMode"), m_nWrapMode);
  790. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowLineNumber"), m_bShowLineNumber);
  791. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowSelectLine"), m_bShowSelectLine);
  792. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowUnderLine"), m_bShowUnderLine);
  793. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowReturnLineToken"), m_bShowReturnLineToken);
  794. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowCross"), m_bShowCross);
  795. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bShowTabSpace"), m_bShowTab);
  796. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nLanguage"), m_nLanguage);
  797. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nTabSize"), m_nTabSize);
  798. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bReadOnly"), m_bReadOnly);
  799. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_bAutoWordSelect"), IsAutoWordSelect());
  800. app->WriteProfileInt(_T("icrEdit_Values"), _T("m_nUndoLimits"), m_nUndoLimits);
  801. CString strColorPos = _T("icrEdit_Color");
  802. strColorPos += GetLanguageString(m_nLanguage);
  803. app->WriteProfileInt( strColorPos, _T("m_clrBkColor"), m_clrBkColor);
  804. app->WriteProfileInt( strColorPos, _T("m_clrCommentColor"), m_clrCommentColor);
  805. app->WriteProfileInt( strColorPos, _T("m_clrSyntaxColor"), m_clrSyntaxColor);
  806. app->WriteProfileInt( strColorPos, _T("m_clrNormalColor"), m_clrNormalColor);
  807. app->WriteProfileInt( strColorPos, _T("m_clrStringColor"), m_clrStringColor);
  808. app->WriteProfileInt( strColorPos, _T("m_clrCharColor"), m_clrCharColor);
  809. app->WriteProfileInt( strColorPos, _T("m_clrNumberColor"), m_clrNumberColor);
  810. app->WriteProfileInt( strColorPos, _T("m_clrUnderLine"), m_clrUnderLine);
  811. app->WriteProfileInt( strColorPos, _T("m_clrBkCurLine"), m_clrBkCurLine);
  812. app->WriteProfileInt( strColorPos, _T("m_clrLineEnd"), m_clrLineEnd);
  813. app->WriteProfileInt( strColorPos, _T("m_clrLinNumberBkColor"), m_clrLinNumberBkColor);
  814. app->WriteProfileInt( strColorPos, _T("m_clrLinNumberNormal"), m_clrLinNumberNormal);
  815. app->WriteProfileInt( strColorPos, _T("m_clrCurLinNumber"), m_clrCurLinNumber);
  816. app->WriteProfileInt( strColorPos, _T("m_clrLinNumberSep"), m_clrLinNumberSep);
  817. app->WriteProfileInt( strColorPos, _T("m_clrCross"), m_clrCross);
  818. app->WriteProfileInt( strColorPos, _T("m_clrTab"), m_clrTab);
  819. app->WriteProfileInt( strColorPos, _T("m_clrBKSelText"), m_clrBKSelText);
  820. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfHeight"), m_lf.lfHeight);
  821. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfWidth"), m_lf.lfWidth);
  822. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfEscapement"), m_lf.lfEscapement);
  823. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfOrientation"), m_lf.lfOrientation);
  824. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfWeight"), m_lf.lfWeight);
  825. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfItalic"), m_lf.lfItalic);
  826. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfUnderline"), m_lf.lfUnderline);
  827. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfStrikeOut"), m_lf.lfStrikeOut);
  828. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfCharSet"), m_lf.lfCharSet);
  829. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfOutPrecision"), m_lf.lfOutPrecision);
  830. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfClipPrecision"), m_lf.lfClipPrecision);
  831. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfItalic"), m_lf.lfItalic);
  832. app->WriteProfileInt(_T("icrEdit_Font"), _T("lfQuality"), m_lf.lfQuality);
  833. app->WriteProfileString(_T("icrEdit_Font"), _T("lfFaceName"), m_lf.lfFaceName);
  834. }
  835. void CSynEditView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  836. {
  837. InvalidateRect(m_rcClient, FALSE);
  838. m_bAllowDraw = FALSE;
  839. CRichEditView::OnHScroll(nSBCode, nPos, pScrollBar);
  840. m_bAllowDraw = TRUE;
  841. ValidateRect(m_rcClient);
  842. SCROLLINFO si;
  843. si.cbSize = sizeof(si);
  844. GetScrollInfo(SB_HORZ, &si);
  845. if(nSBCode==SB_THUMBPOSITION || nSBCode==SB_THUMBTRACK)
  846. m_bTrack = TRUE;
  847. else
  848. m_bTrack = FALSE;
  849. SendMessage(WM_PAINT, 0, 0);
  850. }
  851. void CSynEditView::GetSelection()
  852. {
  853. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  854. CHARRANGE cr;
  855. SynCtrl.GetSel( cr );
  856. m_ptStart = SynCtrl.GetCharPos( cr.cpMin );
  857. m_ptEnd = SynCtrl.GetCharPos( cr.cpMax );
  858. }
  859. BOOL CSynEditView::IsStrInSelection(int ptLeft, int ptTop, BOOL bleft)
  860. {
  861. if( m_ptStart == m_ptEnd ) //如果没有选定直接返回FALSE
  862. return FALSE;
  863. int nhalfcharwidth = m_nCharSpaceWidth/2;
  864. if(bleft) //如果判断当前点是否在选定区域的左边,则ptLeft应加nhalfcharwidth
  865. ptLeft+=nhalfcharwidth;
  866. else
  867. ptLeft-=nhalfcharwidth; //否则减nhalfcharwidth
  868. if( m_ptStart.y == m_ptEnd.y ) { //如果选定行为单行
  869. if( ptTop != m_ptStart.y ) //如果光标不在该行
  870. return FALSE;
  871. else {
  872. if( ptLeft >= m_ptStart.x && ptLeft <= m_ptEnd.x)
  873. return TRUE;
  874. else
  875. return FALSE;
  876. }
  877. }
  878. else {
  879. if( ptTop == m_ptStart.y ) { //如果当前位置在选取定行的第一行
  880. if( ptLeft < m_ptStart.x )
  881. return FALSE;
  882. else
  883. return TRUE;
  884. }
  885. if( ptTop == m_ptEnd.y ) { //如果当前位置在选定行的最后一行
  886. if( ptLeft < m_ptEnd.x )
  887. return TRUE;
  888. else
  889. return FALSE;
  890. }
  891. else if( ptTop > m_ptStart.y && ptTop < m_ptEnd.y ) //如果当前位置在选定行的中间
  892. return TRUE;
  893. else
  894. return FALSE;
  895. }
  896. }
  897. void CSynEditView::JudgeInSeletioAndDrawText(CDC *cacheDC, CRect &rcLine, CString &str, COLORREF clrBkColor, COLORREF clrText)
  898. {
  899. //*
  900. COLORREF clrSelText;
  901. int nFormat = DT_LEFT|DT_NOPREFIX|DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE|DT_RTLREADING;
  902. CSize size = cacheDC->GetTextExtent(str);
  903. int nOffsetY = (rcLine.Height()-size.cy)/2;
  904. if( !IsSelectionInStr(rcLine.left, size.cx, rcLine.top) ) {
  905. BOOL bStrLeft = IsStrInSelection( rcLine.left, rcLine.top, TRUE );
  906. BOOL bStrRight = IsStrInSelection( rcLine.left + size.cx, rcLine.top, FALSE );
  907. if( !bStrLeft && !bStrRight ) //如果str的左右都不在选定区域内
  908. {
  909. /* if(rcLine.top == m_ptEnd.y && rcLine.left == m_ptEnd.x)
  910. {
  911. //这段代码是画最后一行的选定区域标志
  912. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  913. int nLineCount = SynCtrl.GetLineCount();
  914. int nOffset = SynCtrl.LineIndex( nLineCount-1 );
  915. int nLineLength = SynCtrl.LineLength(nOffset);
  916. CPoint pt = SynCtrl.GetCharPos( nOffset+nLineLength );
  917. if(0 == nLineLength && pt == m_ptEnd)
  918. {
  919. CRect rect(rcLine);
  920. rect.right = rect.left + size.cx;
  921. cacheDC->FillSolidRect( &rect, m_clrBKSelText );
  922. rcLine.OffsetRect( size.cx, 0 );
  923. return;
  924. }
  925. }
  926. else
  927. {*/
  928. cacheDC->SetBkColor( clrBkColor );
  929. cacheDC->SetTextColor( clrText );
  930. cacheDC->TextOut( rcLine.left, rcLine.top+nOffsetY, str);
  931. rcLine.OffsetRect( size.cx, 0 );
  932. return;
  933. //}
  934. }
  935. else if( bStrLeft && bStrRight ) { //如果str的左右都在选定区域内
  936. CRect rect(rcLine);
  937. rect.right = rect.left + size.cx;
  938. cacheDC->FillSolidRect( &rect, m_clrBKSelText );
  939. clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
  940. cacheDC->SetTextColor( clrSelText );
  941. cacheDC->TextOut( rcLine.left, rcLine.top+nOffsetY, str);
  942. rcLine.OffsetRect( size.cx, 0 );
  943. return;
  944. }
  945. }
  946. //如果str部分在选定区域内, 或者选定区域在str内执行以下代码
  947. CString strChar;
  948. for( int nChar = 0; nChar < str.GetLength(); nChar++ ) {
  949. if(IsDBCSLeadByte(str[nChar]))
  950. {
  951. //如果是双字节字符如中文,则取该中文
  952. strChar = str.Mid( nChar, 2 );
  953. nChar++;
  954. }
  955. else
  956. {
  957. strChar = str.Mid( nChar, 1 );
  958. }
  959. size = cacheDC->GetTextExtent( strChar );
  960. BOOL bStrLeft = IsStrInSelection( rcLine.left, rcLine.top, TRUE );
  961. BOOL bStrRight = IsStrInSelection( rcLine.left + size.cx, rcLine.top, FALSE );
  962. if( bStrLeft && bStrRight ) {
  963. CRect rect(rcLine);
  964. rect.right = rect.left + size.cx;
  965. cacheDC->FillSolidRect( &rect, m_clrBKSelText );
  966. clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
  967. cacheDC->SetTextColor( clrSelText );
  968. }
  969. else {
  970. cacheDC->SetBkColor( clrBkColor );
  971. cacheDC->SetTextColor( clrText );
  972. }
  973. cacheDC->TextOut( rcLine.left, rcLine.top+nOffsetY, strChar);
  974. rcLine.OffsetRect( size.cx, 0 );
  975. }
  976. //*/
  977. /*
  978. COLORREF clrSelText;
  979. int nFormat = DT_LEFT|DT_NOPREFIX|DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE;
  980. CSize size = cacheDC->GetTextExtent(str);
  981. if( !IsSelectionInStr(rcLine.left, size.cx, rcLine.top) ) {
  982. //如果整个选定区域不在str内,则可能情况是str不在选定区域内、str在选定区域内、str部分在选定区域内
  983. BOOL bStrLeft = IsStrInSelection( rcLine.left, rcLine.top, TRUE );
  984. BOOL bStrRight = IsStrInSelection( rcLine.left + size.cx, rcLine.top, FALSE );
  985. if( !bStrLeft && !bStrRight ) { //如果str的左右都不在选定区域内
  986. cacheDC->SetBkColor( clrBkColor );
  987. cacheDC->SetTextColor( clrText );
  988. cacheDC->TextOut( rcLine.left, rcLine.top, str);
  989. rcLine.OffsetRect( size.cx, 0 );
  990. return;
  991. }
  992. else if( bStrLeft && bStrRight ) { //如果str的左右都在选定区域内
  993. CRect rect(rcLine);
  994. rect.right = rect.left + size.cx;
  995. cacheDC->FillSolidRect( &rect, m_clrBKSelText );
  996. clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
  997. cacheDC->SetTextColor( clrSelText );
  998. cacheDC->TextOut( rcLine.left, rcLine.top, str);
  999. rcLine.OffsetRect( size.cx, 0 );
  1000. return;
  1001. }
  1002. }
  1003. //如果选定区域在str中或str部分在选定区域中则往下做
  1004. //方法:将str按选定分为在块,中间一块为选定的文本,两边为没有选定的文本
  1005. if(str.IsEmpty())
  1006. return;
  1007. size = (0, 0);
  1008. CString strtmp;
  1009. int nleft, nright;
  1010. for( nleft = 0; nleft <= str.GetLength(); nleft++ ) {
  1011. if( rcLine.left + size.cx >= m_ptStart.x )
  1012. break;
  1013. strtmp = str.Left( nleft );
  1014. size = cacheDC->GetTextExtent( strtmp );
  1015. }
  1016. if(--nleft<0)
  1017. nleft = 0;
  1018. size = (0, 0);
  1019. for( nright = 0; nright <= str.GetLength(); nright++ ) {
  1020. if( rcLine.left + size.cx >= m_ptEnd.x )
  1021. break;
  1022. strtmp = str.Left( nright );
  1023. size = cacheDC->GetTextExtent( strtmp );
  1024. }
  1025. --nright;
  1026. //取最左的一块
  1027. strtmp = str.Left( nleft );
  1028. if(!strtmp.IsEmpty()) {
  1029. CRect rect(rcLine);
  1030. size = cacheDC->GetTextExtent( strtmp );
  1031. rect.right = rect.left + size.cx;
  1032. cacheDC->FillSolidRect( &rect, clrBkColor );
  1033. cacheDC->SetTextColor( clrText );
  1034. cacheDC->TextOut( rcLine.left, rcLine.top, str);
  1035. rcLine.OffsetRect( size.cx, 0 );
  1036. }
  1037. //取中间的一块
  1038. strtmp = str.Mid( nleft, nright - nleft );
  1039. if(!strtmp.IsEmpty()) {
  1040. CRect rect(rcLine);
  1041. size = cacheDC->GetTextExtent( strtmp );
  1042. rect.right = rect.left + size.cx;
  1043. clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
  1044. cacheDC->FillSolidRect( &rect, m_clrBKSelText );
  1045. cacheDC->SetTextColor( clrSelText );
  1046. cacheDC->TextOut( rcLine.left, rcLine.top, str);
  1047. rcLine.OffsetRect( size.cx, 0 );
  1048. }
  1049. //取最右的一块
  1050. strtmp = str.Mid( nright, str.GetLength() - nright );
  1051. if(!strtmp.IsEmpty()) {
  1052. CRect rect(rcLine);
  1053. size = cacheDC->GetTextExtent( strtmp );
  1054. rect.right = rect.left + size.cx;
  1055. cacheDC->FillSolidRect( &rect, clrBkColor );
  1056. cacheDC->SetTextColor( clrText );
  1057. cacheDC->TextOut( rcLine.left, rcLine.top, str);
  1058. rcLine.OffsetRect( size.cx, 0 );
  1059. }
  1060. //*/
  1061. }
  1062. //计算水平滚动位置,以便在水平滚动时可以正确显示
  1063. void CSynEditView::CalcHorzScrollPos()
  1064. {
  1065. if(m_nWrapMode == WrapToWindow)
  1066. {
  1067. m_nHorzPos = 0;
  1068. return;
  1069. }
  1070. SCROLLINFO si;
  1071. si.cbSize = sizeof(si);
  1072. GetScrollInfo(SB_HORZ, &si);
  1073. if( m_bTrack )
  1074. m_nHorzPos = si.nTrackPos;
  1075. else
  1076. m_nHorzPos = si.nPos;
  1077. }
  1078. void CSynEditView::DrawSynEditView()
  1079. {
  1080. if(!m_bAllowDraw)
  1081. return;
  1082. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1083. m_nLineCount = SynCtrl.GetLineCount();
  1084. m_nCurrentLine = GetCurrentLine();
  1085. int i = 0;
  1086. int nLineCount = m_nLineCount;
  1087. while(nLineCount!=0) {
  1088. i++;
  1089. nLineCount /= 10;
  1090. }
  1091. if(m_nLineNumberCharNumber!=i) {
  1092. m_nLineNumberCharNumber = i;
  1093. SetLeftMargin();
  1094. PostMessage(WM_PAINT);
  1095. }
  1096. if (m_pdwParseCookies != NULL)
  1097. {
  1098. if (m_nParseArraySize != m_nLineCount)
  1099. {
  1100. int nCurrentLine = m_nCurrentLine;
  1101. if(m_nParseArraySize < m_nLineCount) {
  1102. nCurrentLine = m_nParseArraySize + m_nCurrentLine - m_nLineCount;
  1103. if(nCurrentLine<0)
  1104. nCurrentLine = m_nCurrentLine;
  1105. }
  1106. if(m_nCurrentLine>m_nLineCount)
  1107. nCurrentLine=0;
  1108. // Reallocate cookies array
  1109. DWORD *pdwNewArray = new DWORD[m_nLineCount];
  1110. if (m_nCurrentLine > 0)
  1111. memcpy(pdwNewArray, m_pdwParseCookies, sizeof(DWORD) * nCurrentLine);
  1112. delete m_pdwParseCookies;
  1113. m_nParseArraySize = m_nLineCount;
  1114. m_pdwParseCookies = pdwNewArray;
  1115. memset(m_pdwParseCookies + nCurrentLine, 0xff, sizeof(DWORD) * (m_nParseArraySize - nCurrentLine));
  1116. }
  1117. }
  1118. CDC *pdc=GetDC();
  1119. CDC cacheDC;
  1120. VERIFY(cacheDC.CreateCompatibleDC(pdc));
  1121. if (m_pCacheBitmap == NULL)
  1122. {
  1123. m_pCacheBitmap = new CBitmap;
  1124. m_pCacheBitmap->CreateCompatibleBitmap(pdc, m_rcClient.Width(), m_rcClient.Height()); //nLineHeight);
  1125. }
  1126. CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
  1127. GetSelection();
  1128. CalcHorzScrollPos();
  1129. CString str;
  1130. int nLine = SynCtrl.GetFirstVisibleLine();
  1131. if(nLine==0)
  1132. m_bRealReturn = TRUE;
  1133. else
  1134. m_bRealReturn = GetLineString(nLine-1, str);
  1135. //将文本显示区域背景色画好
  1136. CRect rcRightText(m_rcClient);
  1137. rcRightText.left = m_nLeftMargin;
  1138. cacheDC.FillSolidRect(&rcRightText, m_clrBkColor);
  1139. rcRightText.left = m_nLeftMargin - m_nHorzPos;
  1140. int nLinesTop = GetLinesTop(nLine); //第一行要计算好偏移值,因为第一行可能只显示半行出来
  1141. int nLinesTopTemp = nLinesTop;
  1142. //*
  1143. rcRightText.top = nLinesTop;
  1144. rcRightText.bottom = nLinesTop + m_nLineHeight;
  1145. //calc the number ready to draw
  1146. int nNumberToDraw = 0;
  1147. while(nLinesTop <= m_rcClient.bottom ) {
  1148. if(nLine + nNumberToDraw > m_nLineCount-1)
  1149. break;
  1150. nLinesTop += m_nLineHeight;
  1151. ++nNumberToDraw;
  1152. }
  1153. for(i=0; i<nNumberToDraw; i++) {
  1154. DrawSingleLineColorText(&cacheDC, nLine+i, rcRightText);
  1155. rcRightText.OffsetRect(0, m_nLineHeight );
  1156. }
  1157. //将行号显示区域背景色画好
  1158. CRect rcLeftLineNumber(m_rcClient);
  1159. CRect rcLineNumberRight(m_rcClient);
  1160. if(m_bShowLineNumber) {
  1161. rcLeftLineNumber.right = m_nLeftMargin;
  1162. cacheDC.FillSolidRect(&rcLeftLineNumber, m_clrBkColor);
  1163. CPen NewPen(PS_SOLID, 1, m_clrLinNumberSep);
  1164. CPen *OldPen = cacheDC.SelectObject(&NewPen);
  1165. cacheDC.MoveTo(m_nLeftMargin - m_nDefaultLeftMargin, rcLeftLineNumber.top);
  1166. cacheDC.LineTo(m_nLeftMargin - m_nDefaultLeftMargin, rcLeftLineNumber.bottom);
  1167. cacheDC.SelectObject(OldPen);
  1168. rcLeftLineNumber.right = m_nLeftMargin - m_nDefaultLeftMargin;
  1169. cacheDC.FillSolidRect(&rcLeftLineNumber, m_clrLinNumberBkColor);
  1170. }
  1171. else {
  1172. rcLeftLineNumber.right = m_nDefaultLeftMargin;
  1173. cacheDC.FillSolidRect(&rcLeftLineNumber, m_clrBkColor);
  1174. }
  1175. rcLeftLineNumber.top = nLinesTopTemp;
  1176. rcLeftLineNumber.bottom = nLinesTopTemp + m_nLineHeight;
  1177. rcLeftLineNumber.right -= 2;
  1178. for(i=0; i<nNumberToDraw; i++) {
  1179. DrawLineNumber(&cacheDC, nLine+i, rcLeftLineNumber);
  1180. rcLeftLineNumber.OffsetRect(0, m_nLineHeight);
  1181. }
  1182. if(m_bShowCross)
  1183. DrawCross(&cacheDC);
  1184. pdc->BitBlt(m_rcClient.left, m_rcClient.top, m_rcClient.Width(), m_rcClient.Height(), &cacheDC, 0, 0, SRCCOPY);
  1185. cacheDC.SelectObject(pOldBitmap);
  1186. cacheDC.DeleteDC();
  1187. ReleaseDC(pdc);
  1188. }
  1189. void CSynEditView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1190. {
  1191. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1192. m_bAllowDraw = FALSE;
  1193. CHARRANGE cr;
  1194. SynCtrl.GetSel( cr );
  1195. CRichEditView::OnKeyDown(nChar, nRepCnt, nFlags);
  1196. if(cr.cpMax != cr.cpMin)
  1197. {
  1198. if(VK_DELETE==nChar || VK_BACK==nChar)
  1199. {
  1200. ReCalcCursorPostion();
  1201. }
  1202. }
  1203. /*
  1204. //放弃以下功能是因为ReCalcCursorPostion这个函数
  1205. if(nChar==VK_RETURN)
  1206. {
  1207. int nline = GetCurrentLine();
  1208. if(nline!=0)
  1209. {
  1210. CString strtmp, strline;
  1211. GetLineString(--nline, strline);
  1212. strtmp = strline;
  1213. strtmp.TrimLeft(0x20);
  1214. strtmp.TrimLeft(0x9);
  1215. int npos = strline.Find(strtmp);
  1216. if(npos!=0)
  1217. {
  1218. strtmp = strline.Left(npos);
  1219. SynCtrl.ReplaceSel(strtmp, TRUE);
  1220. }
  1221. }
  1222. }
  1223. //*/
  1224. m_bAllowDraw = TRUE;
  1225. GetSelection();
  1226. if(nChar == VK_LEFT || nChar == VK_RIGHT || nChar == VK_UP || nChar == VK_DOWN)
  1227. {
  1228. SendMessage(WM_PAINT, 0, 0);
  1229. }
  1230. SynCtrl.GetSel( cr );
  1231. if(cr.cpMin != cr.cpMax)
  1232. {
  1233. SendMessage(WM_PAINT, 0, 0);
  1234. }
  1235. else if (m_nCurrentLine != GetCurrentLine())
  1236. {
  1237. SendMessage(WM_PAINT, 0, 0);
  1238. }
  1239. int nHorzPos = m_nHorzPos;
  1240. CalcHorzScrollPos();
  1241. if(nHorzPos != m_nHorzPos)
  1242. {
  1243. SendMessage(WM_PAINT, 0, 0);
  1244. }
  1245. }
  1246. void CSynEditView::OnLButtonDown(UINT nFlags, CPoint point)
  1247. {
  1248. CRichEditView::OnLButtonDown(nFlags, point);
  1249. SendMessage(WM_PAINT, 0, 0);
  1250. }
  1251. void CSynEditView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  1252. {
  1253. CRichEditView::OnKeyUp(nChar, nRepCnt, nFlags);
  1254. SendMessage(WM_PAINT, 0, 0);
  1255. }
  1256. BOOL CSynEditView::IsSelectionInStr(int nFromHere, int nStrWidth, int nTop)
  1257. {
  1258. if( m_ptStart == m_ptEnd )
  1259. return FALSE;
  1260. if( m_ptStart.y != m_ptEnd.y ) //如果选定行不为单行,返回,因为字符不可能跨行
  1261. return FALSE;
  1262. if( m_ptStart.y != nTop ) //如果待测试行的顶部不等于选定行的顶部则返回
  1263. return FALSE;
  1264. if( (m_ptStart.x > nFromHere) && (m_ptEnd.x < nFromHere + nStrWidth) )
  1265. return TRUE;
  1266. else
  1267. return FALSE;
  1268. }
  1269. int CSynEditView::GetLanguage()
  1270. {
  1271. return m_nLanguage;
  1272. }
  1273. void CSynEditView::SetColor(int nColorIndex, COLORREF clrNew)
  1274. {
  1275. switch(nColorIndex) {
  1276. case COLORINDEX_BK:
  1277. m_clrBkColor = clrNew;
  1278. break;
  1279. case COLORINDEX_COMMENT:
  1280. m_clrCommentColor = clrNew;
  1281. break;
  1282. case COLORINDEX_SYNTAX:
  1283. m_clrSyntaxColor = clrNew;
  1284. break;
  1285. case COLORINDEX_NORMAL:
  1286. m_clrNormalColor = clrNew;
  1287. break;
  1288. case COLORINDEX_STRING:
  1289. m_clrStringColor = clrNew;
  1290. break;
  1291. case COLORINDEX_CHAR:
  1292. m_clrCharColor = clrNew;
  1293. break;
  1294. case COLORINDEX_NUMBER:
  1295. m_clrNumberColor = clrNew;
  1296. break;
  1297. case COLORINDEX_UNDERLINE:
  1298. m_clrUnderLine = clrNew;
  1299. break;
  1300. case COLORINDEX_LINEEND:
  1301. m_clrLineEnd = clrNew;
  1302. break;
  1303. case COLORINDEX_BKCURLINE:
  1304. m_clrBkCurLine = clrNew;
  1305. break;
  1306. case COLORINDEX_LINNUMBERBKCOLOR:
  1307. m_clrLinNumberBkColor = clrNew;
  1308. break;
  1309. case COLORINDEX_LINNUMBERNORMAL:
  1310. m_clrLinNumberNormal = clrNew;
  1311. break;
  1312. case COLORINDEX_CURLINNUMBER:
  1313. m_clrCurLinNumber = clrNew;
  1314. break;
  1315. case COLORINDEX_LINNUMBERSEP:
  1316. m_clrLinNumberSep = clrNew;
  1317. break;
  1318. case COLORINDEX_CROSS:
  1319. m_clrCross = clrNew;
  1320. break;
  1321. case COLORINDEX_TAB:
  1322. m_clrTab = clrNew;
  1323. break;
  1324. case COLORINDEX_BKSELTEXT:
  1325. m_clrBKSelText = clrNew;
  1326. break;
  1327. }
  1328. WriteSettings();
  1329. }
  1330. COLORREF CSynEditView::GetColor(int nColorIndex)
  1331. {
  1332. switch(nColorIndex) {
  1333. case COLORINDEX_BK:
  1334. return m_clrBkColor;
  1335. case COLORINDEX_COMMENT:
  1336. return m_clrCommentColor;
  1337. case COLORINDEX_SYNTAX:
  1338. return m_clrSyntaxColor;
  1339. case COLORINDEX_NORMAL:
  1340. return m_clrNormalColor;
  1341. case COLORINDEX_STRING:
  1342. return m_clrStringColor;
  1343. case COLORINDEX_CHAR:
  1344. return m_clrCharColor;
  1345. case COLORINDEX_NUMBER:
  1346. return m_clrNumberColor;
  1347. case COLORINDEX_UNDERLINE:
  1348. return m_clrUnderLine;
  1349. case COLORINDEX_LINEEND:
  1350. return m_clrLineEnd;
  1351. case COLORINDEX_BKCURLINE:
  1352. return m_clrBkCurLine;
  1353. case COLORINDEX_LINNUMBERBKCOLOR:
  1354. return m_clrLinNumberBkColor;
  1355. case COLORINDEX_LINNUMBERNORMAL:
  1356. return m_clrLinNumberNormal;
  1357. case COLORINDEX_CURLINNUMBER:
  1358. return m_clrCurLinNumber;
  1359. case COLORINDEX_LINNUMBERSEP:
  1360. return m_clrLinNumberSep;
  1361. case COLORINDEX_CROSS:
  1362. return m_clrCross;
  1363. case COLORINDEX_TAB:
  1364. return m_clrTab;
  1365. case COLORINDEX_BKSELTEXT:
  1366. return m_clrBKSelText;
  1367. default:
  1368. return m_clrNormalColor;
  1369. }
  1370. }
  1371. void CSynEditView::ReadColorInfo(int nLanguage)
  1372. {
  1373. CString strColorPos = _T("icrEdit_Color");
  1374. strColorPos += GetLanguageString(nLanguage);
  1375. CWinApp *app = AfxGetApp();
  1376. m_clrBkColor = app->GetProfileInt( strColorPos, _T("m_clrBkColor"), RGB(255, 255, 255));
  1377. m_clrCommentColor = app->GetProfileInt( strColorPos, _T("m_clrCommentColor"), RGB(0, 128, 0));
  1378. m_clrSyntaxColor = app->GetProfileInt( strColorPos, _T("m_clrSyntaxColor"), RGB(0, 0, 255));
  1379. m_clrNormalColor = app->GetProfileInt( strColorPos, _T("m_clrNormalColor"), RGB(0, 0, 0));
  1380. m_clrStringColor = app->GetProfileInt( strColorPos, _T("m_clrStringColor"), RGB(128, 0, 0));
  1381. m_clrCharColor = app->GetProfileInt( strColorPos, _T("m_clrCharColor"), RGB(128, 0, 0));
  1382. m_clrNumberColor = app->GetProfileInt( strColorPos, _T("m_clrNumberColor"), RGB(255, 0, 0));
  1383. m_clrUnderLine = app->GetProfileInt( strColorPos, _T("m_clrUnderLine"), RGB(200, 200, 200));
  1384. m_clrLineEnd = app->GetProfileInt( strColorPos, _T("m_clrLineEnd"), RGB(0, 0, 200));
  1385. m_clrBkCurLine = app->GetProfileInt( strColorPos, _T("m_clrBkCurLine"), RGB(200, 200, 200));
  1386. m_clrLinNumberBkColor = app->GetProfileInt( strColorPos, _T("m_clrLinNumberBkColor"), RGB(255, 255, 255));
  1387. m_clrLinNumberNormal = app->GetProfileInt( strColorPos, _T("m_clrLinNumberNormal"), RGB(192, 192, 192));
  1388. m_clrCurLinNumber = app->GetProfileInt( strColorPos, _T("m_clrCurLinNumber"), RGB(0, 0, 128));
  1389. m_clrLinNumberSep = app->GetProfileInt( strColorPos, _T("m_clrLinNumberSep"), RGB(192, 192, 192));
  1390. m_clrCross = app->GetProfileInt( strColorPos, _T("m_clrCross"), RGB(0, 0, 128));
  1391. m_clrTab = app->GetProfileInt( strColorPos, _T("m_clrTab"), RGB(128, 128, 128));
  1392. m_clrBKSelText = app->GetProfileInt( strColorPos, _T("m_clrBKSelText"), RGB(0, 0, 128));
  1393. }
  1394. BOOL CSynEditView::IsShowLineNumber()
  1395. {
  1396. return m_bShowLineNumber;
  1397. }
  1398. BOOL CSynEditView::IsShowSelectLine()
  1399. {
  1400. return m_bShowSelectLine;
  1401. }
  1402. BOOL CSynEditView::IsShowUnderLine()
  1403. {
  1404. return m_bShowUnderLine;
  1405. }
  1406. BOOL CSynEditView::IsShowReturnLineToken()
  1407. {
  1408. return m_bShowReturnLineToken;
  1409. }
  1410. int CSynEditView::GetTabSize()
  1411. {
  1412. return m_nTabSize;
  1413. }
  1414. CString CSynEditView::GetSingleCommentString(int nlanguage)
  1415. {
  1416. return GetLineCommentString(nlanguage);
  1417. }
  1418. void CSynEditView::DrawReturnLineToken(BOOL bRealReturn, CDC *cacheDC, CRect &rcline)
  1419. {
  1420. rcline.OffsetRect(-m_nCharSpaceWidth-2, 0);
  1421. int nlineheight = rcline.Height();
  1422. int nleft = rcline.left;
  1423. int ntop = rcline.top + nlineheight/4 + 1 ;
  1424. int nbottom = rcline.bottom - nlineheight/4;
  1425. if(bRealReturn) {
  1426. for(int i=ntop; i<nbottom; i++)
  1427. cacheDC->SetPixel( nleft + 5, i+1, m_clrLineEnd );
  1428. cacheDC->SetPixel( nleft + 2, nbottom - 3, m_clrLineEnd );
  1429. cacheDC->SetPixel( nleft + 3, nbottom - 2, m_clrLineEnd );
  1430. cacheDC->SetPixel( nleft + 4, nbottom - 1, m_clrLineEnd );
  1431. cacheDC->SetPixel( nleft + 6, nbottom - 1, m_clrLineEnd );
  1432. cacheDC->SetPixel( nleft + 7, nbottom - 2, m_clrLineEnd );
  1433. cacheDC->SetPixel( nleft + 8, nbottom - 3, m_clrLineEnd );
  1434. }
  1435. else {
  1436. int nhalfline = rcline.top + nlineheight/2;
  1437. for(int i=nleft+2; i<nleft+8; i++)
  1438. cacheDC->SetPixel( i, nhalfline, m_clrLineEnd );
  1439. cacheDC->SetPixel( nleft + 7, nhalfline-1, m_clrLineEnd );
  1440. cacheDC->SetPixel( nleft + 7, nhalfline+1, m_clrLineEnd );
  1441. cacheDC->SetPixel( nleft + 6, nhalfline-2, m_clrLineEnd );
  1442. cacheDC->SetPixel( nleft + 6, nhalfline+2, m_clrLineEnd );
  1443. cacheDC->SetPixel( nleft + 5, nhalfline-3, m_clrLineEnd );
  1444. cacheDC->SetPixel( nleft + 5, nhalfline+3, m_clrLineEnd );
  1445. }
  1446. }
  1447. void CSynEditView::GetSelLine(int &nfirstline, int &nendline)
  1448. {
  1449. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1450. CHARRANGE cr;
  1451. SynCtrl.GetSel( cr );
  1452. //计算选定区域的第一行和最后一行
  1453. nfirstline = SynCtrl.LineFromChar(cr.cpMin);
  1454. nendline = SynCtrl.LineFromChar(cr.cpMax);
  1455. if(SynCtrl.LineFromChar(cr.cpMax-1)<nendline)
  1456. --nendline;
  1457. if(nendline<nfirstline)
  1458. nendline = nfirstline;
  1459. //////////////////////////////////
  1460. }
  1461. BOOL CSynEditView::IsReadOnly()
  1462. {
  1463. return m_bReadOnly;
  1464. }
  1465. void CSynEditView::SetReadOnly(BOOL bReadOnly)
  1466. {
  1467. m_bReadOnly = bReadOnly;
  1468. GetRichEditCtrl().SetReadOnly(m_bReadOnly);
  1469. WriteSettings();
  1470. }
  1471. //这个函数的作用是在粘贴时重置行nParseArraySize的语法解析缓冲区, 调用位置在CMainFrame的粘贴处理函数
  1472. void CSynEditView::SetParseCookieZeroFromGivenLine(int nParseArraySize)
  1473. {
  1474. memset(m_pdwParseCookies + nParseArraySize, 0xff, sizeof(DWORD) * (m_nParseArraySize - nParseArraySize));
  1475. }
  1476. int CSynEditView::GetUndoLimits()
  1477. {
  1478. return m_nUndoLimits;
  1479. }
  1480. void CSynEditView::SetUndoLimits(int nMax)
  1481. {
  1482. m_nUndoLimits = nMax;
  1483. SendMessage(EM_SETUNDOLIMIT, m_nUndoLimits, 0);
  1484. WriteSettings();
  1485. }
  1486. BOOL CSynEditView::IsAutoWordSelect()
  1487. {
  1488. const DWORD eco = SendMessage(EM_GETOPTIONS, 0, 0);
  1489. if(eco & ECO_AUTOWORDSELECTION)
  1490. return TRUE;
  1491. else
  1492. return FALSE;
  1493. }
  1494. void CSynEditView::SetAutoWordSelect(BOOL bAutoSelect)
  1495. {
  1496. if(IsAutoWordSelect()) {
  1497. if(!bAutoSelect)
  1498. SendMessage(EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOWORDSELECTION);
  1499. }
  1500. else {
  1501. if(bAutoSelect)
  1502. SendMessage(EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOWORDSELECTION);
  1503. }
  1504. }
  1505. void CSynEditView::DrawCross(CDC *cacheDC)
  1506. {
  1507. if(m_ptStart!=m_ptEnd)
  1508. return;
  1509. CPen NewPen(PS_SOLID, 1, m_clrCross);
  1510. CPen *OldPen = cacheDC->SelectObject(&NewPen);
  1511. cacheDC->MoveTo(m_nLeftMargin, m_ptStart.y+m_nLineHeight);
  1512. cacheDC->LineTo(m_rcClient.Width(), m_ptStart.y+m_nLineHeight);
  1513. cacheDC->MoveTo(m_ptStart.x, 0);
  1514. cacheDC->LineTo(m_ptStart.x, m_rcClient.Height());
  1515. cacheDC->SelectObject(OldPen);
  1516. }
  1517. void CSynEditView::ShowCross(BOOL bShow)
  1518. {
  1519. m_bShowCross = bShow;
  1520. }
  1521. BOOL CSynEditView::IsShowCross()
  1522. {
  1523. return m_bShowCross;
  1524. }
  1525. void CSynEditView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1526. {
  1527. InvalidateRect(m_rcClient, FALSE);
  1528. m_bAllowDraw = FALSE;
  1529. CRichEditView::OnVScroll(nSBCode, nPos, pScrollBar);
  1530. m_bAllowDraw = TRUE;
  1531. ValidateRect(m_rcClient);
  1532. SendMessage(WM_PAINT, 0, 0);
  1533. }
  1534. BOOL CSynEditView::IsShowTabSpace()
  1535. {
  1536. return m_bShowTab;
  1537. }
  1538. void CSynEditView::ShowTabSpace(BOOL bShow)
  1539. {
  1540. m_bShowTab = bShow;
  1541. }
  1542. int CSynEditView::GetVisibleLineCount()
  1543. {
  1544. return m_rcClient.Height() / m_nLineHeight;
  1545. }
  1546. int CSynEditView::GetSpaceWidth()
  1547. {
  1548. return m_nCharSpaceWidth;
  1549. }
  1550. void CSynEditView::OnPaint()
  1551. {
  1552. CPaintDC dc(this); // device context for painting
  1553. DrawSynEditView();
  1554. // Do not call CRichEditView::OnPaint() for painting messages
  1555. }
  1556. void CSynEditView::InitEditorFont()
  1557. {
  1558. SetWindowText(""); //此行不必要,因为初始化时内容必为空,同时会引导致启动程序时内容为空
  1559. SetSynEditViewFont(m_lf); //不会改文本内容
  1560. //将tab宽设置好
  1561. SetSynCtrlTabSize(m_nTabSize); //不会改文本内容
  1562. /////////////////
  1563. //EM_SETTEXTMODE必须要内容为空时才有效
  1564. SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT|TM_MULTILEVELUNDO|TM_SINGLECODEPAGE, 0);
  1565. }
  1566. void CSynEditView::OnSetFocus(CWnd* pOldWnd)
  1567. {
  1568. CRichEditView::OnSetFocus(pOldWnd);
  1569. SendMessage(WM_PAINT, 0, 0);
  1570. }
  1571. //从RichEditCtrl中流出文本
  1572. //文本流入到RichEditCtrl中
  1573. //dwCookie - 送入的一段文本的首地址,文本长度通常为2k
  1574. //pbBuff - 可以理解为RichEditCtrl的文本缓冲区
  1575. //cb - 送来的文本长度,通常为2k
  1576. //pcb - 送入的文本长度,将会回调给RichEditCtrl
  1577. DWORD CALLBACK EditStreamCallbackOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  1578. {
  1579. /*
  1580. //下面的代码来自MFC Programmer's SourceBook
  1581. As noted in Article ID: Q136810 of Microsoft Knowlage Base: The EditStreamCallback
  1582. function is called until *pcb receives a zero value.
  1583. I found this problem only appear when work with win9x (in win2k EditStreamCallback
  1584. never called again for normal text if *pcb gets value less than cb)
  1585. So you can use next techniques for stream in (& out ) normal text:
  1586. */
  1587. CString* strWholeString = reinterpret_cast<CString*>(dwCookie);
  1588. // I hope this allocation/deallocation better then manipulation with CStrings
  1589. char* szInThisCall = new char[cb+1];
  1590. memcpy( szInThisCall, reinterpret_cast<char*>(pbBuff), cb );
  1591. szInThisCall[cb] = '\0';
  1592. // This is the main trik! Control can call this function for just a part of string!
  1593. (*strWholeString ) += szInThisCall;
  1594. delete [] szInThisCall;
  1595. *pcb = cb;
  1596. return 0;
  1597. }
  1598. void CSynEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  1599. {
  1600. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1601. CHARRANGE cr;
  1602. SynCtrl.GetSel( cr );
  1603. CRichEditView::OnChar(nChar, nRepCnt, nFlags);
  1604. if(cr.cpMax != cr.cpMin)
  1605. {
  1606. ReCalcCursorPostion();
  1607. }
  1608. else
  1609. {
  1610. SCROLLINFO si;
  1611. si.cbSize = sizeof(si);
  1612. GetScrollInfo(SB_HORZ, &si);
  1613. m_nHorzMaxOld = si.nMax;
  1614. }
  1615. }
  1616. void CSynEditView::ReCalcCursorPostion()
  1617. {
  1618. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1619. SCROLLINFO si;
  1620. si.cbSize = sizeof(si);
  1621. GetScrollInfo(SB_HORZ, &si);
  1622. if(si.nMax != m_nHorzMaxOld)
  1623. {
  1624. m_nHorzMaxOld = si.nMax;
  1625. SendMessage(WM_KEYDOWN, 0xd, 0);
  1626. SendMessage(WM_KEYDOWN, VK_BACK, 0);
  1627. if(GetCurrentLine()!=0)
  1628. {
  1629. SendMessage(WM_KEYDOWN, VK_UP, 0);
  1630. SendMessage(WM_KEYDOWN, VK_DOWN, 0);
  1631. }
  1632. if(GetCurrentLine()!=SynCtrl.GetLineCount()-1)
  1633. {
  1634. SendMessage(WM_KEYDOWN, VK_DOWN, 0);
  1635. SendMessage(WM_KEYDOWN, VK_UP, 0);
  1636. }
  1637. }
  1638. }
  1639. LRESULT CSynEditView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  1640. {
  1641. CHARRANGE cr;
  1642. if(WM_IME_CHAR == message)
  1643. {
  1644. CRichEditCtrl &SynCtrl = GetRichEditCtrl();
  1645. SynCtrl.GetSel( cr );
  1646. }
  1647. LRESULT lr = CRichEditView::WindowProc(message, wParam, lParam);
  1648. if(WM_IME_CHAR == message)
  1649. {
  1650. if(cr.cpMax != cr.cpMin)
  1651. {
  1652. ReCalcCursorPostion();
  1653. }
  1654. else
  1655. {
  1656. SCROLLINFO si;
  1657. si.cbSize = sizeof(si);
  1658. GetScrollInfo(SB_HORZ, &si);
  1659. m_nHorzMaxOld = si.nMax;
  1660. }
  1661. }
  1662. return lr;
  1663. }