Findword.c
上传用户:chzmdj
上传日期:2007-01-22
资源大小:135k
文件大小:21k
源码类别:

源码/资料

开发平台:

C/C++

  1. #include <windows.h>
  2. #include "findword.h"
  3. #include "stdio.h"
  4. #include "string.h"
  5. #include "math.h"
  6. #include "..pub3216.h"
  7. #include <malloc.h>
  8. #include "import.h"
  9. extern char  g_szCurWord[];
  10. extern RECT  g_CurWordRect;
  11. extern int   g_nCurCaretPlace;
  12. extern BOOL  g_bAllowGetCurWord;
  13. extern POINT g_CurMousePos;
  14. extern HWND  g_hNotifyWnd;
  15. extern UINT         g_nTextAlign;
  16. extern POINT        g_dwDCOrg;
  17. extern int          g_nExtra;
  18. extern POINT        g_CurPos;
  19. extern TEXTMETRIC   g_tm;
  20. #define CHAR_WILDCHAR1 '*'
  21. #define CHAR_WILDCHAR2 '?'
  22. ///////////////////////////////////////////////////////////////////////////
  23. // Modify by Yan/Gang 1997/11/18
  24. // 用於修改在计算 TA_CENTER 情况的失误。
  25. extern BOOL bRecAllRect;
  26. extern RECT g_rcTotalRect;
  27. // End Modify
  28. ///////////////////////////////////////////////////////////////////////////
  29. #ifdef _DICTING_
  30. /////////////////////////////////////////////////////////////////////////////////
  31. // Modify by Yan/Gang 1997/11/19
  32. // 主要解决通配符的问题。
  33. extern int g_nGetWordStyle;
  34. // End Add.
  35. /////////////////////////////////////////////////////////////////////////////////
  36. #endif
  37. #define RIGHT  1
  38. #define LEFT  -1
  39. //////////////////////////////////////////////////////////////////////////////////
  40. // TODO: Return a char type.
  41. __inline int  GetCharType(char ch)
  42. {
  43. BYTE chitem = ch;
  44. if (ch < 0)
  45. return CHAR_TYPE_HZ;
  46. if (((ch >= 'a')&&(ch <= 'z'))||
  47.     ((ch >= 'A')&&(ch <= 'Z')))
  48. {
  49. return CHAR_TYPE_ASCII;
  50. }
  51. return CHAR_TYPE_OTHER;
  52. }
  53. #ifdef _DICTING_
  54. /////////////////////////////////////////////////////////////////////////////////
  55. // Modify by Yan/Gang 1997/11/19
  56. // 主要解决通配符的问题。
  57. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  58. {
  59. if (g_nGetWordStyle == GETWORD_TW_ENABLE)
  60. {
  61. return FindTWWord(lpString, nFromPlace, nLength);
  62. }
  63. else
  64. {
  65. return FindDWord(lpString, nFromPlace, nLength);
  66. }
  67. return 0;
  68. }
  69. __inline int  FindDWord(LPCSTR lpString, int nFromPlace, int nLength)
  70. {
  71. int i = nFromPlace;
  72. while (i < nLength)
  73. {
  74. if (GetCharType(lpString[i]) == CHAR_TYPE_ASCII)
  75. {
  76. i++;
  77. }
  78. else
  79. {
  80. return i-1;
  81. }
  82. return nLength - 1;
  83. }
  84. __inline int  FindTWWord(LPCSTR lpString, int nFromPlace, int nLength)
  85. {
  86. int i = nFromPlace;
  87. while (i < nLength)
  88. {
  89. if (lpString[i] == CHAR_LINK)
  90. {
  91. if (IsASCIIWord(lpString, nFromPlace, nLength, i + 1))
  92. {
  93. i++;
  94. }
  95. else
  96. {
  97. return i-1;
  98. }
  99. }
  100. else
  101. {
  102. // 用於处理 '-' 的几种情况·
  103. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  104. // if (GetCharType(lpString[i]) == CHAR_TYPE_ASCII)
  105. {
  106. i++;
  107. }
  108. else
  109. {
  110. return i-1;
  111. }
  112. }
  113. return nLength - 1;
  114. }
  115. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  116. {
  117. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  118. {
  119. return TRUE;
  120. }
  121.     
  122. if (lpString[nCurCharNum] == CHAR_WILDCHAR1)
  123. {
  124. return TRUE;
  125. }
  126. if (lpString[nCurCharNum] == CHAR_WILDCHAR2)
  127. {
  128. return TRUE;
  129. }
  130. return FALSE;
  131. }
  132. // End Add.
  133. /////////////////////////////////////////////////////////////////////////////////
  134. #else
  135. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  136. {
  137. int i = nFromPlace;
  138. // int j;
  139. while (i < nLength)
  140. {
  141. if (lpString[i] == CHAR_LINK)
  142. {
  143. if (IsASCIIWord(lpString, nFromPlace, nLength, i + 1))
  144. {
  145. i++;
  146. }
  147. else
  148. {
  149. return i-1;
  150. }
  151. }
  152. else
  153. {
  154. // 用於处理 '-' 的几种情况·
  155. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  156. {
  157. i++;
  158. }
  159. else
  160. {
  161. return i-1;
  162. }
  163. }
  164. return nLength - 1;
  165. }
  166. #define CHAR_WILDCHAR1 '*'
  167. #define CHAR_WILDCHAR2 '?'
  168. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  169. {
  170. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  171. {
  172. return TRUE;
  173. }
  174.     
  175. if (lpString[nCurCharNum] == CHAR_WILDCHAR1)
  176. {
  177. return TRUE;
  178. }
  179. if (lpString[nCurCharNum] == CHAR_WILDCHAR2)
  180. {
  181. return TRUE;
  182. }
  183. return FALSE;
  184. }
  185. #endif
  186. __inline int  FindHZWord(LPCSTR lpString, int nFromPlace, int nLength)
  187. {
  188. int i = nFromPlace;
  189. while (i < nLength)
  190. {
  191. if (GetCharType(lpString[i]) == CHAR_TYPE_HZ)
  192. {
  193. i = i + 2;
  194. }
  195. else
  196. {
  197. return i - 1;
  198. }
  199. return nLength - 1;
  200. }
  201. __inline int FindNextWordBegin(LPCSTR lpString, int nFromPlace, int nLength)
  202. {
  203. int i = nFromPlace;
  204. while (i < nLength)
  205. {
  206. if (GetCharType(lpString[i]) == CHAR_TYPE_OTHER)
  207. {
  208. i++;
  209. }
  210. else
  211. {
  212. return i-1;
  213. }
  214. return i - 1;
  215. }
  216. __inline int GetCurWordEnd(LPCSTR lpString, int nFromPlace, int nLength, int nCharType)
  217. {
  218. switch (nCharType)
  219. {                       
  220. case CHAR_TYPE_ASCII:
  221.  return FindAWord(lpString, nFromPlace, nLength);
  222.  break;
  223. case CHAR_TYPE_HZ:
  224.  return FindHZWord(lpString, nFromPlace, nLength);
  225.  break;
  226. case CHAR_TYPE_OTHER:
  227.  return FindNextWordBegin(lpString, nFromPlace, nLength);
  228.  break;
  229. }
  230. return FindAWord(lpString, nFromPlace, nLength);
  231. }
  232. __inline void CopyWord(LPSTR lpWord, LPCSTR lpString, int nBegin, int nEnd)
  233. {
  234. int i;
  235. for ( i = nBegin; i <= nEnd; i++)
  236. {
  237. lpWord[i - nBegin] = lpString[i];
  238. }
  239. lpWord[nEnd - nBegin + 1] = '';
  240. }
  241. __inline void GetStringTopBottom(HDC hDC, int y, RECT* lpStringRect)
  242. {
  243. POINT  WndPos;
  244. WndPos.y = g_dwDCOrg.y;
  245.     if (TA_UPDATECP & g_nTextAlign)
  246.     {
  247.      y = g_CurPos.y;
  248.     }
  249.     
  250. switch ((TA_TOP | TA_BOTTOM)&g_nTextAlign)
  251. {
  252. case TA_BOTTOM:
  253.  lpStringRect->top    = y - g_tm.tmHeight + g_tm.tmInternalLeading;
  254.  lpStringRect->bottom = y;
  255.  break;
  256. case TA_BASELINE:
  257.  lpStringRect->top    = y - g_tm.tmAscent;
  258.  lpStringRect->bottom = y + g_tm.tmDescent;
  259.  break;
  260. case TA_TOP:
  261. default:
  262.  lpStringRect->top    = y;
  263.  lpStringRect->bottom = y + g_tm.tmHeight + g_tm.tmInternalLeading;
  264.  break;
  265. }
  266. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  267. lpStringRect->top    = lpStringRect->top    + WndPos.y;
  268. lpStringRect->bottom = lpStringRect->bottom + WndPos.y;
  269. }
  270. __inline void GetStringLeftRight(HDC hDC, LPSTR szBuff, int cbLen, int x, RECT* lpStringRect, int FAR* lpDx)
  271. {
  272. SIZE   StringSize;
  273. POINT  WndPos;
  274.     int i;
  275. if (cbLen < 0)
  276. {
  277. lpStringRect->top    = 0;
  278. lpStringRect->bottom = 0;
  279. lpStringRect->left   = 0;
  280. lpStringRect->right  = 0;
  281. return;
  282. }
  283. GetTextExtentPoint(hDC, szBuff, cbLen, &StringSize);
  284. WndPos.x = g_dwDCOrg.x;
  285. if (lpDx != NULL)
  286. {
  287. StringSize.cx = 0;
  288. for (i = 0; i < cbLen; i++)
  289. {
  290. StringSize.cx += lpDx[i];
  291. }
  292. }
  293.     
  294.     if (TA_UPDATECP & g_nTextAlign)
  295.     {
  296.      x = g_CurPos.x;
  297.     }
  298.     
  299. switch ((TA_LEFT | TA_CENTER | TA_RIGHT)&g_nTextAlign)
  300. {
  301. case TA_RIGHT:
  302. ///////////////////////////////////////////////////////////////////////////
  303. // Modify by Yan/Gang 1997/11/21
  304. // 用於修改在计算 TA_RIGHT 情况的失误。
  305. //  lpStringRect->right = x;
  306. //  lpStringRect->left  = x - StringSize.cx;
  307.  if (!bRecAllRect)
  308.  {
  309.  lpStringRect->right = x;
  310.  lpStringRect->left  = x - StringSize.cx;
  311.  }
  312.  else
  313.  {
  314.   lpStringRect->left = g_rcTotalRect.left;
  315.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  316.  }
  317. // End Modify
  318. ///////////////////////////////////////////////////////////////////////////
  319. //  lpStringRect->right = x;
  320. //  lpStringRect->left  = x - StringSize.cx;
  321.  break;
  322. case TA_CENTER:
  323. ///////////////////////////////////////////////////////////////////////////
  324. // Modify by Yan/Gang 1997/11/18
  325. // 用於修改在计算 TA_CENTER 情况的失误。
  326. //  lpStringRect->right = x + StringSize.cx / 2;
  327. //  lpStringRect->left  = x - StringSize.cx / 2;
  328.  if (!bRecAllRect)
  329.  {
  330.  lpStringRect->right = x + StringSize.cx / 2;
  331.  lpStringRect->left  = x - StringSize.cx / 2;
  332.  }
  333.  else
  334.  {
  335.   lpStringRect->left = g_rcTotalRect.left;
  336.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  337.  }
  338. // End Modify
  339. ///////////////////////////////////////////////////////////////////////////
  340. //  lpStringRect->right = x + StringSize.cx / 2;
  341. //  lpStringRect->left  = x - StringSize.cx / 2;
  342.  break;
  343. case TA_LEFT:
  344. default:
  345.  lpStringRect->left  = x ;
  346.  lpStringRect->right = x + StringSize.cx;
  347.  break;
  348. }
  349. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  350. lpStringRect->left   = lpStringRect->left   + WndPos.x;
  351. lpStringRect->right  = lpStringRect->right  + WndPos.x;
  352. }
  353. void GetStringRect(HDC hDC, LPSTR szBuff, int cbLen, int x, int y, RECT* lpStringRect, int FAR* lpDx)
  354. {
  355. SIZE   StringSize;
  356. POINT  WndPos;
  357.     int i;
  358. if (cbLen < 0)
  359. {
  360. lpStringRect->top    = 0;
  361. lpStringRect->bottom = 0;
  362. lpStringRect->left   = 0;
  363. lpStringRect->right  = 0;
  364. return;
  365. }
  366. GetTextExtentPoint(hDC, szBuff, cbLen, &StringSize);
  367. WndPos.x = g_dwDCOrg.x;
  368. WndPos.y = g_dwDCOrg.y;
  369. if (lpDx != NULL)
  370. {
  371. StringSize.cx = 0;
  372. for (i = 0; i < cbLen; i++)
  373. {
  374. StringSize.cx += lpDx[i];
  375. }
  376. }
  377.     
  378.     if (TA_UPDATECP & g_nTextAlign)
  379.     {
  380.      x = g_CurPos.x;
  381.      y = g_CurPos.y;
  382.     }
  383.     
  384. switch ((TA_LEFT | TA_CENTER | TA_RIGHT)&g_nTextAlign)
  385. {
  386. case TA_RIGHT:
  387. ///////////////////////////////////////////////////////////////////////////
  388. // Modify by Yan/Gang 1997/11/21
  389. // 用於修改在计算 TA_RIGHT 情况的失误。
  390. //  lpStringRect->right = x;
  391. //  lpStringRect->left  = x - StringSize.cx;
  392.  if (!bRecAllRect)
  393.  {
  394.  lpStringRect->right = x;
  395.  lpStringRect->left  = x - StringSize.cx;
  396.  }
  397.  else
  398.  {
  399.   lpStringRect->left = g_rcTotalRect.left;
  400.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  401.  }
  402. // End Modify
  403. ///////////////////////////////////////////////////////////////////////////
  404. //  lpStringRect->right = x;
  405. //  lpStringRect->left  = x - StringSize.cx;
  406.  break;
  407. case TA_CENTER:
  408. ///////////////////////////////////////////////////////////////////////////
  409. // Modify by Yan/Gang 1997/11/18
  410. // 用於修改在计算 TA_CENTER 情况的失误。
  411. //  lpStringRect->right = x + StringSize.cx / 2;
  412. //  lpStringRect->left  = x - StringSize.cx / 2;
  413.  if (!bRecAllRect)
  414.  {
  415.  lpStringRect->right = x + StringSize.cx / 2;
  416.  lpStringRect->left  = x - StringSize.cx / 2;
  417.  }
  418.  else
  419.  {
  420.   lpStringRect->left = g_rcTotalRect.left;
  421.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  422.  }
  423. // End Modify
  424. ///////////////////////////////////////////////////////////////////////////
  425. //  lpStringRect->right = x + StringSize.cx / 2;
  426. //  lpStringRect->left  = x - StringSize.cx / 2;
  427.  break;
  428. case TA_LEFT:
  429. default:
  430.  lpStringRect->left  = x ;
  431.  lpStringRect->right = x + StringSize.cx;
  432.  break;
  433. }
  434. switch ((TA_TOP | TA_BOTTOM | TA_BASELINE)&g_nTextAlign)
  435. {
  436. case TA_BOTTOM:
  437.  lpStringRect->top    = y - StringSize.cy;
  438.  lpStringRect->bottom = y;
  439.  break;
  440. case TA_BASELINE:
  441.  lpStringRect->top    = y - g_tm.tmAscent;
  442.  lpStringRect->bottom = y + g_tm.tmDescent;
  443.  break;
  444. case TA_TOP:
  445. default:
  446.  lpStringRect->top    = y;
  447.  lpStringRect->bottom = y + StringSize.cy;
  448.  break;
  449. }
  450. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  451. lpStringRect->top    = lpStringRect->top    + WndPos.y;
  452. lpStringRect->bottom = lpStringRect->bottom + WndPos.y;
  453. lpStringRect->left   = lpStringRect->left   + WndPos.x;
  454. lpStringRect->right  = lpStringRect->right  + WndPos.x;
  455. }
  456. DWORD GetCurMousePosWord(HDC   hDC, 
  457.  LPSTR szBuff, 
  458.  int   cbLen, 
  459.  int   x, 
  460.  int   y, 
  461.  int   FAR* lpDx)
  462. {
  463. int   nCurrentWord, nPrevWord;
  464. RECT  StringRect;
  465. int   CharType;
  466. int   nLeft;
  467. DWORD dwReturn;
  468. GetStringTopBottom(hDC, y, &StringRect);
  469. if ((StringRect.top > g_CurMousePos.y) || (StringRect.bottom < g_CurMousePos.y))
  470. {
  471. return NO_CURMOUSEWORD;
  472. }
  473. GetStringRect(hDC, szBuff, cbLen, x, y, &StringRect, lpDx);
  474. nLeft = StringRect.left;
  475. // nLeft = 0;
  476. nPrevWord = nCurrentWord = -1;
  477. while (nCurrentWord < cbLen)
  478. {
  479. CharType     = GetCharType(szBuff[nCurrentWord + 1]);
  480. nPrevWord    = nCurrentWord;
  481. nCurrentWord = GetCurWordEnd(szBuff, nPrevWord + 1, cbLen, CharType);
  482. dwReturn     = CheckMouseInCurWord(hDC, szBuff, cbLen, x, y, lpDx, &nLeft, nPrevWord + 1, nCurrentWord, CharType);
  483. if (dwReturn == HAS_CURMOUSEWORD)
  484. return HAS_CURMOUSEWORD;
  485. if (nCurrentWord >= cbLen - 1)
  486. return NO_CURMOUSEWORD;
  487. }
  488. return NO_CURMOUSEWORD;   
  489. }
  490. __inline DWORD CheckMouseInCurWord(HDC   hDC, 
  491.    LPSTR szBuff, 
  492.    int   cbLen, 
  493.    int   x, 
  494.    int   y, 
  495.    int   FAR* lpDx,
  496.    int*  lpLeft,
  497.    int   nBegin,    // = nPrevWord + 1
  498.    int   nEnd,
  499.    int   nCharType)
  500. {
  501. RECT  StringRect;
  502. GetStringRect(hDC, szBuff, nEnd + 1, x, y, &StringRect, lpDx);
  503. StringRect.left = *lpLeft;
  504. *lpLeft = StringRect.right;
  505. if (  ((g_CurMousePos.x >= StringRect.left    ) && (g_CurMousePos.x <= StringRect.right))
  506.     || (g_CurMousePos.x == StringRect.left - 1)
  507.     || (g_CurMousePos.x == StringRect.right + 1))
  508. {
  509. switch (nCharType)
  510. {
  511. case CHAR_TYPE_HZ:
  512. case CHAR_TYPE_ASCII:
  513.  CopyWord(g_szCurWord, szBuff, nBegin, nEnd);
  514.  g_CurWordRect.left   = StringRect.left;
  515.  g_CurWordRect.right  = StringRect.right;
  516.  g_CurWordRect.top    = StringRect.top;
  517.  g_CurWordRect.bottom = StringRect.bottom;
  518.  
  519.  g_nCurCaretPlace = -1;
  520.  CalculateCaretPlace(hDC, 
  521.  szBuff, 
  522.  cbLen,
  523.  x,
  524.  y,
  525.  lpDx,
  526.  nBegin,
  527.  nEnd,
  528.  nCharType);
  529.  
  530.  break;
  531. case CHAR_TYPE_OTHER:
  532.  break;
  533. }
  534. Nh16_AddToTotalWord(szBuff, cbLen, nBegin, nEnd, nCharType, &StringRect, TRUE, g_nCurCaretPlace);
  535. if (  (nCharType == CHAR_TYPE_OTHER)
  536.     &&(CalcCaretInThisPlace(g_CurMousePos.x, StringRect.right)))
  537. {
  538. return NO_CURMOUSEWORD;
  539. }
  540. return HAS_CURMOUSEWORD;
  541. }
  542. else
  543. {
  544. }
  545. Nh16_AddToTotalWord(szBuff, cbLen, nBegin, nEnd, nCharType, &StringRect, FALSE, g_nCurCaretPlace);
  546. return NO_CURMOUSEWORD;   
  547. }
  548. // 用於计算指定位置在字串中的位置·
  549. __inline DWORD CalculateCaretPlace(HDC   hDC, 
  550.    LPSTR szBuff, 
  551.    int   cbLen, 
  552.    int   x, 
  553.    int   y, 
  554.    int   FAR* lpDx,
  555.    int   nBegin,    // = nPrevWord + 1
  556.    int   nEnd,
  557.    int   nCharType)
  558. {
  559. RECT  StringRect, BeginRect;
  560. RECT  CaretPrevRect, CaretNextRect;
  561. int   itemWidth; 
  562. int   TempPlace;
  563. if ((nCharType == CHAR_TYPE_HZ) && (nBegin == nEnd))
  564. {
  565. g_nCurCaretPlace = -1;
  566. return 0L;
  567. }
  568. GetStringRect(hDC, szBuff, nBegin, x, y, &BeginRect, lpDx);
  569. GetStringRect(hDC, szBuff, nEnd + 1,   x, y, &StringRect, lpDx);
  570. StringRect.left = BeginRect.right;
  571.     
  572.     if (StringRect.left == StringRect.right)
  573.     {
  574. g_nCurCaretPlace = -1;
  575. return 0L;
  576.     }
  577. switch (nCharType)
  578. {
  579. case CHAR_TYPE_HZ:
  580.  // 由於汉字都是等宽的字符,因此对於汉字的计算是通过计算
  581.  // 平均宽度来实现的·
  582.  itemWidth = (StringRect.right - StringRect.left) / (nEnd - nBegin + 1);
  583.  g_nCurCaretPlace = (g_CurMousePos.x - StringRect.left) * (nEnd - nBegin + 1) / (StringRect.right - StringRect.left);
  584.              break;
  585.              
  586. case CHAR_TYPE_ASCII:
  587.  // 由於英文字符为不等宽字符· 按以下步骤来计算的:
  588.  // 1. 按等宽计算一个相对位置·
  589.  // 2. 计算该相对位置的的绝对位置·
  590.  // 3. 若在该位置,返回·
  591.  // 4. 若该绝对长小於相对位置乘以宽,转6
  592.  // 5. 向右计算·
  593.  // 6. 向左计算·
  594.  
  595.  // 1. 按等宽计算一个相对位置·
  596.  // 计算宽度·
  597.  itemWidth = (StringRect.right - StringRect.left) / (nEnd - nBegin + 1);
  598.  // 计算位置·
  599.  TempPlace = (g_CurMousePos.x - StringRect.left) * (nEnd - nBegin + 1) / (StringRect.right - StringRect.left);
  600.  
  601.  // 2. 计算该相对位置的的绝对位置·
  602.  GetStringRect(hDC, szBuff, TempPlace,     x, y, &CaretPrevRect, lpDx);
  603.  GetStringRect(hDC, szBuff, TempPlace + 1, x, y, &CaretNextRect, lpDx);
  604.  
  605.  // 3. 若在该位置,返回·
  606.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  607.  {
  608.   g_nCurCaretPlace = TempPlace - nBegin;
  609.   break;
  610.  }
  611.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  612.  {
  613.   g_nCurCaretPlace = TempPlace - nBegin + 1;
  614.   break;
  615.  }
  616.  // 4. 若该绝对长小於相对位置乘以宽,转6
  617.  if (g_CurMousePos.x > CaretNextRect.right)
  618.  {
  619.  // 5. 向右计算·      
  620.  GetEngLishCaretPlace(hDC, 
  621.   szBuff,
  622.   x,
  623.   y,
  624.   lpDx,
  625.   nBegin,    // = nPrevWord + 1
  626.   nEnd,
  627.   TempPlace,
  628.   RIGHT);
  629.  }
  630.  else
  631.  {
  632.  // 6. 向左计算·
  633.  GetEngLishCaretPlace(hDC, 
  634.   szBuff,
  635.   x,
  636.   y,
  637.   lpDx,
  638.   nBegin,    // = nPrevWord + 1
  639.   nEnd,
  640.   TempPlace,
  641.   LEFT);
  642.  }
  643.  
  644.  break;
  645. }
  646. return 0L;
  647. }
  648. __inline DWORD GetEngLishCaretPlace(HDC   hDC, 
  649. LPSTR szBuff,
  650. int   x,
  651. int   y,
  652. int   FAR* lpDx,
  653. int   nBegin,    // = nPrevWord + 1
  654. int   nEnd,
  655. int   TempPlace,
  656. int   turnto)
  657. {
  658. int i;
  659. RECT  CaretPrevRect, CaretNextRect;
  660. if (turnto == RIGHT)
  661. {
  662. i = TempPlace;
  663. GetStringRect(hDC, szBuff, i, x, y, &CaretPrevRect, lpDx);
  664. for (i = TempPlace; i <= nEnd; i++)
  665. {
  666.  GetStringRect(hDC, szBuff, i + 1, x, y, &CaretNextRect, lpDx);
  667.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  668.  {
  669.   g_nCurCaretPlace = i - nBegin;
  670.   return 0;
  671.  }
  672.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  673.  {
  674.   g_nCurCaretPlace = i - nBegin + 1;
  675.   return 0;
  676.  }
  677.  CopyRect(&CaretPrevRect, &CaretNextRect);
  678. }
  679. g_nCurCaretPlace = nEnd - nBegin + 1;
  680. }
  681. else
  682. {
  683. i = TempPlace;
  684. GetStringRect(hDC, szBuff, i + 1, x, y, &CaretNextRect, lpDx);
  685. for (i = TempPlace; i >= nBegin; i--)
  686. {
  687.  GetStringRect(hDC, szBuff, i, x, y, &CaretPrevRect, lpDx);
  688.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  689.  {
  690.   g_nCurCaretPlace = i - nBegin;
  691.   return 0;
  692.  }
  693.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  694.  {
  695.   g_nCurCaretPlace = i - nBegin + 1;
  696.   return 0;
  697.  }
  698.  CopyRect(&CaretNextRect, &CaretPrevRect);
  699. }
  700. g_nCurCaretPlace = nBegin - nBegin;
  701. }
  702. return 0;
  703. }
  704. BOOL CalcCaretInThisPlace(int CaretX, int nPlace)
  705. {
  706. if (CaretX == nPlace)
  707. {
  708. return TRUE;
  709. }
  710. if (CaretX == nPlace - 1)
  711. {
  712. return TRUE;
  713. }
  714. if (CaretX == nPlace + 1)
  715. {
  716. return TRUE;
  717. }
  718. return FALSE;
  719. }
  720. // Get current Chinese char that under the mouse cursor.
  721. // 1.                       2
  722. // mouse place :    |            |
  723. // chinese char:  英业达      英业达
  724. // return place:    |           |
  725. __inline int GetHZBeginPlace(LPSTR lpszHzBuff, int nBegin, int nEnd, LPRECT lpStringRect)
  726. {
  727. int itemWidth; 
  728. int nReturn;
  729. itemWidth = (lpStringRect->right - lpStringRect->left) / (nEnd - nBegin + 1);
  730. nReturn = (g_CurMousePos.x - lpStringRect->left) * (nEnd - nBegin + 1) / (lpStringRect->right - lpStringRect->left);
  731. if (nReturn == 0)
  732. return nBegin;
  733.     
  734. if (nReturn % 2 == 1)
  735. {
  736.      lpStringRect->left = lpStringRect->left + (nReturn - 1) * itemWidth;
  737.      return nBegin + nReturn - 1;
  738.     }
  739.     
  740.     lpStringRect->left = lpStringRect->left + nReturn * itemWidth;
  741. return (nBegin + nReturn);
  742. }
  743. ////////////////////////////////////////////////////////////////////
  744. // Deal with memdc string.
  745. void AddToTextOutBuffer(HDC hMemDC, LPSTR szBuff, int cbLen, int x, int y, int FAR* lpDx)
  746. {
  747. int  nPrevWord, nCurrentWord, CharType;
  748. RECT PrevWordRect, NextWordRect;
  749. int  nLen, i;
  750. nLen = Nh16_GetTempLen();
  751. if (!Nh16_AddToTempBuff(szBuff, cbLen))
  752. {
  753. return;
  754. }
  755. nPrevWord = nCurrentWord = -1;
  756. while (nCurrentWord < cbLen)
  757. {
  758. CharType     = GetCharType(szBuff[nCurrentWord + 1]);
  759. nPrevWord    = nCurrentWord;
  760. nCurrentWord = GetCurWordEnd(szBuff, nPrevWord + 1, cbLen, CharType);
  761. GetStringRect(hMemDC, szBuff, nPrevWord + 1, x, y, &PrevWordRect, lpDx);
  762. GetStringRect(hMemDC, szBuff, nCurrentWord + 1 , x, y, &NextWordRect, lpDx);
  763. NextWordRect.left = PrevWordRect.right;
  764. if (!Nh16_AddToWordStruct(nLen + nPrevWord + 1, nLen + nCurrentWord, hMemDC, CharType, &NextWordRect))
  765. {
  766. break;
  767. }
  768. if (nCurrentWord >= cbLen - 1)
  769. break;
  770. }
  771. GetStringLeftRight(hMemDC, szBuff, 0, x, &PrevWordRect, lpDx);
  772. for (i = 0; i < cbLen; i++)
  773. {
  774. GetStringLeftRight(hMemDC, szBuff, i+1, x, &NextWordRect, lpDx);
  775. Nh16_AddToCharStruct(nLen + i, PrevWordRect.right, NextWordRect.right);
  776. CopyRect(&PrevWordRect, &NextWordRect);
  777. }
  778. }