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

源码/资料

开发平台:

C/C++

  1. #include <windows.h>
  2. #include "srhword.h"
  3. #include "findword.h"
  4. #include "stdio.h"
  5. #include "string.h"
  6. #include "math.h"
  7. #include "..pub3216.h"
  8. #include <malloc.h>
  9. #ifdef _DEBUG
  10. #include "DbgFunc.h"
  11. #endif //_DEBUG
  12. extern int   g_nCurrWindowVer;
  13. extern char  g_szTotalWord[BUFFERLENGTH];
  14. extern RECT  g_TotalWordRect;
  15. extern int   g_CharType;
  16. extern int   g_nCurCaretPlaceInTotalWord;
  17. extern int   g_bMouseInTotalWord;
  18. //Added by XGL,Sep 29th,1998
  19. extern RECT  g_rcFirstWordRect;
  20. //Adding ends.
  21. extern char  g_szCurWord[BUFFERLENGTH];
  22. extern RECT  g_CurWordRect;
  23. extern int   g_nCurCaretPlace;
  24. extern char szMemDCWordBuff[BUFFERLENGTH];
  25. extern int  pnMemDCCharLeft[BUFFERLENGTH];
  26. extern int  pnMemDCCharRight[BUFFERLENGTH];
  27. extern WORDPARA WordBuffer[MEMDC_MAXNUM];
  28. extern int nWordNum;
  29. extern BOOL  g_bAllowGetCurWord;
  30. extern POINT g_CurMousePos;
  31. extern HWND  g_hNotifyWnd;
  32. extern UINT         g_nTextAlign;
  33. extern DWORD        g_dwDCOrg;
  34. extern int          g_nExtra;
  35. extern POINT        g_CurPos;
  36. extern TEXTMETRIC   g_tm;
  37. ///////////////////////////////////////////////////////////////////////////
  38. // Modify by Yan/Gang 1997/11/18
  39. // 用於修改在计算 TA_CENTER 情况的失误。
  40. extern BOOL bRecAllRect;
  41. extern RECT g_rcTotalRect;
  42. // End Modify
  43. ///////////////////////////////////////////////////////////////////////////
  44. #define RIGHT  1
  45. #define LEFT  -1
  46. #ifdef _DICTING_
  47. ///////////////////////////////////////////////////////////////////////////
  48. // Add by Yan/Gang   11/13/1997
  49. // 用於向查字助理通知取得所需要的单词·
  50. extern UINT BL_HASSTRING;
  51. // Add end.
  52. ///////////////////////////////////////////////////////////////////////////
  53. #endif
  54. #ifdef _DICTING_
  55. /////////////////////////////////////////////////////////////////////////////////
  56. // Modify by Yan/Gang 1997/11/19
  57. // 主要解决通配符的问题。
  58. extern int g_nGetWordStyle;
  59. // End Add.
  60. /////////////////////////////////////////////////////////////////////////////////
  61. //Added by XGL Sep 17th, 1998
  62. extern int g_nWordsInPhrase ;
  63. extern BOOL g_bPhraseNeeded ;
  64. extern int g_nPhraseCharType ;
  65. //Adding ends
  66. /////////////////////////////////////////////////////////////////////////////////
  67. #endif
  68. //////////////////////////////////////////////////////////////////////////////////
  69. // TODO: Return a char type.
  70. __inline int  GetCharType(char ch)
  71. {
  72. BYTE chitem = ch;
  73. if (ch < 0)
  74. return CHAR_TYPE_HZ;
  75. if (((ch >= 'a')&&(ch <= 'z'))||
  76.     ((ch >= 'A')&&(ch <= 'Z')))
  77. {
  78. return CHAR_TYPE_ASCII;
  79. }
  80. return CHAR_TYPE_OTHER;
  81. }
  82. #ifdef _DICTING_
  83. /////////////////////////////////////////////////////////////////////////////////
  84. // Modify by Yan/Gang 1997/11/19
  85. // 主要解决通配符的问题。
  86. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  87. {
  88. return FindTWWord(lpString, nFromPlace, nLength);
  89. }
  90. __inline int  FindDWord(LPCSTR lpString, int nFromPlace, int nLength)
  91. {
  92. int i = nFromPlace;
  93. while (i < nLength)
  94. {
  95. if (GetCharType(lpString[i]) == CHAR_TYPE_ASCII)
  96. {
  97. i++;
  98. }
  99. else
  100. {
  101. return i-1;
  102. }
  103. return nLength - 1;
  104. }
  105. __inline int  FindTWWord(LPCSTR lpString, int nFromPlace, int nLength)
  106. {
  107. int i = nFromPlace;
  108. // int j;
  109. while (i < nLength)
  110. {
  111. if (lpString[i] == CHAR_LINK)
  112. {
  113. if (IsASCIIWord(lpString, nFromPlace, nLength, i + 1))
  114. {
  115. i++;
  116. }
  117. else
  118. {
  119. return i-1;
  120. }
  121. }
  122. else
  123. {
  124. // 用於处理 '-' 的几种情况·
  125. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  126. {
  127. i++;
  128. }
  129. else
  130. {
  131. return i-1;
  132. }
  133. }
  134. return nLength - 1;
  135. }
  136. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  137. {
  138. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  139. {
  140. return TRUE;
  141. }
  142. return FALSE;
  143. }
  144. // End Add.
  145. /////////////////////////////////////////////////////////////////////////////////
  146. #else
  147. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  148. {
  149. int i = nFromPlace;
  150. while (i < nLength)
  151. {
  152. if (lpString[i] == CHAR_LINK)
  153. {
  154. if (IsASCIIWord(lpString, nFromPlace, nLength, i + 1))
  155. {
  156. i++;
  157. }
  158. else
  159. {
  160. return i-1;
  161. }
  162. }
  163. else
  164. {
  165. // 用於处理 '-' 的几种情况·
  166. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  167. {
  168. i++;
  169. }
  170. else
  171. {
  172. return i-1;
  173. }
  174. }
  175. return nLength - 1;
  176. }
  177. #define CHAR_WILDCHAR1 '*'
  178. #define CHAR_WILDCHAR2 '?'
  179. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  180. {
  181. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  182. {
  183. return TRUE;
  184. }
  185.     
  186. return FALSE;
  187. }
  188. #endif
  189. __inline int  FindHZWord(LPCSTR lpString, int nFromPlace, int nLength)
  190. {
  191. int i = nFromPlace;
  192. if ((BYTE)(lpString[nFromPlace]) >= 0xa1
  193. && (BYTE)(lpString[nFromPlace]) <= 0xa9)
  194. {
  195. return nFromPlace + 1 ;
  196. }
  197. while (i < nLength)
  198. {
  199. if (GetCharType(lpString[i]) == CHAR_TYPE_HZ)
  200. {
  201.  //Added by XGL, Nov 13th, 1998
  202.  //We have to filter out Chinese punctuation marks,
  203.  //which is diffent as it is in ASCII.
  204.  if ((BYTE)(lpString[i]) >= 0xa1
  205.  && (BYTE)(lpString[i]) <= 0xa9)
  206.  {
  207.  return i - 1 ;
  208.  }
  209.  //Adding ends. XGL, Nov 13th, 1998
  210. i = i + 2;
  211. }
  212. else
  213. {
  214. return i - 1;
  215. }
  216. return nLength - 1;
  217. }
  218. __inline int FindNextWordBegin(LPCSTR lpString, int nFromPlace, int nLength)
  219. {
  220. int i = nFromPlace;
  221. while (i < nLength)
  222. {
  223. if (GetCharType(lpString[i]) == CHAR_TYPE_OTHER)
  224. {
  225. i++;
  226. }
  227. else
  228. {
  229. return i-1;
  230. }
  231. return i - 1;
  232. }
  233. __inline int GetCurWordEnd(LPCSTR lpString, int nFromPlace, int nLength, int nCharType)
  234. {
  235. switch (nCharType)
  236. {                       
  237. case CHAR_TYPE_ASCII:
  238.  return FindAWord(lpString, nFromPlace, nLength);
  239.  break;
  240. case CHAR_TYPE_HZ:
  241.  return FindHZWord(lpString, nFromPlace, nLength);
  242.  break;
  243. case CHAR_TYPE_OTHER:
  244.  return FindNextWordBegin(lpString, nFromPlace, nLength);
  245.  break;
  246. }
  247. return FindAWord(lpString, nFromPlace, nLength);
  248. }
  249. __inline void CopyWord(LPSTR lpWord, LPCSTR lpString, int nBegin, int nEnd)
  250. {
  251. int i;
  252. for ( i = nBegin; i <= nEnd; i++)
  253. {
  254. lpWord[i - nBegin] = lpString[i];
  255. }
  256. lpWord[nEnd - nBegin + 1] = '';
  257. }
  258. __inline void GetStringTopBottom(HDC hDC, int y, RECT* lpStringRect)
  259. {
  260. POINT  WndPos;
  261. WndPos.y = HIWORD(g_dwDCOrg);
  262.     if (TA_UPDATECP & g_nTextAlign)
  263.     {
  264.      y = g_CurPos.y;
  265.     }
  266.     
  267. switch ((TA_TOP | TA_BOTTOM)&g_nTextAlign)
  268. {
  269. case TA_BOTTOM:
  270.  lpStringRect->top    = y - g_tm.tmHeight + g_tm.tmInternalLeading;
  271.  lpStringRect->bottom = y;
  272.  break;
  273. case TA_BASELINE:
  274.  lpStringRect->top    = y - g_tm.tmAscent;
  275.  lpStringRect->bottom = y + g_tm.tmDescent;
  276.  break;
  277. case TA_TOP:
  278. default:
  279.  lpStringRect->top    = y;
  280.  lpStringRect->bottom = y + g_tm.tmHeight + g_tm.tmInternalLeading;
  281.  break;
  282. }
  283. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  284. lpStringRect->top    = lpStringRect->top    + WndPos.y;
  285. lpStringRect->bottom = lpStringRect->bottom + WndPos.y;
  286. }
  287. __inline void GetStringLeftRight(HDC hDC, LPSTR szBuff, int cbLen, int x, RECT* lpStringRect, int FAR* lpDx)
  288. {
  289. SIZE   StringSize;
  290. POINT  WndPos;
  291.     int i;
  292. if (cbLen < 0)
  293. {
  294. lpStringRect->top    = 0;
  295. lpStringRect->bottom = 0;
  296. lpStringRect->left   = 0;
  297. lpStringRect->right  = 0;
  298. return;
  299. }
  300. GetTextExtentPoint(hDC, szBuff, cbLen, &StringSize);
  301. WndPos.x = LOWORD(g_dwDCOrg);
  302. if (lpDx != NULL)
  303. {
  304. StringSize.cx = 0;
  305. for (i = 0; i < cbLen; i++)
  306. {
  307. StringSize.cx += lpDx[i];
  308. }
  309. }
  310.     
  311.     if (TA_UPDATECP & g_nTextAlign)
  312.     {
  313.      x = g_CurPos.x;
  314.     }
  315.     
  316. switch ((TA_LEFT | TA_CENTER | TA_RIGHT)&g_nTextAlign)
  317. {
  318. case TA_RIGHT:
  319.  if (!bRecAllRect)
  320.  {
  321.  lpStringRect->right = x;
  322.  lpStringRect->left  = x - StringSize.cx;
  323.  }
  324.  else
  325.  {
  326.   lpStringRect->left = g_rcTotalRect.left;
  327.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  328.  }
  329.  break;
  330. case TA_CENTER:
  331.  if (!bRecAllRect)
  332.  {
  333.  lpStringRect->right = x + StringSize.cx / 2;
  334.  lpStringRect->left  = x - StringSize.cx / 2;
  335.  }
  336.  else
  337.  {
  338.   lpStringRect->left = g_rcTotalRect.left;
  339.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  340.  }
  341.  break;
  342. case TA_LEFT:
  343. default:
  344.  lpStringRect->left  = x ;
  345.  lpStringRect->right = x + StringSize.cx;
  346.  break;
  347. }
  348. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  349. lpStringRect->left   = lpStringRect->left   + WndPos.x;
  350. lpStringRect->right  = lpStringRect->right  + WndPos.x;
  351. }
  352. //#define _TEST
  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 = LOWORD(g_dwDCOrg);
  368. WndPos.y = HIWORD(g_dwDCOrg);
  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.  if (bRecAllRect == FALSE)
  388.  {
  389.  lpStringRect->right = x;
  390.  lpStringRect->left  = x - StringSize.cx;
  391.  }
  392.  else
  393.  {
  394.   lpStringRect->left = g_rcTotalRect.left;
  395.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  396.  }
  397.  break;
  398. case TA_CENTER:
  399.  if (bRecAllRect == FALSE)
  400.  {
  401.  lpStringRect->right = x + StringSize.cx / 2;
  402.  lpStringRect->left  = x - StringSize.cx / 2;
  403.  }
  404.  else
  405.  {
  406.   lpStringRect->left = g_rcTotalRect.left;
  407.   lpStringRect->right= g_rcTotalRect.left + StringSize.cx;
  408.  }
  409.  break;
  410. case TA_LEFT:
  411. default:
  412.  lpStringRect->left  = x ;
  413.  lpStringRect->right = x + StringSize.cx;
  414.  break;
  415. }
  416. switch ((TA_TOP | TA_BOTTOM | TA_BASELINE)&g_nTextAlign)
  417. {
  418. case TA_BOTTOM:
  419.  lpStringRect->top    = y - StringSize.cy;
  420.  lpStringRect->bottom = y;
  421.  break;
  422. case TA_BASELINE:
  423.  lpStringRect->top    = y - g_tm.tmAscent;
  424.  lpStringRect->bottom = y + g_tm.tmDescent;
  425.  break;
  426. case TA_TOP:
  427. default:
  428.  lpStringRect->top    = y;
  429.  lpStringRect->bottom = y + StringSize.cy;
  430.  break;
  431. }
  432. LPtoDP(hDC, (LPPOINT)lpStringRect, 2);
  433. lpStringRect->top    = lpStringRect->top    + WndPos.y;
  434. lpStringRect->bottom = lpStringRect->bottom + WndPos.y;
  435. lpStringRect->left   = lpStringRect->left   + WndPos.x;
  436. lpStringRect->right  = lpStringRect->right  + WndPos.x;
  437. }
  438. DWORD GetCurMousePosWord(HDC   hDC, 
  439.  LPSTR szBuff, 
  440.  int   cbLen, 
  441.  int   x, 
  442.  int   y, 
  443.  int   FAR* lpDx)
  444. {
  445. int   nCurrentWord, nPrevWord;
  446. RECT  StringRect;
  447. int   CharType;
  448. int   nLeft;
  449. DWORD dwReturn;
  450. GetStringTopBottom(hDC, y, &StringRect);
  451. if ((StringRect.top > g_CurMousePos.y) || (StringRect.bottom < g_CurMousePos.y))
  452. {
  453. return NO_CURMOUSEWORD;
  454. }
  455. GetStringRect(hDC, szBuff, cbLen, x, y, &StringRect, lpDx);
  456. nLeft = StringRect.left;
  457. // nLeft = 0;
  458. nPrevWord = nCurrentWord = -1;
  459. while (nCurrentWord < cbLen)
  460. {
  461. CharType     = GetCharType(szBuff[nCurrentWord + 1]);
  462. nPrevWord    = nCurrentWord;
  463. nCurrentWord = GetCurWordEnd(szBuff, nPrevWord + 1, cbLen, CharType);
  464. dwReturn     = CheckMouseInCurWord(hDC, szBuff, cbLen, x, y, lpDx, &nLeft, nPrevWord + 1, nCurrentWord, CharType);
  465. #ifdef _DICTING_
  466. if (dwReturn == HAS_CURMOUSEWORD)
  467. {
  468. if (CharType == CHAR_TYPE_OTHER)
  469. {
  470. PostMessage(g_hNotifyWnd, BL_HASSTRING, 0, 0l);
  471. }
  472. else
  473. {
  474. }
  475. }
  476. else
  477. {
  478. if (g_bMouseInTotalWord)
  479. {
  480. PostMessage(g_hNotifyWnd, BL_HASSTRING, 0, 0l);
  481. }
  482. }
  483. #else
  484. if (dwReturn == HAS_CURMOUSEWORD)
  485. return HAS_CURMOUSEWORD;
  486. #endif
  487. if (nCurrentWord >= cbLen - 1)
  488. return NO_CURMOUSEWORD;
  489. }
  490. return NO_CURMOUSEWORD;   
  491. }
  492. __inline DWORD CheckMouseInCurWord(HDC   hDC, 
  493.    LPSTR szBuff, 
  494.    int   cbLen, 
  495.    int   x, 
  496.    int   y, 
  497.    int   FAR* lpDx,
  498.    int*  lpLeft,
  499.    int   nBegin,    // = nPrevWord + 1
  500.    int   nEnd,
  501.    int   nCharType)
  502. {
  503. RECT  StringRect;
  504. GetStringRect(hDC, szBuff, nEnd + 1, x, y, &StringRect, lpDx);
  505. StringRect.left = *lpLeft;
  506. *lpLeft = StringRect.right;
  507. if (  ((g_CurMousePos.x >= StringRect.left    ) && (g_CurMousePos.x <= StringRect.right))
  508.     || (g_CurMousePos.x == StringRect.left - 1)
  509.     || (g_CurMousePos.x == StringRect.right + 1))
  510. {
  511. switch (nCharType)
  512. {
  513. case CHAR_TYPE_HZ:
  514. case CHAR_TYPE_ASCII:
  515.  CopyWord(g_szCurWord, szBuff, nBegin, nEnd);
  516.  g_CurWordRect.left   = StringRect.left;
  517.  g_CurWordRect.right  = StringRect.right;
  518.  g_CurWordRect.top    = StringRect.top;
  519.  g_CurWordRect.bottom = StringRect.bottom;
  520.  
  521.  g_nCurCaretPlace = -1;
  522.  CalculateCaretPlace(hDC, 
  523.  szBuff, 
  524.  cbLen,
  525.  x,
  526.  y,
  527.  lpDx,
  528.  nBegin,
  529.  nEnd,
  530.  nCharType);
  531.  
  532.  break;
  533. case CHAR_TYPE_OTHER:
  534.  break;
  535. }
  536. AddToTotalWord(szBuff, cbLen, nBegin, nEnd, nCharType, StringRect, TRUE);
  537. if (  (nCharType == CHAR_TYPE_OTHER)
  538.     &&(CalcCaretInThisPlace(g_CurMousePos.x, StringRect.right)))
  539. {
  540. #ifdef _DICTING_
  541. return HAS_CURMOUSEWORD;
  542. #else
  543. return NO_CURMOUSEWORD;
  544. #endif
  545. }
  546. return HAS_CURMOUSEWORD;
  547. }
  548. else
  549. {
  550. }
  551. AddToTotalWord(szBuff, cbLen, nBegin, nEnd, nCharType, StringRect, FALSE);
  552. return NO_CURMOUSEWORD;   
  553. }
  554. // 用於计算指定位置在字串中的位置·
  555. __inline DWORD CalculateCaretPlace(HDC   hDC, 
  556.    LPSTR szBuff, 
  557.    int   cbLen, 
  558.    int   x, 
  559.    int   y, 
  560.    int   FAR* lpDx,
  561.    int   nBegin,    // = nPrevWord + 1
  562.    int   nEnd,
  563.    int   nCharType)
  564. {
  565. RECT  StringRect, BeginRect;
  566. RECT  CaretPrevRect, CaretNextRect;
  567. // int   itemWidth; 
  568. double itemWidth; 
  569. int   TempPlace;
  570. int   i;
  571. if ((nCharType == CHAR_TYPE_HZ) && (nBegin == nEnd))
  572. {
  573. g_nCurCaretPlace = -1;
  574. return 0L;
  575. }
  576. GetStringRect(hDC, szBuff, nBegin, x, y, &BeginRect, lpDx);
  577. GetStringRect(hDC, szBuff, nEnd + 1,   x, y, &StringRect, lpDx);
  578. StringRect.left = BeginRect.right;
  579.     if (StringRect.left == StringRect.right)
  580.     {
  581. g_nCurCaretPlace = -1;
  582. return 0L;
  583.     }
  584. switch (nCharType)
  585. {
  586. case CHAR_TYPE_HZ:
  587. ///////////////////////////////////////////////////////////////////////
  588. // 汉字处理部分·
  589.  // 由於汉字都是等宽的字符,因此对於汉字的计算是通过计算
  590.  // 平均宽度来实现的·
  591. //  itemWidth = (StringRect.right - StringRect.left) / (nEnd - nBegin + 1);
  592. /////////////////////////////////////////////////////////////////
  593. // Modify by GY
  594. // Ver0.036  074号 bug.
  595. // 主要是由於在进行类型转换中有误·  
  596.  itemWidth = ((double)StringRect.right - (double)StringRect.left + 1) / ((double)nEnd - (double)nBegin + 1);
  597. // Modify end
  598. ////////////////////////////////////////////////////////////////////
  599. //  g_nCurCaretPlace = (g_CurMousePos.x - StringRect.left) * (nEnd - nBegin + 1) / (StringRect.right - StringRect.left);
  600.  for (i = 0; i <= (nEnd - nBegin + 1); i++)
  601.  {
  602.   if (CalcCaretInThisPlace(g_CurMousePos.x, (double)((double)StringRect.left + (double)(itemWidth * i))))
  603.   {
  604.   g_nCurCaretPlace = i;
  605.   i = nEnd - nBegin + 2;
  606.   }
  607.  }
  608.              break;
  609. //
  610. ///////////////////////////////////////////////////////////////////////             
  611. case CHAR_TYPE_ASCII:
  612.  // 由於英文字符为不等宽字符· 按以下步骤来计算的:
  613.  // 1. 按等宽计算一个相对位置·
  614.  // 2. 计算该相对位置的的绝对位置·
  615.  // 3. 若在该位置,返回·
  616.  // 4. 若该绝对长小於相对位置乘以宽,转6
  617.  // 5. 向右计算·
  618.  // 6. 向左计算·
  619.  
  620.  // 1. 按等宽计算一个相对位置·
  621.  // 计算宽度·
  622.  itemWidth = (StringRect.right - StringRect.left + 1) / (nEnd - nBegin + 1);
  623.  // 计算位置·
  624.  TempPlace = (g_CurMousePos.x - StringRect.left) * (nEnd - nBegin + 1) / (StringRect.right - StringRect.left);
  625.  
  626.  // 2. 计算该相对位置的的绝对位置·
  627.  GetStringRect(hDC, szBuff, TempPlace,     x, y, &CaretPrevRect, lpDx);
  628.  GetStringRect(hDC, szBuff, TempPlace + 1, x, y, &CaretNextRect, lpDx);
  629.  
  630.  // 3. 若在该位置,返回·
  631.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  632.  {
  633.   g_nCurCaretPlace = TempPlace - nBegin;
  634.   break;
  635.  }
  636.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  637.  {
  638.   g_nCurCaretPlace = TempPlace - nBegin + 1;
  639.   break;
  640.  }
  641.  // 4. 若该绝对长小於相对位置乘以宽,转6
  642.  if (g_CurMousePos.x > CaretNextRect.right)
  643.  {
  644.  // 5. 向右计算·      
  645.  GetEngLishCaretPlace(hDC, 
  646.   szBuff,
  647.   x,
  648.   y,
  649.   lpDx,
  650.   nBegin,    // = nPrevWord + 1
  651.   nEnd,
  652.   TempPlace,
  653.   RIGHT);
  654.  }
  655.  else
  656.  {
  657.  // 6. 向左计算·
  658.  GetEngLishCaretPlace(hDC, 
  659.   szBuff,
  660.   x,
  661.   y,
  662.   lpDx,
  663.   nBegin,    // = nPrevWord + 1
  664.   nEnd,
  665.   TempPlace,
  666.   LEFT);
  667.  }
  668.  
  669.  break;
  670. }
  671. return 0L;
  672. }
  673. __inline DWORD GetEngLishCaretPlace(HDC   hDC, 
  674. LPSTR szBuff,
  675. int   x,
  676. int   y,
  677. int   FAR* lpDx,
  678. int   nBegin,    // = nPrevWord + 1
  679. int   nEnd,
  680. int   TempPlace,
  681. int   turnto)
  682. {
  683. int i;
  684. RECT  CaretPrevRect, CaretNextRect;
  685. if (turnto == RIGHT)
  686. {
  687. i = TempPlace;
  688. GetStringRect(hDC, szBuff, i, x, y, &CaretPrevRect, lpDx);
  689. for (i = TempPlace; i <= nEnd; i++)
  690. {
  691.  GetStringRect(hDC, szBuff, i + 1, x, y, &CaretNextRect, lpDx);
  692.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  693.  {
  694.   g_nCurCaretPlace = i - nBegin;
  695.   return 0;
  696.  }
  697.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  698.  {
  699.   g_nCurCaretPlace = i - nBegin + 1;
  700.   return 0;
  701.  }
  702.  CopyRect(&CaretPrevRect, &CaretNextRect);
  703. }
  704. g_nCurCaretPlace = nEnd - nBegin + 1;
  705. }
  706. else
  707. {
  708. i = TempPlace;
  709. GetStringRect(hDC, szBuff, i + 1, x, y, &CaretNextRect, lpDx);
  710. for (i = TempPlace; i >= nBegin; i--)
  711. {
  712.  GetStringRect(hDC, szBuff, i, x, y, &CaretPrevRect, lpDx);
  713.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretPrevRect.right)) 
  714.  {
  715.   g_nCurCaretPlace = i - nBegin;
  716.   return 0;
  717.  }
  718.  if (CalcCaretInThisPlace(g_CurMousePos.x, CaretNextRect.right))
  719.  {
  720.   g_nCurCaretPlace = i - nBegin + 1;
  721.   return 0;
  722.  }
  723.  CopyRect(&CaretNextRect, &CaretPrevRect);
  724. }
  725. g_nCurCaretPlace = nBegin - nBegin;
  726. }
  727. return 0;
  728. }
  729. //BOOL CalcCaretInThisPlace(int CaretX, int nPlace)
  730. BOOL CalcCaretInThisPlace(int CaretX, double nPlace)
  731. {
  732. if (((double)CaretX >= nPlace - 3)&&((double)CaretX <= nPlace + 1))
  733. {
  734. return TRUE;
  735. }
  736. return FALSE;
  737. }
  738. // Get current Chinese char that under the mouse cursor.
  739. // 1.                       2
  740. // mouse place :    |            |
  741. // chinese char:  英业达      英业达
  742. // return place:    |           |
  743. __inline int GetHZBeginPlace(LPSTR lpszHzBuff, int nBegin, int nEnd, LPRECT lpStringRect)
  744. {
  745. int itemWidth; 
  746. int nReturn;
  747. itemWidth = (lpStringRect->right - lpStringRect->left + 1) / (nEnd - nBegin + 1);
  748. // nReturn = (g_CurMousePos.x - lpStringRect->left) / itemWidth;
  749. nReturn = (g_CurMousePos.x - lpStringRect->left) * (nEnd - nBegin + 1) / (lpStringRect->right - lpStringRect->left);
  750. if (nReturn == 0)
  751. return nBegin;
  752.     
  753. if (nReturn % 2 == 1)
  754. {
  755.      lpStringRect->left = lpStringRect->left + (nReturn - 1) * itemWidth;
  756.      return nBegin + nReturn - 1;
  757.     }
  758.     
  759.     lpStringRect->left = lpStringRect->left + nReturn * itemWidth;
  760. return (nBegin + nReturn);
  761. }
  762. //=========================================================
  763. //
  764. //  FUNCTION: void AddToTotalWord(LPSTR, int, int, int, int, RECT, BOOL);
  765. //
  766. //  PURPOSE:  用於将多次文本输出的单词合并为一个完整单词·
  767. //
  768. //  PARAMETER: 
  769. //       
  770. //       LPSTR : 由 TextOut 或 ExtTextOut 函数传递的字符串·
  771. //       int   : 字符串长·
  772. //       int   : 由切词程序处理後的单词在串中的起始位置·( 0 代表串的第一字节 )
  773. //       int   : 由切词程序处理後的单词在串中的结束位置·( 0 代表串的第一字节 )
  774. //       int   : 代表由 nBegin, nEnd 指定的单词的性质 ( 中文/英文/其他字符)
  775. //       RECT  : 代表由 nBegin, nEnd 指定的单词的区域·
  776. //       BOOL  : 用於判断当前鼠标位置是否在该单词中·
  777. //
  778. //  COMMENTS:
  779. //
  780. //
  781. //=========================================================
  782. _inline void AddToTotalWord(LPSTR szBuff, 
  783. int   cbLen, 
  784. int   nBegin,
  785. int   nEnd,
  786. int   nCharType,
  787. RECT  StringRect,   
  788. BOOL  bInCurWord)
  789. {
  790. int nPos = 0 ; //temp variable
  791. if ((nCharType == CHAR_TYPE_OTHER) && (!g_bMouseInTotalWord))
  792. {
  793. // 处理串开始为空格的情况·
  794. g_szTotalWord[0] = 0x00;
  795. g_CharType = nCharType;
  796. g_bMouseInTotalWord = FALSE;
  797. return;
  798. }
  799. //Added by XGL, see GetCurWordEnd for reasons
  800. if (((BYTE)(szBuff[nBegin]) >= 0xa1 && (BYTE)(szBuff[nBegin]) <= 0xa9)
  801. && (!g_bMouseInTotalWord))
  802. {
  803. // 处理串开始为空格的情况·
  804. g_szTotalWord[0] = 0x00;
  805. g_CharType = CHAR_TYPE_HZ;
  806. g_bMouseInTotalWord = FALSE;
  807. return;
  808. }
  809. if ((g_szTotalWord[0] == 0x00)&&(nCharType != CHAR_TYPE_OTHER))
  810. {
  811. // 如果完整词缓冲区为空,并且单词为中文或英文,
  812. // 拷贝字符串·
  813. CopyWord(g_szTotalWord, szBuff, nBegin, nEnd);
  814. g_TotalWordRect.left   = StringRect.left;
  815. g_TotalWordRect.right  = StringRect.right;
  816. g_TotalWordRect.top    = StringRect.top;
  817. g_TotalWordRect.bottom = StringRect.bottom;
  818. g_CharType = nCharType;
  819. if (bInCurWord)
  820. {
  821. g_bMouseInTotalWord = TRUE;
  822. //Added by XGL, Sep 17th, 1998
  823. //When the word pointed to by mouse was got,
  824. //attain it's char-type.
  825. g_nPhraseCharType = nCharType ;
  826. g_nWordsInPhrase++ ;
  827. //Adding ends.
  828. //Added by XGL, Sep 29th, 1998
  829. g_rcFirstWordRect.left   = StringRect.left;
  830. g_rcFirstWordRect.right  = StringRect.right;
  831. g_rcFirstWordRect.top    = StringRect.top;
  832. g_rcFirstWordRect.bottom = StringRect.bottom;
  833. //Adding ends.
  834. }
  835. else
  836. {
  837. g_bMouseInTotalWord = FALSE;
  838. }
  839. g_nCurCaretPlaceInTotalWord = -1;
  840. if (g_nCurCaretPlace != -1)
  841. {
  842. g_nCurCaretPlaceInTotalWord = g_nCurCaretPlace;
  843. }
  844. return;
  845. }
  846. if (!g_bMouseInTotalWord)
  847. {
  848. // Added by XGL
  849. //(nCharType == CHAR_TYPE_OTHER) && (!g_bMouseInTotalWord)
  850. //See the line above. How can conditions
  851. //in the following line happen.
  852. //Adding ends.
  853. /* if ((nCharType == CHAR_TYPE_OTHER)&&(g_CharType != nCharType))
  854. {
  855. // Clear buffer.
  856. g_szTotalWord[0] = 0x00;
  857. g_CharType = CHAR_TYPE_OTHER;
  858. g_bMouseInTotalWord = FALSE;
  859. g_nCurCaretPlaceInTotalWord = -1;
  860. if (g_nCurCaretPlace != -1)
  861. {
  862. g_nCurCaretPlaceInTotalWord = g_nCurCaretPlace;
  863. }
  864. return;
  865. }
  866. */
  867. if (g_CharType != nCharType)
  868. {
  869. CopyWord(g_szTotalWord, szBuff, nBegin, nEnd);
  870. g_TotalWordRect.left   = StringRect.left;
  871. g_TotalWordRect.right  = StringRect.right;
  872. g_TotalWordRect.top    = StringRect.top;
  873. g_TotalWordRect.bottom = StringRect.bottom;
  874. g_CharType = nCharType;
  875. if (bInCurWord)
  876. {
  877. g_bMouseInTotalWord = TRUE;
  878. //Added by XGL, Sep 17th, 1998
  879. //When the word pointed to by mouse was got,
  880. //attain it's char-type.
  881. g_nPhraseCharType = nCharType ;
  882. g_nWordsInPhrase++ ;
  883. //Adding ends.
  884. //Added by XGL, Sep 29th, 1998
  885. g_rcFirstWordRect.left   = StringRect.left;
  886. g_rcFirstWordRect.right  = StringRect.right;
  887. g_rcFirstWordRect.top    = StringRect.top;
  888. g_rcFirstWordRect.bottom = StringRect.bottom;
  889. //Adding ends.
  890. }
  891. else
  892. {
  893. g_bMouseInTotalWord = FALSE;
  894. }
  895. g_nCurCaretPlaceInTotalWord = -1;
  896. if (g_nCurCaretPlace != -1)
  897. {
  898. g_nCurCaretPlaceInTotalWord = g_nCurCaretPlace;
  899. }
  900. return;
  901. }
  902. }
  903. //Added by XGL
  904. //g_bMouseInTotalWord == FALSE && g_CharType != nCharType
  905. //has been dealed with.
  906. //Adding ends.
  907. if ((g_CharType != nCharType)) 
  908. {
  909. /* if (bInCurWord)
  910. {
  911. //Added by XGL
  912. //How can this condition happen
  913. //Adding ends.
  914. if (!g_bMouseInTotalWord)
  915. {
  916. CopyWord(g_szTotalWord, szBuff, nBegin, nEnd);
  917. g_TotalWordRect.left   = StringRect.left;
  918. g_TotalWordRect.right  = StringRect.right;
  919. g_TotalWordRect.top    = StringRect.top;
  920. g_TotalWordRect.bottom = StringRect.bottom;
  921. g_CharType = nCharType;
  922. g_bMouseInTotalWord = TRUE;
  923. g_nCurCaretPlaceInTotalWord = g_nCurCaretPlace;
  924. }
  925. }
  926. */
  927. //Added by XGL
  928. //now, g_bMouseInTotalWord == TRUE
  929. //let space char go through since we want to get phrase
  930. if ( ((nCharType == CHAR_TYPE_OTHER) && (szBuff[nBegin] == ' '))
  931.  || ((nCharType != CHAR_TYPE_OTHER)
  932.  && (g_nPhraseCharType == nCharType)) )
  933. {
  934. //Modified by XGL, don't allow space char in Chinese
  935. // if (   g_bPhraseNeeded 
  936. //    &&(g_nWordsInPhrase > MIN_WORDS_IN_PHRASE)
  937. //    &&(g_nWordsInPhrase < MAX_WORDS_IN_PHRASE) )
  938. if (   g_bPhraseNeeded 
  939.    &&(g_nWordsInPhrase > MIN_WORDS_IN_PHRASE)
  940.    &&(g_nWordsInPhrase < MAX_WORDS_IN_PHRASE)
  941.    &&(!(g_szTotalWord[0] < 0 && szBuff[nBegin] == ' ')) )
  942. {
  943. }
  944. else
  945. {
  946. g_nWordsInPhrase = MAX_WORDS_IN_PHRASE + 1 ;
  947. return;
  948. }
  949. }
  950. else
  951. {
  952. g_nWordsInPhrase = MAX_WORDS_IN_PHRASE + 1 ;
  953. return;
  954. }
  955. //Adding ends.
  956. }
  957. /* //Added by XGL, Sep 17th, 1998
  958. if ( g_bMouseInTotalWord && g_bPhraseNeeded
  959.  && (strlen(g_szTotalWord) > MAX_WORDS_IN_PHRASE * 2)
  960.  && (g_nPhraseCharType == CHAR_TYPE_HZ) )
  961. {
  962. //We cann't count Chinese words using space char
  963. //so g_nWordsInPhrase is useless now
  964. g_nWordsInPhrase = MAX_WORDS_IN_PHRASE + 1 ;
  965. }
  966. //Adding ends.
  967. */
  968. if (  ((UINT)(StringRect.left - g_TotalWordRect.right) <= (UINT)SEPERATOR)
  969. &&(abs((int)(StringRect.bottom - g_TotalWordRect.bottom)) <= SEPERATOR))
  970. {
  971. //Added by XGL, see GetCurWordEnd for reasons. Nov 13th, 1998.
  972. if ((BYTE)(szBuff[nBegin]) >= 0xa1 
  973. && (BYTE)(szBuff[nBegin]) <= 0xa9)
  974. {
  975. return;
  976. }
  977. //Adding ends. XGL, Nov 13th, 1998.
  978. //Added by XGL, Sep 17th, 1998
  979. if (g_bMouseInTotalWord && g_bPhraseNeeded
  980. && (g_nWordsInPhrase > MIN_WORDS_IN_PHRASE)
  981. && (g_nWordsInPhrase < MAX_WORDS_IN_PHRASE)
  982. && (szBuff[nBegin] == ' '))
  983. {
  984. //other chars between nBegin and nEnd must be space
  985. nPos = nBegin ;
  986. while (szBuff[nPos] == ' ' && nPos <= nEnd)
  987. {
  988. nPos++ ;
  989. }      
  990. //Modified by XGL, Nov 11th, 1998  
  991. //We allow just one space between words of a phrase
  992. //if (nPos <= nEnd)      
  993. if (nPos <= nEnd || nPos - nBegin > 1)
  994. {
  995. //stop get word
  996. g_nWordsInPhrase = MAX_WORDS_IN_PHRASE + 1 ;
  997. }
  998. else
  999. {
  1000. g_nWordsInPhrase++ ;
  1001. }
  1002. }
  1003. if (g_nWordsInPhrase >= MAX_WORDS_IN_PHRASE)
  1004. {
  1005. //enough words, no need to do more work
  1006. return ;
  1007. }
  1008. //Adding ends.
  1009. if ((g_nCurCaretPlace != -1)&&(g_nCurCaretPlaceInTotalWord == -1))
  1010. {
  1011. g_nCurCaretPlaceInTotalWord = strlen(g_szTotalWord) + g_nCurCaretPlace;
  1012. }
  1013. CopyWord(g_szTotalWord + strlen(g_szTotalWord), szBuff, nBegin, nEnd);
  1014. g_TotalWordRect.right  = StringRect.right;
  1015. //Added by XGL, Sep 29th, 1998
  1016. if (!strchr(g_szTotalWord, ' ') && (*(szBuff + nBegin) != ' '))
  1017. {
  1018. g_rcFirstWordRect.right  = StringRect.right;
  1019. }
  1020. //Adding ends.
  1021. if (bInCurWord)
  1022. {
  1023. g_bMouseInTotalWord = TRUE;
  1024. //Added by XGL, Sep 17th, 1998
  1025. //When the word pointed to by mouse was got,
  1026. //attain it's char-type.        
  1027. g_nPhraseCharType = nCharType ;
  1028. g_nWordsInPhrase++ ;
  1029. //Adding ends.
  1030. //Added by XGL, Sep 29th, 1998
  1031. g_rcFirstWordRect.left   = StringRect.left;
  1032. g_rcFirstWordRect.right  = StringRect.right;
  1033. g_rcFirstWordRect.top    = StringRect.top;
  1034. g_rcFirstWordRect.bottom = StringRect.bottom;
  1035. //Adding ends.
  1036. }
  1037. }
  1038. else
  1039. {
  1040. if (!g_bMouseInTotalWord)
  1041. {
  1042. CopyWord(g_szTotalWord, szBuff, nBegin, nEnd);
  1043. g_TotalWordRect.left   = StringRect.left;
  1044. g_TotalWordRect.right  = StringRect.right;
  1045. g_TotalWordRect.top    = StringRect.top;
  1046. g_TotalWordRect.bottom = StringRect.bottom;
  1047. g_CharType = nCharType;
  1048. g_bMouseInTotalWord = FALSE;
  1049. g_nCurCaretPlaceInTotalWord = -1;
  1050. if (g_nCurCaretPlace != -1)
  1051. {
  1052. g_nCurCaretPlaceInTotalWord = g_nCurCaretPlace;
  1053. }
  1054. if (bInCurWord)
  1055. {
  1056. g_bMouseInTotalWord = TRUE;
  1057. //Added by XGL, Sep 17th, 1998
  1058. //When the word pointed to by mouse was got,
  1059. //attain it's char-type.
  1060. g_nPhraseCharType = nCharType ;
  1061. g_nWordsInPhrase++ ;
  1062. //Adding ends.
  1063. //Added by XGL, Sep 29th, 1998
  1064. g_rcFirstWordRect.left   = StringRect.left;
  1065. g_rcFirstWordRect.right  = StringRect.right;
  1066. g_rcFirstWordRect.top    = StringRect.top;
  1067. g_rcFirstWordRect.bottom = StringRect.bottom;
  1068. //Adding ends.
  1069. }
  1070. }
  1071. }
  1072. }
  1073. ////////////////////////////////////////////////////////////////////
  1074. // Deal with memdc string.
  1075. void AddToTextOutBuffer(HDC hMemDC, LPSTR szBuff, int cbLen, int x, int y, int FAR* lpDx)
  1076. {
  1077. int  nPrevWord, nCurrentWord, CharType;
  1078. RECT PrevWordRect, NextWordRect;
  1079. int  nLen, i;
  1080. if (cbLen >= (int)(BUFFERLENGTH - strlen(szMemDCWordBuff) - 2))
  1081. {
  1082. // buffer too small.
  1083. return;
  1084. }
  1085. // Write string to buffer.
  1086. nLen = strlen(szMemDCWordBuff);
  1087. strncpy(szMemDCWordBuff + nLen, szBuff, cbLen);
  1088. szMemDCWordBuff[nLen + cbLen    ] = ' ';
  1089. szMemDCWordBuff[nLen + cbLen + 1] = 0x00;
  1090. nPrevWord = nCurrentWord = -1;
  1091. while (nCurrentWord < cbLen)
  1092. {
  1093. //////////////////////////////////////////////////////////////
  1094. // Modified by Yan/gang 1998.02.20
  1095. // Reason: 
  1096. //         It cause the system destroy when the user run "WBLASTER"
  1097. //         The reason is the the array is overflow.
  1098. //         The WordBuffer array size is MEMDC_MAXNUM.
  1099. //         But it's point (nWordNum) is large than MEMDC_MAXNUM,
  1100. //         also, nWordNum is small than MAXNUM.
  1101. // if (nWordNum >= MAXNUM)
  1102. if (nWordNum >= MEMDC_MAXNUM)
  1103. break;
  1104. // Modify end.
  1105. //////////////////////////////////////////////////////////////
  1106. CharType     = GetCharType(szBuff[nCurrentWord + 1]);
  1107. nPrevWord    = nCurrentWord;
  1108. nCurrentWord = GetCurWordEnd(szBuff, nPrevWord + 1, cbLen, CharType);
  1109. GetStringRect(hMemDC, szBuff, nPrevWord + 1, x, y, &PrevWordRect, lpDx);
  1110. GetStringRect(hMemDC, szBuff, nCurrentWord + 1 , x, y, &NextWordRect, lpDx);
  1111. WordBuffer[nWordNum].nBegin = nLen + nPrevWord + 1;
  1112. WordBuffer[nWordNum].nEnd   = nLen + nCurrentWord;
  1113. WordBuffer[nWordNum].hMemDC = hMemDC;
  1114. WordBuffer[nWordNum].CharType = CharType;
  1115. WordBuffer[nWordNum].wordRect.left   = PrevWordRect.right;
  1116. WordBuffer[nWordNum].wordRect.right  = NextWordRect.right;
  1117. WordBuffer[nWordNum].wordRect.top    = NextWordRect.top;
  1118. WordBuffer[nWordNum].wordRect.bottom = NextWordRect.bottom;
  1119. nWordNum++;
  1120. if (nCurrentWord >= cbLen - 1)
  1121. break;
  1122. }
  1123. GetStringLeftRight(hMemDC, szBuff, 0, x, &PrevWordRect, lpDx);
  1124. for (i = 0; i < cbLen; i++)
  1125. {
  1126. GetStringLeftRight(hMemDC, szBuff, i+1, x, &NextWordRect, lpDx);
  1127. pnMemDCCharLeft[nLen + i]  = PrevWordRect.right;
  1128. pnMemDCCharRight[nLen + i] = NextWordRect.right;
  1129. CopyRect(&PrevWordRect, &NextWordRect);
  1130. }
  1131. }
  1132. void GetMemWordStringRect(int nWordCode, int nOffset, LPRECT lpStringRect)
  1133. {
  1134. POINT  WndPos;
  1135. int    nNum;
  1136. if (nWordCode >= nWordNum)
  1137. {
  1138. lpStringRect->left   = 0;
  1139. lpStringRect->right  = 0;
  1140. lpStringRect->top    = 0;
  1141. lpStringRect->bottom = 0;
  1142. return;
  1143. }
  1144. CopyRect(lpStringRect, &(WordBuffer[nWordCode].wordRect));
  1145. if (nOffset != MEMDC_TOTALWORD)
  1146. {
  1147. nNum = WordBuffer[nWordCode].nBegin + nOffset;
  1148. lpStringRect->left = pnMemDCCharLeft[nNum];
  1149. // lpStringRect->left = pnMemDCCharRight[nNum];
  1150. lpStringRect->right = pnMemDCCharRight[nNum];
  1151. }
  1152. WndPos.x = LOWORD(g_dwDCOrg);
  1153. WndPos.y = HIWORD(g_dwDCOrg);
  1154. lpStringRect->top    = lpStringRect->top    + WndPos.y;
  1155. lpStringRect->bottom = lpStringRect->bottom + WndPos.y;
  1156. lpStringRect->left   = lpStringRect->left   + WndPos.x;
  1157. lpStringRect->right  = lpStringRect->right  + WndPos.x;
  1158. }
  1159. void CheckMemDCWordBuffer(HDC hdcdest, HDC hdcSrc)
  1160. {
  1161. int i;
  1162. for (i = 0; i < nWordNum; i++)
  1163. {
  1164. if (WordBuffer[i].hMemDC == hdcSrc)
  1165. {
  1166. CheckMouseInMemDCWord(i);
  1167. }
  1168. else
  1169. {
  1170. #ifdef _DICTING_
  1171. if (CheckDCWndClassName(hdcdest))
  1172. {
  1173. CheckMouseInMemDCWord(i);
  1174. }
  1175. #endif
  1176. }
  1177. // CheckMouseInMemDCWord(i);
  1178. }                               
  1179. }
  1180. #ifdef _DICTING_
  1181. #define IE4_CLIENT_CLASSNAME "Internet Explorer_Server"// 定义取词中 DC 所属窗口的类名。
  1182. #define OUTLOOK_EDIT_CLASSNAME "RichEdit20A"
  1183. #define MAX_CLASS_NAME 256
  1184. extern WINDOWFROMDC_PROC WindowFromDC;
  1185. int  g_nWorkOnClassNum = 2;
  1186. char g_szWorkOnClassName[2][MAX_CLASS_NAME] = { 
  1187. IE4_CLIENT_CLASSNAME, // IE 4.0
  1188. OUTLOOK_EDIT_CLASSNAME // OutLook
  1189. };
  1190. _inline BOOL CheckDCWndClassName(HDC hDC)
  1191. {
  1192. HWND hWndFromDC;
  1193. char szClassName[MAX_CLASS_NAME];
  1194. int i;
  1195. hWndFromDC = WindowFromDC(hDC);
  1196. GetClassName(hWndFromDC, szClassName, MAX_CLASS_NAME);
  1197. for (i = 0; i < g_nWorkOnClassNum; i++)
  1198. {
  1199. if (lstrcmp(szClassName, (LPSTR)g_szWorkOnClassName[i]) == 0)
  1200. {
  1201. return TRUE;
  1202. }
  1203.     }
  1204. return FALSE;
  1205. }
  1206. #endif
  1207. __inline DWORD CheckMouseInMemDCWord(int nWordCode)
  1208. {
  1209. RECT  StringRect;
  1210. GetMemWordStringRect(nWordCode, MEMDC_TOTALWORD, &StringRect);
  1211. // if (PtInRect(&StringRect, g_CurMousePos))
  1212. if (  (StringRect.left   <= g_CurMousePos.x)
  1213. &&(StringRect.right  >= g_CurMousePos.x)
  1214. &&(StringRect.top    <= g_CurMousePos.y)
  1215. &&(StringRect.bottom >= g_CurMousePos.y))
  1216. {
  1217. switch (WordBuffer[nWordCode].CharType)
  1218. {
  1219. case CHAR_TYPE_HZ:
  1220. case CHAR_TYPE_ASCII:
  1221.  CopyWord(g_szCurWord, szMemDCWordBuff, WordBuffer[nWordCode].nBegin, WordBuffer[nWordCode].nEnd);
  1222.  g_CurWordRect.left   = StringRect.left;
  1223.  g_CurWordRect.right  = StringRect.right;
  1224.  g_CurWordRect.top    = StringRect.top;
  1225.  g_CurWordRect.bottom = StringRect.bottom;
  1226.  
  1227.  g_nCurCaretPlace = -1;
  1228.  CalculateCaretPlaceInMemDCWord(nWordCode);
  1229.  
  1230.  break;
  1231. case CHAR_TYPE_OTHER:
  1232.  break;
  1233. }
  1234. AddToTotalWord(szMemDCWordBuff, 
  1235. 0,  // Ignor
  1236. WordBuffer[nWordCode].nBegin, 
  1237. WordBuffer[nWordCode].nEnd, 
  1238. WordBuffer[nWordCode].CharType, 
  1239. StringRect, 
  1240. TRUE);
  1241. if (  (WordBuffer[nWordCode].CharType == CHAR_TYPE_OTHER)
  1242.     &&(g_CurMousePos.x == StringRect.right))
  1243. {
  1244. return NO_CURMOUSEWORD;
  1245. }
  1246. return HAS_CURMOUSEWORD;
  1247. }
  1248. else
  1249. {
  1250. }
  1251. AddToTotalWord(szMemDCWordBuff, 
  1252.    0,  // Ignor
  1253.    WordBuffer[nWordCode].nBegin, 
  1254.    WordBuffer[nWordCode].nEnd, 
  1255.    WordBuffer[nWordCode].CharType, 
  1256.    StringRect, 
  1257.    FALSE);
  1258. return NO_CURMOUSEWORD;   
  1259. }
  1260. // 用於计算指定位置在字串中的位置·
  1261. __inline DWORD CalculateCaretPlaceInMemDCWord(int nWordCode)
  1262. {
  1263. RECT  StringRect;
  1264. int   i;
  1265. if (  (WordBuffer[nWordCode].CharType == CHAR_TYPE_HZ) 
  1266.     &&(WordBuffer[nWordCode].nBegin    == WordBuffer[nWordCode].nEnd))
  1267. {
  1268. g_nCurCaretPlace = -1;
  1269. return 0L;
  1270. }
  1271. GetMemWordStringRect(nWordCode, MEMDC_TOTALWORD, &StringRect);
  1272. if (CalcCaretInThisPlace(g_CurMousePos.x, StringRect.left))
  1273. {
  1274. // g_nCurCaretPlace = WordBuffer[nWordCode].nBegin;
  1275. g_nCurCaretPlace = 0;
  1276. return 0l;
  1277. }
  1278. if (CalcCaretInThisPlace(g_CurMousePos.x, StringRect.right))
  1279. {
  1280. // g_nCurCaretPlace = WordBuffer[nWordCode].nEnd + 1;
  1281. g_nCurCaretPlace = WordBuffer[nWordCode].nEnd - WordBuffer[nWordCode].nBegin + 1;
  1282. return 0l;
  1283. }
  1284. for (i = WordBuffer[nWordCode].nBegin; i <= WordBuffer[nWordCode].nEnd; i++)
  1285. {
  1286. GetMemWordStringRect(nWordCode, i - WordBuffer[nWordCode].nBegin, &StringRect);
  1287. if (CalcCaretInThisPlace(g_CurMousePos.x, StringRect.right))
  1288. {
  1289. // g_nCurCaretPlace = i + 1;
  1290. g_nCurCaretPlace = i - WordBuffer[nWordCode].nBegin + 1;
  1291. return 0l;
  1292. }
  1293. }
  1294. return 0L;
  1295. }
  1296. /*
  1297. if (nCurCharNum != nFromPlace)
  1298. {
  1299. #ifdef _DEBUG
  1300. DbgPrintf("NhWSrh.DLL          nCurCharNum != nFromPlace");
  1301. #endif
  1302. return TRUE;
  1303. }
  1304. if (  (nCurCharNum == nLength - 1)
  1305. &&(lpString[nCurCharNum] == CHAR_LINK)
  1306.    ||(lpString[nCurCharNum] == '?')
  1307.    ||(lpString[nCurCharNum] == '*'))
  1308. {
  1309. return FALSE;
  1310. }
  1311. if (  (nCurCharNum != nFromPlace)
  1312. &&   (lpString[nCurCharNum] == CHAR_LINK)
  1313.    ||(lpString[nCurCharNum] == '?')
  1314.    ||(lpString[nCurCharNum] == '*'))
  1315. {
  1316. #ifdef _DEBUG
  1317. DbgPrintf("NhWSrh.DLL          3");
  1318. #endif
  1319. return TRUE;
  1320. }
  1321. if ((nCurCharNum == '?') || (nCurCharNum == '*'))
  1322. {
  1323. #ifdef _DEBUG
  1324. DbgPrintf("NhWSrh.DLL          *?");
  1325. #endif
  1326. if (nCurCharNum == nLength - 1)
  1327. {
  1328. #ifdef _DEBUG
  1329. DbgPrintf("NhWSrh.DLL          nCurCharNum == nLength - 1");
  1330. #endif
  1331. return FALSE;
  1332. }
  1333. if (GetCharType(lpString[nCurCharNum + 1]) != CHAR_TYPE_ASCII)
  1334. {
  1335. #ifdef _DEBUG
  1336. DbgPrintf("NhWSrh.DLL          etCharType(lpString[nCurCharNum + 1]) != CHAR_TYPE_ASCII");
  1337. #endif
  1338. return FALSE;
  1339. }
  1340. if (nCurCharNum == nFromPlace)
  1341. {
  1342. #ifdef _DEBUG
  1343. DbgPrintf("NhWSrh.DLL          nCurCharNum == nFromPlace");
  1344. #endif
  1345. return FALSE;
  1346. }
  1347. return TRUE;
  1348. }
  1349. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  1350. {
  1351. int i = nFromPlace;
  1352. int j;
  1353. while (i < nLength)
  1354. {
  1355. if (  (lpString[i] == '?')
  1356.     ||(lpString[i] == '*'))
  1357. {
  1358. #ifdef _DEBUG
  1359. DbgPrintf("NhWSrh.DLL          ?*");
  1360. #endif
  1361. if (i == nLength - 1)
  1362. {
  1363. #ifdef _DEBUG
  1364. DbgPrintf("NhWSrh.DLL          i == nLength - 1");
  1365. #endif
  1366. // return i - 1;
  1367. return i;
  1368. }
  1369. j = i;
  1370. while(j < nLength)
  1371. {
  1372. if ((lpString[j] != '?')&&(lpString[j] != '*'))
  1373. {
  1374. #ifdef _DEBUG
  1375. DbgPrintf("NhWSrh.DLL          is not ?*");
  1376. #endif
  1377. break;
  1378. }
  1379. j++;
  1380. }
  1381. if (j == nLength)
  1382. return j-1;
  1383. if (IsASCIIWord(lpString, nFromPlace, nLength, j))
  1384. {
  1385. i = j;
  1386. }
  1387. else
  1388. {
  1389. // return i - 1;
  1390. return j - 1;
  1391. }
  1392. }
  1393. // 用於处理 '-' 的几种情况·
  1394. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  1395. // if (GetCharType(lpString[i]) == CHAR_TYPE_ASCII)
  1396. {
  1397. i++;
  1398. }
  1399. else
  1400. {
  1401. return i-1;
  1402. }
  1403. return nLength - 1;
  1404. }
  1405. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  1406. {
  1407. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  1408. {
  1409. return TRUE;
  1410. }
  1411. if (lpString[nCurCharNum] == CHAR_LINK)
  1412. {
  1413. if (nCurCharNum == nLength - 1)
  1414. {
  1415. return FALSE;
  1416. }
  1417. if (GetCharType(lpString[nCurCharNum + 1]) == CHAR_TYPE_ASCII)
  1418. {
  1419. return TRUE;
  1420. }
  1421. }
  1422. /* if (  (lpString[nCurCharNum] == '?')
  1423. ||(lpString[nCurCharNum] == '*'))
  1424. {
  1425. if (nCurCharNum == nLength - 1)
  1426. {
  1427. return FALSE;
  1428. }
  1429. nCurCharNum++;
  1430. while(nCurCharNum < nLength)
  1431. {
  1432. if (GetCharType(lpString[nCurCharNum]) ==
  1433. }
  1434. // if (GetCharType(lpString[nCurCharNum + 1]) == CHAR_TYPE_ASCII)
  1435. // {
  1436. // return TRUE;
  1437. // }
  1438. }*/
  1439. // return FALSE;
  1440. //}
  1441. //*/
  1442. /*
  1443. __inline int  FindAWord(LPCSTR lpString, int nFromPlace, int nLength)
  1444. {
  1445. int i = nFromPlace;
  1446. // int j;
  1447. while (i < nLength)
  1448. {
  1449. if (lpString[i] == CHAR_LINK)
  1450. {
  1451. if (IsASCIIWord(lpString, nFromPlace, nLength, i + 1))
  1452. {
  1453. i++;
  1454. }
  1455. else
  1456. {
  1457. return i-1;
  1458. }
  1459. }
  1460. else
  1461. {
  1462. // 用於处理 '-' 的几种情况·
  1463. if (IsASCIIWord(lpString, nFromPlace, nLength, i))
  1464. // if (GetCharType(lpString[i]) == CHAR_TYPE_ASCII)
  1465. {
  1466. i++;
  1467. }
  1468. else
  1469. {
  1470. return i-1;
  1471. }
  1472. }
  1473. return nLength - 1;
  1474. }
  1475. __inline BOOL IsASCIIWord(LPCSTR lpString, int nFromPlace, int nLength, int nCurCharNum)
  1476. {
  1477. if (GetCharType(lpString[nCurCharNum]) == CHAR_TYPE_ASCII)
  1478. {
  1479. return TRUE;
  1480. }
  1481.     
  1482. if (lpString[nCurCharNum] == CHAR_WILDCHAR1)
  1483. {
  1484. return TRUE;
  1485. }
  1486. if (lpString[nCurCharNum] == CHAR_WILDCHAR2)
  1487. {
  1488. return TRUE;
  1489. }
  1490. // if (lpString[nCurCharNum] == CHAR_LINK)
  1491. // {
  1492. // if (nCurCharNum == nLength - 1)
  1493. // {
  1494. // return FALSE;
  1495. // }
  1496. // if (GetCharType(lpString[nCurCharNum + 1]) == CHAR_TYPE_ASCII)
  1497. // {
  1498. // return TRUE;
  1499. // }
  1500. // }
  1501. return FALSE;
  1502. }
  1503. */