MyRichEditCtrl.cpp
Upload User: qzjqfs
Upload Date: 2008-02-20
Package Size: 5k
Code Size: 11k
Category:

RichEdit

Development Platform:

Visual C++

  1. // MyRichEditCtrl.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "THComputer.h"
  5. #include "MyRichEditCtrl.h"
  6. #include "TranASMDlg.h"
  7. #include "MainFrm.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CMyRichEditCtrl
  15. CMyRichEditCtrl::CMyRichEditCtrl()
  16. {
  17. m_nVpos = 0;
  18. m_bEVpos = false;
  19. m_bAVpos = false;
  20. }
  21. CMyRichEditCtrl::~CMyRichEditCtrl()
  22. {
  23. }
  24. BEGIN_MESSAGE_MAP(CMyRichEditCtrl, CRichEditCtrl)
  25. //{{AFX_MSG_MAP(CMyRichEditCtrl)
  26. ON_WM_RBUTTONDOWN()
  27. ON_WM_PAINT()
  28. ON_WM_KEYUP()
  29. ON_WM_VSCROLL()
  30. ON_WM_MOUSEMOVE()
  31. //}}AFX_MSG_MAP
  32. END_MESSAGE_MAP()
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CMyRichEditCtrl message handlers
  35. BOOL CMyRichEditCtrl::PreTranslateMessage(MSG* pMsg) 
  36. {
  37. pMessage = pMsg;
  38. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
  39. {
  40. SetReturnBlank();
  41. return TRUE;
  42. /* if (pMsg->message == WM_VSCROLL && pMsg->wParam == )
  43. {
  44. }*/
  45. /* if (pMsg->wParam != VK_LEFT && pMsg->wParam != VK_RIGHT && pMsg->wParam != VK_UP &&pMsg->wParam != VK_DOWN)
  46. {
  47. HandleFont();
  48. }
  49. */
  50. }
  51. return CRichEditCtrl::PreTranslateMessage(pMsg);
  52. }
  53. void CMyRichEditCtrl::HandleFont()
  54. {
  55. CString strCur = GetCursorString();
  56. int nResult = SearchStr(strCur);
  57. int len = strCur.GetLength();
  58. //正确选中字符串;针对光标移动至字符串中间情况
  59. long nStartChar,nEndChar,start,end;
  60. GetSel(nStartChar,nEndChar);
  61. start = nStartChar;
  62. end = nEndChar;
  63. long nlast;
  64. SetSel(-1,-1);
  65. GetSel(nlast,nlast);
  66. SetSel(nStartChar,nEndChar);
  67. nStartChar = nEndChar-len;
  68. CString strTemp;
  69. SetSel(nStartChar,nEndChar);
  70. strTemp = GetSelText();
  71. while (strTemp != strCur && nEndChar-1 < nlast)
  72. {
  73. nStartChar++;
  74. nEndChar++;
  75. SetSel(nStartChar,nEndChar);
  76. strTemp = GetSelText();
  77. }
  78. SetCurColor(nResult,nStartChar,nEndChar);
  79. SetSel(start,end);
  80. }
  81. CString CMyRichEditCtrl::GetCursorString()
  82. {
  83. long start, end;
  84. GetSel(start, end);
  85. long startline = LineFromChar(start);
  86. long endlie = LineFromChar(end);
  87. if(startline == endlie && start != end) //用户选定了文本
  88. {
  89. return GetSelText();
  90. }
  91. else
  92. {
  93. int nlnstart, nlnend;
  94. long line = LineFromChar(end);
  95. int ntmp = end-LineIndex(line); //计算行内偏移
  96. CString strline;
  97. GetLineString(line, strline);
  98. int i=0, noffset=0;
  99. while(noffset!=ntmp) //得到光标所在行的字符串中的位置(字符串中中文为两个字符)
  100. {
  101. if(IsDBCSLeadByte(strline[i])) ++i;
  102. ++i; ++noffset;
  103. }
  104. ntmp = i;
  105. while(ntmp>0)
  106. {
  107. --ntmp;
  108. if(!isalnum(strline[ntmp]) && strline[ntmp]!='_')
  109. {
  110. if(ntmp>0)
  111. {
  112. if(IsDBCSLeadByte(strline[ntmp-1])) //检查是不是中文字符
  113. {
  114. --ntmp;
  115. }
  116. else
  117. break;
  118. }
  119. }
  120. }
  121. if(!(isalnum(strline[ntmp]) || IsDBCSLeadByte(strline[ntmp])) || strline[ntmp]=='_')
  122. nlnstart = ntmp+1;
  123. else
  124. nlnstart = ntmp;
  125. ntmp = i; //计算行内偏移
  126. int nstrlen = strline.GetLength();
  127. while(ntmp<nstrlen-1)
  128. {
  129. if(IsDBCSLeadByte(strline[ntmp])) //检查是不是中文字符
  130. ++ntmp;
  131. else
  132. {
  133. if(!isalnum(strline[ntmp]) && strline[ntmp]!='_')
  134. break;
  135. }
  136. ++ntmp;
  137. }
  138. nlnend = ntmp;
  139. CString str = strline.Mid(nlnstart, nlnend-nlnstart);
  140. return str;
  141. }
  142. }
  143. BOOL CMyRichEditCtrl::GetLineString(int nLine, CString &strLine)
  144. {
  145. strLine = _T("");
  146. int m_nLineCount = GetLineCount();
  147. if(nLine > m_nLineCount - 1 || nLine < 0) 
  148. return TRUE;
  149. int nTemp = LineIndex(nLine);
  150. nTemp = LineLength(nTemp)*16+32; //缓冲区必须足够大,否则读取中文时可能会有乱码
  151. TCHAR *achLine = new TCHAR[nTemp];
  152. int nLen = GetLine(nLine, achLine, nTemp); 
  153. //检查实际读出的字符数,一个中文应换算成两个字符
  154. int i = 0;
  155. nTemp = 0;
  156. while(nTemp != nLen)
  157. {
  158. if(IsDBCSLeadByte(achLine[i++]))
  159. i++;
  160. ++nTemp;
  161. }
  162. /////////////////////////////////////////////////
  163. BOOL bRealReturn;
  164. achLine[i] = 0;
  165. //检查是不是真的换行
  166. if(0xd == achLine[i-1]) 
  167. {
  168. achLine[--i] = 0;  
  169. bRealReturn=TRUE;
  170. }
  171. else 
  172. {
  173. achLine[i] = 0;
  174. bRealReturn=FALSE;
  175. }
  176. ////////////////////
  177. //尾部加一个空格,以送给语法解析器
  178. lstrcat(achLine, _T(" "));
  179. strLine = achLine;
  180. if(achLine)
  181. delete achLine;
  182. return bRealReturn;
  183. }
  184. int CMyRichEditCtrl::SearchStr(CString strCur)
  185. {
  186. CMainFrame *pMain = (CMainFrame *)FromHandle(m_hMainMyRichEdit);
  187. strCur.MakeUpper();
  188. //黑色的情况,不认识的
  189. int lenc = strCur.GetLength();
  190. if (lenc == 0)
  191. return 0;
  192. if (strCur == "MM" || strCur == "#II")
  193. return 0;
  194. //红色的情况,数字和‘H’
  195. bool flag = true;
  196. for (int j=0;j<lenc;j++)
  197. {
  198. int num = (int)strCur.GetAt(j);
  199. if (num>47 && num<58)
  200. ;
  201. else
  202. flag = false;
  203. }
  204. if (flag)
  205. {
  206. return 2;
  207. }
  208. CString strTemp;
  209. int num = atoi(strCur);
  210. strTemp.Format("%d",num);
  211. if (strCur == strTemp)
  212. return 2;
  213. //CString strTemp;
  214. if (strCur.GetAt(lenc-1) == 'H')//16进制
  215. {
  216. if (pMain->SixteenToTen(strCur.Left(lenc-1)) == pMain->SixteenToTen(strTemp))
  217. return 2;
  218. if (pMain->TenToSixteen(pMain->SixteenToTen(strCur.Left(lenc-1))) = strCur.Left(lenc-1))
  219. {
  220. return 2;
  221. }
  222. }
  223. if (strCur.GetAt(lenc-1) == 'B')//2进制
  224. {
  225. if (pMain->HexToBin(pMain->BinToHex(strCur.Left(lenc-1))) = strCur.Left(lenc-1))
  226. {
  227. flag = true;
  228. for (int j=0;j<lenc-1;j++)
  229. {
  230. int num = (int)strCur.GetAt(j);
  231. if (num>47 && num<50)
  232. ;
  233. else
  234. flag = false;
  235. }
  236. if (flag)
  237. {
  238. return 2;
  239. }
  240. }
  241. }
  242. //
  243. if (strCur == "R0" || strCur == "R1" || strCur == "R2" || strCur == "R3")
  244. return 1;
  245. for (int i=0;i<64;i++)
  246. {
  247. CString strZjfL,strZjfM,strZjfR;
  248. strZjfL = pMain->StuSeg[i].ZJfL;
  249. strZjfM = pMain->StuSeg[i].ZJfM;
  250. strZjfR = pMain->StuSeg[i].ZJfR;
  251. if (strCur == strZjfL || strCur == strZjfM || strCur == strZjfR)
  252. return 1;
  253. }
  254. return 0;
  255. }
  256. void CMyRichEditCtrl::SetCurColor(int n,int nStart, int nEnd)//指定区域,设置字体颜色
  257. {
  258. CHARFORMAT cf;
  259.     ZeroMemory(&cf, sizeof(CHARFORMAT));
  260.     cf.cbSize = sizeof(CHARFORMAT);
  261.     cf.dwMask = CFM_COLOR; 
  262. if (n == 0)
  263. cf.crTextColor = RGB(0,0,0);
  264. if (n == 1)
  265. cf.crTextColor = RGB(0,0,255);
  266. if (n == 2)
  267. cf.crTextColor = RGB(255,0,0);
  268.     SetSel(nStart,nEnd); //设置处理区域
  269.     SetSelectionCharFormat(cf);
  270. SetSel(nEnd,nEnd);
  271. cf.crTextColor = RGB(0,0,0);
  272.     SetSelectionCharFormat(cf);
  273. }
  274. void CMyRichEditCtrl::SetReturnBlank()
  275. {
  276. long nstart,nEnd;
  277. GetSel(nstart,nEnd);
  278. int nIndex = LineFromChar(nstart);
  279. int len = LineLength(nIndex-1);
  280. char *buf = new char[len+1];
  281. GetLine(nIndex,buf);
  282. int num=0;
  283. while (buf[num] == ' ')
  284. {
  285. num++;
  286. }
  287. buf[num] = '';
  288. ReplaceSel("rn",true);
  289. if (num != len)
  290. {
  291. ReplaceSel(buf,true);
  292. }
  293. }
  294. BOOL CMyRichEditCtrl::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
  295. {
  296. return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  297. }
  298. void CMyRichEditCtrl::SetRangeFont(int nstart, int nend)
  299. {
  300. if (nstart>nend)
  301. return;
  302. for (int i=0;i<nend-nstart+1;i++)
  303. {
  304. SetSel(nstart+i,nstart+i);
  305. HandleFont();
  306. }
  307. }
  308. //确定是不是一行
  309. BOOL CMyRichEditCtrl::ConfirmLine(int nstart, int nend)
  310. {
  311. if (nstart>nend)
  312. return false;
  313. for (int i=0;i<nend-nstart+1;i++)
  314. {
  315. SetSel(nstart+i,nstart+i);
  316. CString str = GetCursorString();
  317. if (!str.IsEmpty())
  318. return true;
  319. }
  320. return false;
  321. }
  322. void CMyRichEditCtrl::OnRButtonDown(UINT nFlags, CPoint point) 
  323. {
  324. CRichEditCtrl::OnRButtonDown(nFlags, point);
  325. }
  326. void CMyRichEditCtrl::OnPaint() 
  327. {
  328. CRichEditCtrl::OnPaint();
  329. CBrush brushb(RGB(192,192,192));
  330. CDC* hdc;
  331. hdc = GetWindowDC();
  332. CRect rect;
  333. GetClientRect(&rect);
  334. hdc->FillRect(CRect(rect.left+5 ,rect.top+5 ,rect.left + 25,rect.Height ()+5),&brushb);//画底色
  335. brushb.DeleteObject();
  336. ReleaseDC(hdc);
  337. CTranASMDlg *pDlg = (CTranASMDlg *)FromHandle(m_hDlgTranASM);
  338. int nLine = pDlg->m_index;
  339. COLORREF col = pDlg->m_color;
  340. pDlg->DrawEllipse();//断点
  341. pDlg->DrawArrow(nLine,col);//箭头
  342. }
  343. void CMyRichEditCtrl::PreSubclassWindow() 
  344. {
  345. CRichEditCtrl::PreSubclassWindow();
  346. SetRect(CRect(21,0,8000,8000));
  347. LimitText(20000);
  348. m_flag = false;
  349. // CRect rc(21,0,80,80);
  350. // SetMargins(&rc);
  351. }
  352. void CMyRichEditCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  353. {
  354. CRichEditCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
  355. CMainFrame *pMain = (CMainFrame *)FromHandle(m_hMainMyRichEdit);
  356. pMain->PviewTraFrom->m_DlgTranASMToSegDlg.m_CListBoxToSeg.SetFocus();
  357. HandleFont();
  358. pMain->PviewTraFrom->m_DlgTranASMDlg.m_CRichEditASM.SetFocus();
  359. SendMessage(WM_PAINT,0,0);
  360. m_flag = false;
  361. }
  362. void CMyRichEditCtrl::EnsureVisible(int nRow)
  363. {
  364. CRect rt;
  365. GetRect(&rt);
  366. int nLine = GetLineCount(); //行数
  367. int nHeight = 10; //行高
  368. int nVisalLine = rt.Height()/nHeight/2; //可视行数
  369. int nUp = GetFirstVisibleLine(); //最上面行
  370. int nDown = nUp + rt.Height()/nHeight/2 - 1;//最下面行
  371. int nMid = (nUp + nDown)/2; //中间行
  372. if (nRow == nUp)
  373. {
  374. SendMessage(WM_VSCROLL,SB_LINEUP,0);
  375. }
  376. if (nDown-nRow<2 && nDown == nLine-2) //当前位置到低端小于2行
  377. {
  378. SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
  379. }
  380. if (nRow < nUp) //在最上
  381. {
  382. while (nRow < nMid && nUp > 0)
  383. {
  384. SendMessage(WM_VSCROLL, SB_LINEUP, 0);
  385. nUp = GetFirstVisibleLine();
  386. nDown = nUp + rt.Height()/nHeight/2 - 1;
  387. nMid = (nUp + nDown)/2;
  388. }
  389. }
  390. if (nRow > nDown && nRow < nLine) //在最下
  391. {
  392. while (nRow > nMid && nDown < nLine-2)
  393. {
  394. SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
  395. nUp = GetFirstVisibleLine();
  396. nDown = nUp + rt.Height()/nHeight/2 - 1;
  397. nMid = (nUp + nDown)/2;
  398. }
  399. }
  400. while (nDown-nRow<2 && nDown<nLine-2)     //往下滚
  401. {
  402. SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
  403. nUp = GetFirstVisibleLine();
  404. nDown = nUp + rt.Height()/nHeight/2 - 1;
  405. //nMid = (nUp + nDown)/2;
  406. }
  407. }
  408. /*
  409. #define SB_LINEUP           0
  410. #define SB_LINELEFT         0
  411. #define SB_LINEDOWN         1
  412. #define SB_LINERIGHT        1
  413. #define SB_PAGEUP           2
  414. #define SB_PAGELEFT         2
  415. #define SB_PAGEDOWN         3
  416. #define SB_PAGERIGHT        3
  417. #define SB_THUMBPOSITION    4
  418. #define SB_THUMBTRACK       5
  419. #define SB_TOP              6
  420. #define SB_LEFT             6
  421. #define SB_BOTTOM           7
  422. #define SB_RIGHT            7
  423. #define SB_ENDSCROLL        8
  424. */
  425. void CMyRichEditCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  426. {
  427. if(nSBCode == SB_THUMBTRACK )
  428. {
  429. m_nVpos = nPos;
  430. m_bEVpos = true;
  431. m_bAVpos = true;
  432. }
  433. CRichEditCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
  434. m_flag = true;
  435. }
  436. void CMyRichEditCtrl::OnMouseMove(UINT nFlags, CPoint point) 
  437. {
  438. CRichEditCtrl::OnMouseMove(nFlags, point);
  439. }
  440. void CMyRichEditCtrl::DrawLineArrow(int index, COLORREF color)
  441. {
  442. /* if (index <0)
  443. return;
  444. UINT hScroll = GetScrollPos(SB_VERT);
  445. //高度24,44,64,84……
  446. int height = index*20;
  447. CDC *pDC;
  448. pDC = GetWindowDC();
  449. CBrush brushb(color);
  450. pDC->FillRect(CRect(12,12+height-hScroll,22,16+height-hScroll),&brushb);
  451. brushb.DeleteObject();
  452. CPen cpen,*pPen;
  453. cpen.CreatePen(PS_SOLID,3,color);
  454. pPen=pDC->SelectObject(&cpen);
  455. pDC->MoveTo(22,14+height-hScroll);
  456. pDC->LineTo(18,10+height-hScroll);
  457. pDC->MoveTo(22,14+height-hScroll);
  458. pDC->LineTo(18,18+height-hScroll);
  459. cpen.DeleteObject();*/
  460. }