CGuiEditView.cpp
上传用户:wlkj888
上传日期:2022-08-01
资源大小:806k
文件大小:14k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------//
  2. // This is a part of the GuiLib MFC Extention.  //
  3. // Modified  :  Francisco Campos  //
  4. // (C) 2002 Francisco Campos <www.beyondata.com> All rights reserved     //
  5. // This code is provided "as is", with absolutely no warranty expressed  //
  6. // or implied. Any use is at your own risk.  //
  7. // You must obtain the author's consent before you can include this code //
  8. // in a software library.  //
  9. // If the source code in  this file is used in any application  //
  10. // then acknowledgement must be made to the author of this program  //
  11. // fcampos@tutopia.com  //
  12. //-----------------------------------------------------------------------//
  13. // Copyright (C) 1998 by Juraj Rojko jrojko@twist.cz
  14. // All rights reserved
  15. //
  16. #include "stdafx.h"
  17. #include "CGuiEditView.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CGuiEditView
  25. IMPLEMENT_DYNCREATE(CGuiEditView, CRichEditView)
  26. BEGIN_MESSAGE_MAP(CGuiEditView, CRichEditView)
  27. //{{AFX_MSG_MAP(CGuiEditView)
  28. ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
  29. ON_WM_CREATE()
  30. //}}AFX_MSG_MAP
  31. // Standard printing commands
  32. ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
  33. ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
  34. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
  35. ON_NOTIFY_REFLECT(EN_PROTECTED, OnProtected)
  36. ON_MESSAGE(WM_SETTEXT, OnSetText)
  37. END_MESSAGE_MAP()
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CGuiEditView construction/destruction
  40. CGuiEditView::CGuiEditView()
  41. {
  42. m_chComment = 1;
  43. m_bCaseSensitive = FALSE;
  44. m_bChangeCase = TRUE;
  45. SetStringQuotes(_T("""));
  46. SetKeywordColor(RGB(0,0,255), FALSE);
  47. SetConstantColor(RGB(0,0,0), TRUE);
  48. SetCommentColor(RGB(0,128,0), FALSE);
  49. SetNumberColor(RGB(255,0,255), FALSE);
  50. SetStringColor(RGB(255,0,255), FALSE);
  51. m_bInForcedChange = FALSE;
  52. m_changeType = ctUndo;
  53. m_crOldSel.cpMin = m_crOldSel.cpMax = 0;
  54. }
  55. CGuiEditView::~CGuiEditView()
  56. {
  57. }
  58. BOOL CGuiEditView::PreCreateWindow(CREATESTRUCT& cs)
  59. {
  60. // TODO: Modify the Window class or styles here by modifying
  61. //  the CREATESTRUCT cs
  62. return CRichEditView::PreCreateWindow(cs);
  63. }
  64. void CGuiEditView::OnInitialUpdate()
  65. {
  66. // Set the printing margins (720 twips = 1/2 inch).
  67. SetMargins(CRect(720, 720, 720, 720));
  68. CRichEditView::OnInitialUpdate();
  69. }
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CGuiEditView printing
  72. BOOL CGuiEditView::OnPreparePrinting(CPrintInfo* pInfo)
  73. {
  74. // default preparation
  75. return DoPreparePrinting(pInfo);
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. // CGuiEditView diagnostics
  79. #ifdef _DEBUG
  80. void CGuiEditView::AssertValid() const
  81. {
  82. CRichEditView::AssertValid();
  83. }
  84. void CGuiEditView::Dump(CDumpContext& dc) const
  85. {
  86. CRichEditView::Dump(dc);
  87. }
  88. CVBScriptEditorDoc* CGuiEditView::GetDocument() // non-debug version is inline
  89. {
  90. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVBScriptEditorDoc)));
  91. return (CVBScriptEditorDoc*)m_pDocument;
  92. }
  93. #endif //_DEBUG
  94. /////////////////////////////////////////////////////////////////////////////
  95. // CGuiEditView message handlers
  96. void CGuiEditView::Initialize() 
  97. {
  98. PARAFORMAT2 pf;
  99. pf.cbSize = sizeof(PARAFORMAT);
  100. pf.dwMask = PFM_TABSTOPS ;
  101. pf.cTabCount = MAX_TAB_STOPS;
  102. for( int itab = 0 ; itab < pf.cTabCount  ; itab++ )
  103. pf.rgxTabs[itab] = (itab + 1) * 1440/5 ;
  104. SetParaFormat( pf );
  105. CHARFORMAT cfDefault;
  106. cfDefault.cbSize = sizeof(cfDefault);
  107. cfDefault.dwEffects = CFE_PROTECTED; 
  108. cfDefault.dwMask = CFM_BOLD | CFM_FACE | CFM_SIZE | CFM_CHARSET | CFM_PROTECTED;
  109. cfDefault.yHeight = 200;
  110. cfDefault.bCharSet = 0xEE; 
  111. strcpy(cfDefault.szFaceName, _T("Courier New")); 
  112. GetRichEditCtrl().SetDefaultCharFormat(cfDefault);
  113. GetRichEditCtrl().SetEventMask(ENM_CHANGE | ENM_SELCHANGE | ENM_PROTECTED);
  114. }
  115. void CGuiEditView::SetSLComment(TCHAR chComment, TCHAR chComment2)
  116. {
  117. m_chComment = chComment;
  118. m_chComment2 = chComment2;
  119. }
  120. void CGuiEditView::SetSLComment(LPCTSTR lpszComment)
  121. {
  122. m_strComment = lpszComment;
  123. }
  124. void CGuiEditView::AddKeywords(LPCTSTR lpszKwd)
  125. {
  126. m_strKeywords = m_strKeywords + lpszKwd;
  127. m_strKeywordsLower = m_strKeywords;
  128. if (!m_bCaseSensitive)
  129. m_strKeywordsLower.MakeLower();
  130. }
  131. void CGuiEditView::ClearKeywords()
  132. {
  133. m_strKeywords.Empty();
  134. m_strKeywordsLower.Empty();
  135. }   
  136. void CGuiEditView::AddConstants(LPCTSTR lpszConst)
  137. {
  138. m_strConstants = m_strConstants + lpszConst;
  139. m_strConstantsLower = m_strConstants;
  140. if (!m_bCaseSensitive)
  141. m_strConstantsLower.MakeLower();
  142. }
  143. void CGuiEditView::ClearConstants()
  144. {
  145. m_strConstants.Empty();
  146. m_strConstantsLower.Empty();
  147. }   
  148. void CGuiEditView::SetCaseSensitive(BOOL bSensitive)
  149. {
  150. m_bCaseSensitive = bSensitive;
  151. }
  152. void CGuiEditView::SetChangeCase(BOOL bChange)
  153. {
  154. m_bChangeCase = bChange;
  155. }
  156. void CGuiEditView::SetStringQuotes(LPCTSTR lpszStrQ)
  157. {
  158. m_strStringQuotes = lpszStrQ;
  159. }
  160. void CGuiEditView::SetKeywordColor(COLORREF clr, BOOL bBold)
  161. {
  162. m_icKeyword.clrColor = clr;
  163. m_icKeyword.bBold = bBold;
  164. }
  165. void CGuiEditView::SetConstantColor(COLORREF clr, BOOL bBold)
  166. {
  167. m_icConstant.clrColor = clr;
  168. m_icConstant.bBold = bBold;
  169. }
  170. void CGuiEditView::SetCommentColor(COLORREF clr, BOOL bBold)
  171. {
  172. m_icComment.clrColor = clr;
  173. m_icComment.bBold = bBold;
  174. }
  175. void CGuiEditView::SetNumberColor(COLORREF clr, BOOL bBold)
  176. {
  177. m_icNumber.clrColor = clr;
  178. m_icNumber.bBold = bBold;
  179. }
  180. void CGuiEditView::SetStringColor(COLORREF clr, BOOL bBold)
  181. {
  182. m_icString.clrColor = clr;
  183. m_icString.bBold = bBold;
  184. }
  185. int CGuiEditView::IsKeyword(LPCTSTR lpszSymbol)
  186. {
  187. CString strSymbol; strSymbol.Format(" %s ", lpszSymbol);
  188. if (!m_bCaseSensitive) 
  189. strSymbol.MakeLower();
  190. return m_strKeywordsLower.Find(strSymbol);
  191. }
  192. int CGuiEditView::IsConstant(LPCTSTR lpszSymbol)
  193. {
  194. CString strSymbol; strSymbol.Format(" %s ", lpszSymbol);
  195. if (!m_bCaseSensitive) 
  196. strSymbol.MakeLower();
  197. return m_strConstantsLower.Find(strSymbol);
  198. }
  199. BOOL CGuiEditView::IsStringQuote(TCHAR ch)
  200. {
  201. return (m_strStringQuotes.Find(ch) >= 0);
  202. }
  203. void CGuiEditView::SetFormatRange(int nStart, int nEnd, BOOL bBold, COLORREF clr)
  204. {
  205. if (nStart >= nEnd)
  206. return;
  207. GetRichEditCtrl().SetSel(nStart, nEnd);
  208. DWORD dwEffects = bBold?CFE_BOLD:0;
  209. CHARFORMAT cfm;
  210. cfm.cbSize = sizeof(cfm);
  211.     GetRichEditCtrl().GetSelectionCharFormat(cfm);
  212. if ((cfm.dwMask & CFM_COLOR)  && cfm.crTextColor == clr && 
  213. (cfm.dwMask & CFM_BOLD) && (cfm.dwEffects & CFE_BOLD) == dwEffects)
  214. return;
  215. cfm.dwEffects = dwEffects;
  216. cfm.crTextColor = clr;
  217. cfm.dwMask = CFM_BOLD | CFM_COLOR;
  218. GetRichEditCtrl().SetSelectionCharFormat(cfm);
  219. }
  220. void CGuiEditView::ChangeCase(int nStart, int nEnd, LPCTSTR lpsz)
  221. {
  222. ASSERT((nEnd - nStart) == (int)_tcslen(lpsz));
  223. if (!m_bCaseSensitive && m_bChangeCase) {
  224. GetRichEditCtrl().SetSel(nStart, nEnd);
  225. GetRichEditCtrl().ReplaceSel(lpsz);
  226. }
  227. }
  228. void CGuiEditView::FormatTextRange(int nStart, int nEnd)
  229. {
  230. if (nStart >= nEnd)
  231. return;
  232. m_bInForcedChange = TRUE;
  233. CHARRANGE crOldSel;
  234. GetRichEditCtrl().GetSel(crOldSel);
  235. LockWindowUpdate();
  236. GetRichEditCtrl().HideSelection(TRUE, FALSE);
  237. TCHAR *pBuffer = NULL;
  238. try {
  239. GetRichEditCtrl().SetSel(nStart, nEnd);
  240. pBuffer = new TCHAR[nEnd - nStart + 1];
  241. long nLen = GetRichEditCtrl().GetSelText(pBuffer);
  242. ASSERT(nLen <= nEnd - nStart);
  243. pBuffer[nLen] = 0;
  244. TCHAR *pStart, *pPtr;
  245. pStart = pPtr = pBuffer;
  246. TCHAR* pSymbolStart = NULL;
  247. SymbolColor ic;
  248. while (*pPtr != 0) {
  249. TCHAR ch = *pPtr;
  250. if (ch == m_chComment && (m_chComment2 == 0 || pPtr[1] == m_chComment2)) {
  251. pSymbolStart = pPtr;
  252. do {
  253. ch = *(++pPtr);
  254. } while (ch != 0 && ch != 'r');
  255. ic = m_icComment;
  256. } else if (IsStringQuote(ch)) { // Process strings
  257. pSymbolStart = pPtr;
  258. TCHAR ch1 = ch;
  259. do {
  260. ch = *(++pPtr);
  261. } while (ch != 0 && ch != ch1 && ch != 'r');
  262. if (ch == ch1) pPtr++;
  263. ic = m_icString;
  264. } else if (_istdigit(ch)) { // Process numbers
  265. pSymbolStart = pPtr;
  266. _tcstod(pSymbolStart, &pPtr);
  267. ic = m_icNumber;
  268. } else if (_istalpha(ch) || ch == '_') { // Process keywords
  269. pSymbolStart = pPtr;
  270. do {
  271. ch = *(++pPtr);
  272. } while (_istalnum(ch) || ch == '_');
  273. *pPtr = 0;
  274. int nPos = IsKeyword(pSymbolStart);
  275. if (nPos >= 0) {
  276. ChangeCase(nStart + pSymbolStart - pBuffer, nStart + pPtr - pBuffer, 
  277. m_strKeywords.Mid(nPos+1, pPtr - pSymbolStart));
  278. if (_tcsicmp(m_strComment, pSymbolStart) == 0) {
  279. *pPtr = ch;
  280. *pSymbolStart = m_chComment;
  281. if (pSymbolStart[1] != 0 && m_chComment2 != 0)
  282. pSymbolStart[1] = m_chComment2;
  283. pPtr = pSymbolStart;
  284. pSymbolStart = NULL;
  285. continue;
  286. }
  287. ic = m_icKeyword;
  288. } else {
  289. nPos = IsConstant(pSymbolStart);
  290. if (nPos >= 0) {
  291. ChangeCase(nStart + pSymbolStart - pBuffer, nStart + pPtr - pBuffer, 
  292. m_strConstants.Mid(nPos+1, pPtr - pSymbolStart));
  293. ic = m_icConstant;
  294. } else {
  295. pSymbolStart = NULL;
  296. }
  297. }
  298. *pPtr = ch;
  299. } else {
  300. pPtr++;
  301. }
  302. if (pSymbolStart != NULL) {
  303. ASSERT(pSymbolStart < pPtr);
  304. SetFormatRange(nStart + pStart - pBuffer, nStart + pSymbolStart - pBuffer, FALSE, RGB(0,0,0));
  305. SetFormatRange(nStart + pSymbolStart - pBuffer, nStart + pPtr - pBuffer, ic.bBold, ic.clrColor);
  306. pStart = pPtr;
  307. pSymbolStart = 0;
  308. } else if (*pPtr == 0)
  309. SetFormatRange(nStart + pStart - pBuffer, nStart + pPtr - pBuffer, FALSE, RGB(0,0,0));
  310. }
  311. } catch(...){}
  312. delete [] pBuffer;
  313. GetRichEditCtrl().SetSel(crOldSel);
  314. GetRichEditCtrl().HideSelection(FALSE, FALSE);
  315. UnlockWindowUpdate();
  316. m_bInForcedChange = FALSE;
  317. }
  318. void CGuiEditView::FormatTextLines(int nLineStart, int nLineEnd)
  319. {
  320. long nStart = GetRichEditCtrl().LineIndex(GetRichEditCtrl().LineFromChar(nLineStart));
  321. long nEnd = GetRichEditCtrl().LineIndex(GetRichEditCtrl().LineFromChar(nLineEnd));
  322. nEnd += GetRichEditCtrl().LineLength(nLineEnd);
  323. FormatTextRange(nStart, nEnd);
  324. }
  325. void CGuiEditView::FormatAll()
  326. {
  327. FormatTextRange(0, GetTextLength());
  328. }
  329. LRESULT CGuiEditView::OnSetText(WPARAM wParam, LPARAM lParam)
  330. {
  331. LRESULT res = Default();
  332. //FormatAll();
  333. return res;
  334. }
  335. void CGuiEditView::OnChange() 
  336. {
  337. if (m_bInForcedChange)
  338. return;
  339. CHARRANGE crCurSel; 
  340. GetRichEditCtrl().GetSel(crCurSel);
  341. if (m_changeType == ctMove && crCurSel.cpMin == crCurSel.cpMax) {
  342. // cut was canceled, so this is paste operation
  343. m_changeType = ctPaste;
  344. }
  345. switch(m_changeType) {
  346. case ctReplSel:// old=(x,y) -> cur=(x+len,x+len)
  347. case ctPaste:  // old=(x,y) -> cur=(x+len,x+len)
  348. FormatTextLines(m_crOldSel.cpMin, crCurSel.cpMax);
  349. break;
  350. case ctDelete: // old=(x,y) -> cur=(x,x)
  351. case ctBack:   // old=(x,y) -> cur=(x,x), newline del => old=(x,x+1) -> cur=(x-1,x-1)
  352. case ctCut:    // old=(x,y) -> cur=(x,x)
  353. FormatTextLines(crCurSel.cpMin, crCurSel.cpMax);
  354. break;
  355. case ctUndo:   // old=(?,?) -> cur=(x,y)
  356. FormatTextLines(crCurSel.cpMin, crCurSel.cpMax);
  357. break;
  358. case ctMove:   // old=(x,x+len) -> cur=(y-len,y) | cur=(y,y+len)
  359. FormatTextLines(crCurSel.cpMin, crCurSel.cpMax);
  360. if (crCurSel.cpMin > m_crOldSel.cpMin) // move after
  361. FormatTextLines(m_crOldSel.cpMin, m_crOldSel.cpMin);
  362. else // move before
  363. FormatTextLines(m_crOldSel.cpMax, m_crOldSel.cpMax);
  364. break;
  365. default:
  366. FormatAll();
  367. break;
  368. }
  369. //undo action does not call OnProtected, so make it default
  370. m_changeType = ctUndo;
  371. }
  372. void CGuiEditView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
  373. {
  374. ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
  375. // determine type of change will occur
  376. switch (pEP->msg) {
  377. case WM_KEYDOWN:
  378. switch (pEP->wParam) {
  379. case VK_DELETE:
  380. m_changeType = ctDelete;
  381. break;
  382. case VK_BACK:
  383. m_changeType = ctBack;
  384. break;
  385. default:
  386. m_changeType = ctUnknown;
  387. break;
  388. }
  389. break;
  390. case EM_REPLACESEL:
  391. case WM_CHAR:
  392. m_changeType = ctReplSel;
  393. break;
  394. case WM_PASTE:
  395. m_changeType = (m_changeType == ctCut)?ctMove:ctPaste;
  396. break;
  397. case WM_CUT:
  398. m_changeType = ctCut;
  399. break;
  400. case EM_SETCHARFORMAT:
  401. // Ignore this
  402. break;
  403. default:
  404. m_changeType = ctUnknown;
  405. break;
  406. };
  407. if (pEP->msg != EM_SETCHARFORMAT && m_changeType != ctMove)
  408. m_crOldSel = pEP->chrg;
  409. *pResult = FALSE;
  410. }
  411. static LPCTSTR szKeywords = " Call Const Dim Do Loop Erase Exit For To Step Next "
  412. "Each Function If Then Else On Error Resume Option Explicit Private Public Randomize "
  413. "ReDim Rem Select Case Set Sub End While Wend "
  414. "And Eqv Imp Is Mod Not Or Xor ";
  415. static LPCTSTR szConstants = " Empty False True Nothing Null "
  416. "vbBlack vbRed vbGreen vbYellow vbBlue vbMagenta vbCyan vbWhite "
  417. "vbBinaryCompare vbTextCompare vbDatabaseCompare "
  418. "vbGeneralDate vbLongDate vbShortDate vbLongTime vbShortTime "
  419. "vbSunday vbMonday vbTuesday vbWednesday vbThursday vbFriday vbSaturday "
  420. "vbFirstJan1 vbFirstFourDays vbFirstFullWeek vbUseSystem vbUseSystemDayOfWeek "
  421. "vbObjectError vbOKOnly vbOKCancel vbAbortRetryIgnore vbYesNoCancel vbYesNo "
  422. "vbRetryCancel vbCritical vbQuestion vbExclamation vbInformation "
  423. "vbDefaultButton1 vbDefaultButton2 vbDefaultButton3 vbDefaultButton4 "
  424. "vbApplicationModal vbSystemModal "
  425. "vbCr vbCrLf vbFormFeed vbLf vbNewLine vbNullChar vbNullString vbTab vbVerticalTab "
  426. "vbEmpty vbNull vbInteger vbLong vbSingle vbDouble vbCurrency vbDate vbString "
  427. "vbObject vbError vbBoolean vbVariant vbDataObject vbDecimal vbByte vbArray ";
  428. int CGuiEditView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  429. {
  430. if (CRichEditView::OnCreate(lpCreateStruct) == -1)
  431. return -1;
  432. Initialize();
  433. SetCaseSensitive(FALSE);
  434. SetStringQuotes(_T("""));
  435. SetSLComment(_T('''));
  436. SetSLComment(_T("rem"));
  437. AddKeywords(szKeywords);
  438. AddConstants(szConstants);
  439. return 0;
  440. }