EditWnd.cpp
上传用户:gtl066
上传日期:2007-06-15
资源大小:33k
文件大小:22k
源码类别:

Delphi控件源码

开发平台:

Visual C++

  1. // EditWnd.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MyEdit.h"
  5. #include "EditWnd.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CEditWnd
  13. const int nMargin = 5;
  14. #define SHIFTED 0x8000
  15. CEditWnd::CEditWnd()
  16. {
  17. m_ptCursor.y = m_ptTxtBegin.y = 0;
  18. m_ptTxtBegin.x = m_ptCursor.x = nMargin;
  19. m_strEdit = "";
  20. m_strSelect = "";
  21. m_nCharPos = 0;
  22. m_nShowChar = 0;
  23. m_nMaxShowChars = 0;
  24. m_nSelectBegin = 0;
  25. m_nSelectEnd = 0;
  26. m_bLBtDown = false;
  27. m_ptFirst.x = m_ptFirst.y = 0;//m_ptSecond.x = m_ptSecond.y = 0;
  28. ::memset(&m_tm, 0, sizeof(TEXTMETRIC));
  29. m_TxtFont.CreateFont( 15, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, 
  30. CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
  31. "宋体" );
  32. m_nShiftBegin = -1;
  33. }
  34. CEditWnd::~CEditWnd()
  35. {
  36. if ( m_TxtFont.GetSafeHandle() )
  37. m_TxtFont.DeleteObject();
  38. if ( m_BmpBK.GetSafeHandle() )
  39. m_BmpBK.DeleteObject();
  40. }
  41. IMPLEMENT_DYNCREATE(CEditWnd, CWnd)
  42. BEGIN_MESSAGE_MAP(CEditWnd, CWnd)
  43. //{{AFX_MSG_MAP(CEditWnd)
  44. ON_WM_LBUTTONDOWN()
  45. ON_WM_PAINT()
  46. ON_WM_SETFOCUS()
  47. ON_WM_KILLFOCUS()
  48. ON_WM_CHAR()
  49. ON_WM_GETDLGCODE()
  50. ON_WM_CREATE()
  51. ON_WM_SIZE()
  52. ON_WM_CONTEXTMENU()
  53. ON_WM_MOUSEMOVE()
  54. ON_WM_LBUTTONUP()
  55. //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CEditWnd message handlers
  59. void CEditWnd::OnLButtonDown(UINT nFlags, CPoint point) 
  60. {
  61. CWnd::OnLButtonDown(nFlags, point);
  62. SetFocus();
  63. SetCapture();
  64. m_nCharPos = CharFromPos(point.x); // 从当前鼠标的位置获得对应字符的序号
  65. if ( m_nCharPos > m_strEdit.GetLength() ) // 修正 m_nCharPos ,确保其值不会超过字符串的长度
  66. m_nCharPos = m_strEdit.GetLength();
  67. m_ptCursor.x = PosFromChar(m_nCharPos); // 设置光标的位置
  68. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  69. m_bLBtDown = true; // 设置右键按下标志位
  70. m_ptFirst = point;
  71. m_strSelect = "";
  72. m_nSelectBegin = m_nSelectEnd = 0;
  73. m_nShiftBegin = m_nCharPos;//-1;
  74. Invalidate(FALSE);
  75. }
  76. void CEditWnd::OnPaint() 
  77. {
  78. CPaintDC dc(this);
  79. CPen PenLine,*pOldPen;
  80. HBRUSH OldBrush;
  81. CRgn DrawRgn;
  82. CDC BKdc;
  83. CBitmap BmpMem, *pOldBmp;
  84. // 拷贝窗口所在区域的背景
  85. BKdc.CreateCompatibleDC(&dc);
  86. BmpMem.CreateCompatibleBitmap(&dc, m_rcWnd.Width(), m_rcWnd.Height());
  87. pOldBmp = (CBitmap *)BKdc.SelectObject(&BmpMem);
  88. BKdc.BitBlt(0, 0, m_rcWnd.Width(), m_rcWnd.Height(), &dc, 0, 0, SRCCOPY);
  89. // 设置绘制的区域
  90. PenLine.CreatePen(PS_SOLID, 1, RGB(135,155,200));
  91. pOldPen = (CPen *)BKdc.SelectObject(&PenLine);
  92. OldBrush = (HBRUSH)::SelectObject(BKdc.GetSafeHdc(),GetStockObject(NULL_BRUSH)); 
  93. BKdc.BeginPath();
  94. BKdc.RoundRect(m_rcWnd, CPoint(5, 5));
  95. BKdc.EndPath();
  96. DrawRgn.CreateFromPath(&BKdc);
  97. BKdc.SelectClipRgn(&DrawRgn, RGN_COPY);
  98. if ( m_BmpBK.GetSafeHandle() ) // 判断是否设置了背景图片
  99. { // 绘制背景
  100. CDC MemDC;
  101. MemDC.CreateCompatibleDC(&dc);
  102. CBitmap *pOldBmp = (CBitmap *)MemDC.SelectObject(&m_BmpBK);
  103. BKdc.BitBlt(m_rcWnd.left, m_rcWnd.top, m_rcWnd.Width(), m_rcWnd.Height(), &MemDC, 0, 0, SRCCOPY);
  104. MemDC.SelectObject(pOldBmp);
  105. MemDC.DeleteDC();
  106. }
  107. else // 设置缺省背景
  108. MakeBKGround(&BKdc, RGB(148, 182, 225), RGB(46, 74, 137), m_rcWnd);
  109. BKdc.SelectClipRgn(NULL, RGN_COPY); // 恢复DC现场
  110. DrawRgn.DeleteObject(); // 删除区域
  111. BKdc.RoundRect(m_rcWnd, CPoint(5, 5)); // 绘制窗体的边框
  112. BKdc.SelectObject(OldBrush);
  113. BKdc.SelectObject(pOldPen); // 恢复DC现场
  114. PenLine.DeleteObject();
  115. CFont *pOldFont;
  116. pOldFont = (CFont *)BKdc.SelectObject(&m_TxtFont);
  117. int nOldMode = BKdc.SetBkMode(TRANSPARENT);
  118. COLORREF clrOld = BKdc.SetTextColor(RGB(54,73,165));
  119. if ( m_strEdit.GetLength()>0 ) // 绘制窗体中的文本信息
  120. {
  121. CString strTemp;
  122. strTemp = m_strEdit.Right(m_strEdit.GetLength() - m_nShowChar);
  123. BKdc.TextOut(m_ptTxtBegin.x+2,m_ptTxtBegin.y+2,strTemp);
  124. BKdc.SetTextColor(RGB(42,56,127));
  125. BKdc.TextOut(m_ptTxtBegin.x+1,m_ptTxtBegin.y+1,strTemp);
  126. BKdc.SetTextColor(RGB(253,255,247));
  127. BKdc.TextOut(m_ptTxtBegin.x,m_ptTxtBegin.y,strTemp);
  128. }
  129. if ( m_strSelect.GetLength()>0 ) // 绘制被选中字符串
  130. {
  131. BLENDFUNCTION bf;
  132. int nBeginPosX, nEndPosX;
  133. bf.BlendOp = AC_SRC_OVER;
  134. bf.BlendFlags = 0;
  135. bf.AlphaFormat = 0;
  136. bf.SourceConstantAlpha=  100;
  137. if ( m_nSelectBegin < m_nShowChar )
  138. nBeginPosX = PosFromChar(m_nShowChar);
  139. else
  140. nBeginPosX = PosFromChar(m_nSelectBegin);
  141. nEndPosX = PosFromChar(m_nSelectEnd);
  142. CDC MemDC;
  143. CBitmap BmpMask, *pOldBmp;
  144. MemDC.CreateCompatibleDC(&dc);
  145. BmpMask.CreateCompatibleBitmap(&dc, nEndPosX-nBeginPosX, m_tm.tmHeight);
  146. pOldBmp = (CBitmap *)MemDC.SelectObject(&BmpMask);
  147. MemDC.FillSolidRect(0,0,nEndPosX-nBeginPosX, m_tm.tmHeight,RGB(0,0,0));
  148. AlphaBlend(BKdc.GetSafeHdc(), nBeginPosX, m_ptTxtBegin.y, nEndPosX-nBeginPosX, m_tm.tmHeight, 
  149. MemDC.GetSafeHdc(), 0, 0, nEndPosX-nBeginPosX, m_tm.tmHeight,bf);
  150. MemDC.SelectObject(pOldBmp);
  151. MemDC.DeleteDC();
  152. BmpMask.DeleteObject();
  153. }
  154. dc.BitBlt(0, 0,  m_rcWnd.Width(), m_rcWnd.Height(), &BKdc, 0, 0, SRCCOPY);
  155. BKdc.SetTextColor(clrOld);
  156. BKdc.SetBkMode(nOldMode);
  157. BKdc.SelectObject(pOldFont);
  158. BKdc.SelectObject(pOldBmp);
  159. BmpMem.DeleteObject();
  160. BKdc.DeleteDC();
  161. }
  162. BOOL CEditWnd::PreCreateWindow(CREATESTRUCT& cs) 
  163. {
  164. // TODO: Add your specialized code here and/or call the base class
  165. cs.style |= WS_TABSTOP; // 设置该窗体能够获得光标
  166. return CWnd::PreCreateWindow(cs);
  167. }
  168. void CEditWnd::OnSetFocus(CWnd* pOldWnd) 
  169. {
  170. // 窗体获得焦点以后设置光标的位置
  171. CWnd::OnSetFocus(pOldWnd);
  172. ::CreateCaret(m_hWnd,(HBITMAP) NULL, 0, m_tm.tmHeight);
  173. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y); 
  174. ::ShowCaret(m_hWnd);
  175. }
  176. void CEditWnd::OnKillFocus(CWnd* pNewWnd) 
  177. {
  178. CWnd::OnKillFocus(pNewWnd); // 窗口失去焦点的时候销毁光标
  179. ::HideCaret(m_hWnd); 
  180. ::DestroyCaret();
  181. }
  182. void CEditWnd::GetString(CString &strWnd)
  183. {
  184. strWnd = m_strEdit;
  185. }
  186. void CEditWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  187. {
  188. static bool bSpecial = false;
  189. ::HideCaret(m_hWnd);
  190. switch(nChar) {
  191. case 8: // 响应用户删除操作
  192. {
  193. if ( m_strSelect.GetLength()>0 )
  194. {
  195. m_strEdit.Delete(m_nSelectBegin, m_nSelectEnd - m_nSelectBegin);
  196. m_strSelect = "";
  197. m_nCharPos = m_nSelectBegin;
  198. m_ptCursor.x = PosFromChar(m_nCharPos);
  199. m_nSelectBegin = m_nSelectEnd = 0;
  200. m_nShiftBegin = -1;
  201. Invalidate(FALSE);
  202. }
  203. else if ( m_nCharPos>0 && m_strEdit.GetLength()>0 )
  204. {
  205. const char *cText = (const char *)m_strEdit;
  206. if ( (unsigned char)cText[m_nCharPos-1]>127 )
  207. {
  208. m_strEdit.Delete(m_nCharPos-2,2);
  209. m_nCharPos -= 2;
  210. }
  211. else
  212. {
  213. m_strEdit.Delete(m_nCharPos-1);
  214. m_nCharPos--;
  215. }
  216. if ( m_nShowChar>0 && (unsigned char)cText[m_nShowChar-1]>127 )
  217. m_nShowChar -= 2;
  218. else
  219. m_nShowChar--;
  220. if ( m_nShowChar<0 )
  221. m_nShowChar = 0;
  222. m_ptCursor.x = PosFromChar(m_nCharPos);
  223. Invalidate(FALSE);
  224. }
  225. }
  226. break;
  227. default:
  228. {
  229. if ( nChar<32 )
  230. { // 此处处理Ctrl+C、Ctrl+V和Ctrl+X操作
  231. switch(nChar) {
  232. case 3:
  233. {
  234. CopyString();
  235. }
  236. break;
  237. case 22:
  238. {
  239. PasteString();
  240. }
  241. break;
  242. case 24:
  243. {
  244. CutString();
  245. }
  246. }
  247. }
  248. else // 此处进行一般输入字符的处理
  249. {
  250. if ( m_strSelect.GetLength()>0 )
  251. { // 如果当前有被选中的字符串,先进行删除操作
  252. m_strEdit.Delete(m_nSelectBegin, m_nSelectEnd - m_nSelectBegin);
  253. m_strSelect = "";
  254. m_nCharPos = m_nSelectBegin;
  255. }
  256. m_nSelectBegin = m_nSelectEnd = 0;
  257. m_nShiftBegin = -1;
  258. m_strEdit.Insert(m_nCharPos,nChar);
  259. m_nCharPos++;
  260. if ( nChar>127 )
  261. {
  262. if ( bSpecial )
  263. {
  264. while ( m_nCharPos - m_nShowChar>m_nMaxShowChars )
  265. m_nShowChar++;
  266. m_ptCursor.x = PosFromChar(m_nCharPos);
  267. Invalidate(FALSE);
  268. bSpecial = false;
  269. }
  270. else
  271. {
  272. bSpecial = true;
  273. }
  274. }
  275. else
  276. {
  277. const char *cText = (const char *)m_strEdit;
  278. cText += m_nShowChar;
  279. while ( m_nCharPos - m_nShowChar>m_nMaxShowChars )
  280. {
  281. if ( ((unsigned char)*cText)>127 && 
  282. ((unsigned char)*(cText+1))>127 )
  283. {
  284. m_nShowChar += 2;
  285. cText += 2;
  286. }
  287. else
  288. {
  289. m_nShowChar++;
  290. cText++;
  291. }
  292. }
  293. m_ptCursor.x = PosFromChar(m_nCharPos);
  294. Invalidate(FALSE);
  295. }
  296. }
  297. }
  298. break;
  299. }
  300. ::ShowCaret(m_hWnd);
  301. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y); 
  302. CWnd::OnChar(nChar, nRepCnt, nFlags);
  303. }
  304. BOOL CEditWnd::PreTranslateMessage(MSG* pMsg) 
  305. {
  306. switch(pMsg->message)
  307. { // 处理键盘操作
  308. case WM_KEYDOWN:
  309. {
  310. switch(pMsg->wParam)
  311. {
  312. case VK_UP:
  313. case VK_LEFT:
  314. {
  315. int nVirtKey = GetKeyState(VK_SHIFT);
  316. if ( nVirtKey&SHIFTED )
  317. {
  318. if ( m_nShiftBegin<0 )
  319. {
  320. if ( m_strSelect.GetLength()>0 )
  321. {
  322. if ( m_nCharPos<m_nSelectEnd )
  323. m_nShiftBegin = m_nSelectEnd;
  324. else
  325. m_nShiftBegin = m_nSelectBegin;
  326. }
  327. else
  328. {
  329. m_nShiftBegin = m_nCharPos;
  330. }
  331. }
  332. }
  333. else
  334. {
  335. m_nShiftBegin = -1;
  336. m_strSelect = "";
  337. }
  338. ::HideCaret(m_hWnd);
  339. const char *cText = (const char *)m_strEdit;
  340. if( m_nCharPos>0 )
  341. {
  342. if ( (unsigned char)cText[m_nCharPos-1]>127 )
  343. {
  344. m_nCharPos -= 2;
  345. }
  346. else
  347. m_nCharPos--;
  348. }
  349. while ( m_nCharPos - m_nShowChar<0 ) 
  350. {
  351. if ( (unsigned char)cText[m_nShowChar-1]>127 )
  352. m_nShowChar -= 2;
  353. else
  354. m_nShowChar--;
  355. }
  356. if ( nVirtKey&SHIFTED )
  357. {
  358. if ( m_nShiftBegin<m_nCharPos )
  359. {
  360. m_nSelectBegin = m_nShiftBegin;
  361. m_nSelectEnd = m_nCharPos;
  362. }
  363. else
  364. {
  365. m_nSelectBegin = m_nCharPos;
  366. m_nSelectEnd = m_nShiftBegin;
  367. }
  368. m_strSelect = m_strEdit.Mid(m_nSelectBegin, m_nSelectEnd-m_nSelectBegin);
  369. }
  370. m_ptCursor.x = PosFromChar(m_nCharPos);
  371. Invalidate(FALSE);
  372. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  373. ::ShowCaret(m_hWnd);
  374. return TRUE;
  375. }
  376. case VK_DOWN:
  377. case VK_RIGHT:
  378. {
  379. int nVirtKey = GetKeyState(VK_SHIFT);
  380. if ( nVirtKey&SHIFTED )
  381. {
  382. if ( m_nShiftBegin<0 )
  383. {
  384. if ( m_strSelect.GetLength()>0 )
  385. {
  386. if ( m_nCharPos<m_nSelectEnd )
  387. m_nShiftBegin = m_nSelectEnd;
  388. else
  389. m_nShiftBegin = m_nSelectBegin;
  390. }
  391. else
  392. {
  393. m_nShiftBegin = m_nCharPos;
  394. }
  395. }
  396. }
  397. else
  398. {
  399. m_nShiftBegin = -1;
  400. m_strSelect = "";
  401. }
  402. ::HideCaret(m_hWnd);
  403. const char *cText = (const char *)m_strEdit;
  404. if( m_nCharPos<m_strEdit.GetLength() )
  405. {
  406. if ( (unsigned char)cText[m_nCharPos]>127 )
  407. {
  408. m_nCharPos += 2;
  409. }
  410. else
  411. m_nCharPos++;
  412. }
  413. cText += m_nShowChar;
  414. while ( m_nCharPos - m_nShowChar>m_nMaxShowChars )
  415. {
  416. if ( ((unsigned char)*cText)>127 && ((unsigned char)*(cText+1))>127 )
  417. {
  418. m_nShowChar += 2;
  419. cText += 2;
  420. }
  421. else
  422. {
  423. m_nShowChar++;
  424. cText++;
  425. }
  426. }
  427. if ( nVirtKey&SHIFTED )
  428. {
  429. if ( m_nShiftBegin<m_nCharPos )
  430. {
  431. m_nSelectBegin = m_nShiftBegin;
  432. m_nSelectEnd = m_nCharPos;
  433. }
  434. else
  435. {
  436. m_nSelectBegin = m_nCharPos;
  437. m_nSelectEnd = m_nShiftBegin;
  438. }
  439. m_strSelect = m_strEdit.Mid(m_nSelectBegin, m_nSelectEnd-m_nSelectBegin);
  440. }
  441. m_ptCursor.x = PosFromChar(m_nCharPos);
  442. Invalidate(FALSE);
  443. ::ShowCaret(m_hWnd);
  444. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  445. return TRUE;
  446. }
  447. case VK_HOME:
  448. {
  449. int nVirtKey = GetKeyState(VK_SHIFT);
  450. if ( nVirtKey&SHIFTED )
  451. {
  452. if ( m_nShiftBegin<0 )
  453. {
  454. m_nSelectEnd = m_nCharPos;
  455. m_nShiftBegin = m_nCharPos;
  456. }
  457. else
  458. m_nSelectEnd = m_nShiftBegin;
  459. m_nSelectBegin = 0;
  460. m_strSelect = m_strEdit.Mid(m_nSelectBegin, m_nSelectEnd-m_nSelectBegin);
  461. }
  462. else
  463. {
  464. m_nShiftBegin = -1;
  465. m_strSelect = "";
  466. m_nSelectBegin = m_nSelectEnd = 0;
  467. }
  468. ::HideCaret(m_hWnd);
  469. m_nCharPos = 0;
  470. m_nShowChar = 0;
  471. m_ptCursor.x = PosFromChar(m_nCharPos);
  472. Invalidate(FALSE);
  473. ::ShowCaret(m_hWnd);
  474. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  475. return TRUE;
  476. }
  477. case VK_END:
  478. {
  479. int nVirtKey = GetKeyState(VK_SHIFT);
  480. if ( nVirtKey&SHIFTED )
  481. {
  482. if ( m_nShiftBegin<0 )
  483. {
  484. m_nSelectBegin = m_nCharPos;
  485. m_nShiftBegin = m_nCharPos;
  486. }
  487. else
  488. m_nSelectBegin = m_nShiftBegin;
  489. m_nSelectEnd = m_strEdit.GetLength();
  490. m_strSelect = m_strEdit.Mid(m_nSelectBegin, m_nSelectEnd-m_nSelectBegin);
  491. }
  492. else
  493. {
  494. m_nShiftBegin = -1;
  495. m_strSelect = "";
  496. m_nSelectBegin = m_nSelectEnd = 0;
  497. }
  498. ::HideCaret(m_hWnd);
  499. m_nCharPos = m_strEdit.GetLength();
  500. //////////////////////////////////////////////////////////////
  501. const char *cText = (const char *)m_strEdit;
  502. int nIndex = m_nCharPos-1;
  503. int nShowChars = 0;
  504. while( nShowChars<m_nMaxShowChars )
  505. {
  506. if ( (unsigned char)cText[nIndex]>127 )
  507. {
  508. nIndex -= 2;
  509. nShowChars += 2;
  510. }
  511. else
  512. {
  513. nIndex -= 1;
  514. nShowChars += 1;
  515. }
  516. }
  517. //////////////////////////////////////////////////////////////
  518. m_nShowChar = m_nCharPos - nShowChars;//m_nMaxShowChars;
  519. if ( m_nShowChar<0 )
  520. m_nShowChar = 0;
  521. m_ptCursor.x = PosFromChar(m_nCharPos);
  522. Invalidate(FALSE);
  523. ::ShowCaret(m_hWnd);
  524. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  525. return TRUE;
  526. }
  527. case VK_DELETE:
  528. {
  529. if ( m_strEdit.GetLength()>0 && m_nCharPos<m_strEdit.GetLength() )
  530. {
  531. const char *cText = (const char *)m_strEdit;
  532. if ( (unsigned char)cText[m_nCharPos]>127 )
  533. {
  534. m_strEdit.Delete(m_nCharPos,2);
  535. }
  536. else
  537. m_strEdit.Delete(m_nCharPos);
  538. Invalidate(FALSE);
  539. }
  540. break;
  541. }
  542. }
  543. }
  544. break;
  545. }
  546. return CWnd::PreTranslateMessage(pMsg);
  547. }
  548. UINT CEditWnd::OnGetDlgCode() 
  549. {
  550. return (CWnd::OnGetDlgCode() | DLGC_WANTCHARS ); // 此处使得CWnd能够获得OnChar()事件
  551. }
  552. // 创建背景的函数
  553. void CEditWnd::MakeBKGround(CDC *pDC, COLORREF clrBegin, COLORREF clrEnd, CRect rect)
  554. {
  555. CDC MemDC;
  556. int x1=0,y1=0;
  557.     int x2=0,y2=0;
  558. int r1=GetRValue(clrBegin),g1=GetGValue(clrBegin),b1=GetBValue(clrBegin);
  559.     int r2=GetRValue(clrEnd),g2=GetGValue(clrEnd),b2=GetBValue(clrEnd);
  560. MemDC.CreateCompatibleDC(pDC);
  561. if ( m_BmpBK.GetSafeHandle() )
  562. m_BmpBK.DeleteObject();
  563. m_BmpBK.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  564. CBitmap *pOldBmp = MemDC.SelectObject(&m_BmpBK);
  565. while( x1<rect.Width() && y1<rect.Height() )
  566.     {
  567.         if( y1<rect.Height()-1 )
  568.             y1++;
  569.         else
  570.             x1++;
  571.         if( x2<rect.Width()-1 )
  572.             x2++;
  573.         else
  574.             y2++;
  575.         int r,g,b;
  576.         int i = x1+y1;
  577.         r = r1 + (i * (r2-r1) / (rect.Width()+rect.Height()));
  578.         g = g1 + (i * (g2-g1) / (rect.Width()+rect.Height()));
  579.         b = b1 + (i * (b2-b1) / (rect.Width()+rect.Height()));
  580.         CPen p(PS_SOLID,1,RGB(r,g,b));
  581.         CPen *oldpen = MemDC.SelectObject(&p); 
  582.         MemDC.MoveTo(x1,y1);
  583.         MemDC.LineTo(x2,y2);
  584.         MemDC.SelectObject(oldpen);
  585. p.DeleteObject();
  586.     }
  587. pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY);
  588. MemDC.SelectObject(pOldBmp);
  589. MemDC.DeleteDC();
  590. }
  591. int CEditWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  592. {
  593. if ( CWnd::OnCreate(lpCreateStruct)==-1 )
  594. return -1;
  595. GetClientRect(m_rcWnd);
  596. CClientDC dc(this);
  597. CFont *pOldFont = dc.SelectObject(&m_TxtFont);
  598. dc.GetTextMetrics(&m_tm);
  599. m_ptTxtBegin.y = m_ptCursor.y = (m_rcWnd.Height() - m_tm.tmHeight) / 2;
  600. dc.SelectObject(pOldFont);
  601. m_nMaxShowChars = (m_rcWnd.Width() - nMargin) / m_tm.tmAveCharWidth;
  602. return 0;
  603. }
  604. void CEditWnd::OnSize(UINT nType, int cx, int cy) 
  605. {
  606. CWnd::OnSize(nType, cx, cy);
  607. GetClientRect(m_rcWnd);
  608. CClientDC dc(this);
  609. CFont *pOldFont = dc.SelectObject(&m_TxtFont);
  610. dc.GetTextMetrics(&m_tm);
  611. m_ptTxtBegin.y = m_ptCursor.y = (m_rcWnd.Height() - m_tm.tmHeight) / 2;
  612. dc.SelectObject(pOldFont);
  613. m_nMaxShowChars = (m_rcWnd.Width() - nMargin) / m_tm.tmAveCharWidth;
  614. if ( m_BmpBK.GetSafeHandle() )
  615. m_BmpBK.DeleteObject();
  616. }
  617. void CEditWnd::OnContextMenu(CWnd* pWnd, CPoint point) 
  618. {
  619. }
  620. void CEditWnd::CopyString()
  621. {
  622. if ( m_strSelect.GetLength()<=0 )
  623. return;
  624. if ( OpenClipboard() )
  625. {
  626.  EmptyClipboard();
  627.  HGLOBAL hClipboardData;
  628.  hClipboardData = GlobalAlloc(GMEM_DDESHARE, 
  629.  m_strSelect.GetLength()+1);
  630.  char * pchData;
  631.  pchData = (char*)GlobalLock(hClipboardData);
  632.  strcpy(pchData, LPCSTR(m_strSelect));
  633.  GlobalUnlock(hClipboardData);
  634.  SetClipboardData(CF_TEXT,hClipboardData);
  635.  CloseClipboard();
  636. }
  637. }
  638. void CEditWnd::PasteString()
  639. {
  640. if ( OpenClipboard() ) 
  641. {
  642. if ( ::IsClipboardFormatAvailable(CF_TEXT) || 
  643. ::IsClipboardFormatAvailable(CF_OEMTEXT) )
  644. {
  645. ::HideCaret(m_hWnd);
  646. HANDLE hClipboardData = GetClipboardData(CF_TEXT);
  647. char *pchData = (char*)GlobalLock(hClipboardData);
  648. if ( m_strSelect.GetLength()>0 )
  649. {
  650. m_strEdit.Delete(m_nSelectBegin, m_strSelect.GetLength());
  651. m_nCharPos = m_nSelectBegin;
  652. m_strSelect = "";
  653. }
  654. m_strSelect.Format("%s", pchData);
  655. GlobalUnlock(hClipboardData);
  656. m_strEdit.Insert(m_nCharPos,(LPCTSTR)m_strSelect);
  657. m_nCharPos += m_strSelect.GetLength();
  658. const char *cText = (const char *)m_strEdit;
  659. cText += m_nShowChar;
  660. while ( m_nCharPos - m_nShowChar>m_nMaxShowChars )
  661. {
  662. if ( ((unsigned char)*cText)>127 && 
  663. ((unsigned char)*(cText+1)) > 127 )
  664. {
  665. m_nShowChar += 2;
  666. cText += 2;
  667. }
  668. else
  669. {
  670. m_nShowChar++;
  671. cText++;
  672. }
  673. }
  674. m_ptCursor.x = PosFromChar(m_nCharPos);
  675. Invalidate(FALSE);
  676. ::ShowCaret(m_hWnd);
  677. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y); 
  678. m_strSelect = "";
  679. }
  680. CloseClipboard();
  681. }
  682. }
  683. void CEditWnd::CutString()
  684. {
  685. if ( m_strSelect.GetLength() <= 0)
  686. return;
  687. m_strEdit.Delete(m_nSelectBegin, m_strSelect.GetLength());
  688. CopyString();
  689. ::HideCaret(m_hWnd);
  690. m_nCharPos = m_nSelectBegin;
  691. if ( m_nShowChar>0 )
  692. {
  693. m_nShowChar -= m_strSelect.GetLength();
  694. if ( m_nShowChar<0 )
  695. m_nShowChar = 0;
  696. }
  697. m_strSelect = "";
  698. m_ptCursor.x = PosFromChar(m_nCharPos);
  699. Invalidate(FALSE);
  700. ::ShowCaret(m_hWnd);
  701. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  702. }
  703. void CEditWnd::OnMouseMove(UINT nFlags, CPoint point) 
  704. {
  705. if ( m_bLBtDown )
  706. {
  707. ::HideCaret(m_hWnd);
  708. if ( m_ptFirst.x>point.x )
  709. {
  710. m_nSelectBegin = CharFromPos(point.x);
  711. m_nSelectEnd = CharFromPos(m_ptFirst.x);
  712. }
  713. else
  714. {
  715. m_nSelectBegin = CharFromPos(m_ptFirst.x);
  716. m_nSelectEnd = CharFromPos(point.x);
  717. }
  718. if ( m_nSelectEnd>m_strEdit.GetLength() )
  719. m_nSelectEnd = m_strEdit.GetLength();
  720. else if ( m_nSelectEnd<0 )
  721. m_nSelectEnd = 0;
  722. if ( m_nSelectBegin>m_strEdit.GetLength() )
  723. m_nSelectBegin = m_strEdit.GetLength();
  724. else if ( m_nSelectBegin<0 )
  725. m_nSelectBegin = 0;
  726. if ( m_nSelectEnd-m_nSelectBegin>0 )
  727. m_strSelect = m_strEdit.Mid(m_nSelectBegin,m_nSelectEnd-m_nSelectBegin);
  728. m_nCharPos = CharFromPos(point.x);
  729. if ( m_nCharPos<0 )
  730. m_nCharPos = 0;
  731. else if ( m_nCharPos>m_strEdit.GetLength() )
  732. m_nCharPos = m_strEdit.GetLength();
  733. m_ptCursor.x = PosFromChar(m_nCharPos);
  734. Invalidate(FALSE);
  735. ::ShowCaret(m_hWnd);
  736. ::SetCaretPos(m_ptCursor.x, m_ptCursor.y);
  737. }
  738. CWnd::OnMouseMove(nFlags, point);
  739. }
  740. void CEditWnd::OnLButtonUp(UINT nFlags, CPoint point) 
  741. {
  742. m_bLBtDown = false;
  743. ReleaseCapture();
  744. CWnd::OnLButtonUp(nFlags, point);
  745. }
  746. int CEditWnd::PosFromChar(UINT nChar)
  747. {
  748. CString strTemp = m_strEdit.Mid(m_nShowChar, nChar - m_nShowChar);
  749. CClientDC dc(this);
  750. CFont *pOldFont = dc.SelectObject(&m_TxtFont);
  751. CSize TestSize = dc.GetTextExtent(strTemp);
  752. dc.SelectObject(pOldFont);
  753. return (nMargin + TestSize.cx);
  754. }
  755. int CEditWnd::CharFromPos(int nPosX)
  756. {
  757. CString strTemp = m_strEdit.Mid(m_nShowChar);
  758. int nCharIndex = m_nShowChar;
  759. int nStringLen = strTemp.GetLength();
  760. char TempChar[4];
  761. int nBeginPos = nMargin;
  762. CSize TxtSize;
  763. const char *cText = (const char *)strTemp;
  764. CClientDC dc(this);
  765. CFont *pOldFont = dc.SelectObject(&m_TxtFont);
  766. while( nStringLen>0 )
  767. {
  768. if ( ((unsigned char)*cText)>127 && 
  769. ((unsigned char)*(cText+1))>127 )
  770. {
  771. strncpy(TempChar,cText,2);
  772. TempChar[2] = 0;
  773. cText += 2;
  774. nStringLen -= 2;
  775. nCharIndex += 2;
  776. TxtSize = dc.GetTextExtent(TempChar,2);
  777. }
  778. else
  779. {
  780. strncpy(TempChar,cText,1);
  781. TempChar[1] = 0;
  782. cText += 1;
  783. nStringLen -= 1;
  784. nCharIndex += 1;
  785. TxtSize = dc.GetTextExtent(TempChar,1);
  786. }
  787. if ( nBeginPos+TxtSize.cx>nPosX )
  788. {
  789. if ( nPosX-nBeginPos<nBeginPos+TxtSize.cx-nPosX )
  790. nCharIndex -= strlen(TempChar);
  791. break;
  792. }
  793. nBeginPos += TxtSize.cx;
  794. }
  795. dc.SelectObject(pOldFont);
  796. return nCharIndex;
  797. }