Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

761 lines
18 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* util.c -- more frequently used utility routines */
  5. #define NOCOLOR
  6. #define NOCOMM
  7. #define NOCLIPBOARD
  8. #define NOCTLMGR
  9. #define NOGDICAPMASKS
  10. #define NOMENUS
  11. #define NOSOUND
  12. #define NOVIRTUALKEYCODES
  13. #define NOWINMESSAGES
  14. #define NOWINSTYLES
  15. #include <windows.h>
  16. #if WINVER < 0x300
  17. #define SM_CURSORLEVEL 25
  18. #endif
  19. #include "mw.h"
  20. #include "doslib.h"
  21. #include "str.h"
  22. #include "machdefs.h"
  23. #include "cmddefs.h"
  24. #include "propdefs.h"
  25. #include "fkpdefs.h"
  26. #include "docdefs.h"
  27. #include "debug.h"
  28. #include "editdefs.h"
  29. #include "wwdefs.h"
  30. #define NOKCCODES
  31. #include "ch.h"
  32. extern struct DOD (**hpdocdod)[];
  33. extern HANDLE hMmwModInstance;
  34. CHAR *PchFillPchId(PCH, int);
  35. typeCP CpMax(cp1, cp2)
  36. typeCP cp1, cp2;
  37. {{ /* return larger of two cps */
  38. return((cp1 > cp2) ? cp1 : cp2);
  39. }} /* end of C p M a x */
  40. typeCP CpMin(cp1, cp2)
  41. typeCP cp1, cp2;
  42. {{ /* return smaller of two cps */
  43. return((cp1 < cp2) ? cp1 : cp2);
  44. }} /* end of C p M i n */
  45. unsigned umin( w1, w2 )
  46. register unsigned w1, w2;
  47. { return (w1 < w2) ? w1 : w2; }
  48. unsigned umax( w1, w2 )
  49. register unsigned w1, w2;
  50. { return (w1 > w2) ? w1 : w2; }
  51. int imin( i1, i2 )
  52. register int i1, i2;
  53. { return (i1 < i2) ? i1 : i2; }
  54. int imax( i1, i2 )
  55. register int i1, i2;
  56. { return (i1 > i2) ? i1 : i2; }
  57. #define BZNATIVE
  58. #ifndef BZNATIVE
  59. /* C C H D I F F E R */
  60. /* commented out, moved to native code in lib.asm bz 6/20/85 */
  61. int CchDiffer(rgch1, rgch2, cch)
  62. register CHAR *rgch1, *rgch2;
  63. int cch;
  64. {{ /* Return cch of shortest prefix leaving a common remainder */
  65. int ich;
  66. for (ich = cch - 1; ich >= 0; ich--)
  67. if (rgch1[ich] != rgch2[ich])
  68. break;
  69. return ich + 1;
  70. }}
  71. #endif
  72. int CchSz(sz)
  73. register CHAR sz[];
  74. { /* Returns length of string in bytes, including trailing 0 */
  75. register int cch = 1;
  76. while (*sz++ != 0)
  77. cch++;
  78. return cch;
  79. } /* end of C c h S z */
  80. typeCP CpMacText(doc)
  81. register int doc;
  82. {
  83. #ifdef FOOTNOTES
  84. struct FNTB **hfntb;
  85. if ((hfntb = HfntbGet(doc)) != 0)
  86. return((**hfntb).rgfnd[0].cpFtn - ccpEol);
  87. else
  88. #endif /* FOOTNOTES */
  89. return((**hpdocdod)[doc].cpMac);
  90. } /* end of C p M a c T e x t */
  91. struct FNTB **HfntbGet(doc)
  92. register int doc;
  93. { /* Return hfntb if doc has one, 0 if none or style sheet */
  94. #ifdef STYLES
  95. register struct DOD *pdod;
  96. if ((pdod = &(**hpdocdod)[doc])->dty == dtySsht)
  97. return 0;
  98. else
  99. #endif
  100. return (**hpdocdod)[doc].hfntb;
  101. } /* end of H F n t b G e t */
  102. /* N O U N D O */
  103. NoUndo()
  104. {
  105. extern struct UAB vuab;
  106. vuab.uac = uacNil;
  107. SetUndoMenuStr(IDSTRUndoBase);
  108. } /* end of N o U n d o */
  109. SetUndoMenuStr(idstr)
  110. int idstr;
  111. {
  112. extern int idstrCurrentUndo;
  113. idstrCurrentUndo = idstr;
  114. }
  115. /* Returns number chars copied EXCLUDING zero terminator */
  116. int CchCopySz(pchFrom, pchTo)
  117. register PCH pchFrom;
  118. register PCH pchTo;
  119. {
  120. int cch = 0;
  121. while ((*pchTo = *pchFrom++) != 0)
  122. {
  123. pchTo++;
  124. cch++;
  125. }
  126. return cch;
  127. } /* end of C c h C o p y S z */
  128. /*---------------------------------------------------------------------------
  129. -- Routine: WCompSz(psz1,psz2)
  130. -- Description and Usage:
  131. Alphabetically compares the two null-terminated strings lpsz1 and lpsz2.
  132. Upper case alpha characters are mapped to lower case.
  133. Comparison of non-alpha characters is by ascii code.
  134. Returns 0 if they are equal, a negative number if lpsz1 precedes lpsz2, and
  135. a non-zero positive number if lpsz2 precedes lpsz1.
  136. -- Arguments:
  137. psz1, psz2 - pointers to two null-terminated strings to compare
  138. -- Returns:
  139. a short - 0 if strings are equal, negative number if lpsz1 precedes lpsz2,
  140. and non-zero positive number if psz2 precedes psz1.
  141. -- Side-effects: none
  142. -- Bugs:
  143. -- History:
  144. 3/14/83 - created (tsr)
  145. 6/12/86 - Kanji Version (yxy)
  146. ----------------------------------------------------------------------------*/
  147. short
  148. WCompSz(psz1,psz2)
  149. register PCH psz1;
  150. register PCH psz2;
  151. {
  152. int ch1;
  153. int ch2;
  154. for(ch1=ChLower(*psz1++),ch2=ChLower(*psz2++);
  155. ch1==ch2;
  156. ch1=ChLower(*psz1++),ch2=ChLower(*psz2++))
  157. {
  158. if(ch1 == '\0')
  159. return(0);
  160. }
  161. return(ch1-ch2);
  162. } /* end of W C o m p S z */
  163. /*---------------------------------------------------------------------------
  164. -- Routine: ChLower(ch)
  165. -- Description and Usage:
  166. Converts its argument to lower case iff its argument is upper case.
  167. Returns the de-capitalized character or the initial char if it wasn't caps.
  168. -- Arguments:
  169. ch - character to be de-capitalized
  170. -- Returns:
  171. a character - initial character, de-capitalized if needed.
  172. -- Side-effects:
  173. -- Bugs:
  174. -- History:
  175. 3/14/83 - created (tsr)
  176. ----------------------------------------------------------------------------*/
  177. int
  178. ChLower(ch)
  179. register CHAR ch;
  180. { /* use Windows' ANSI char set, the difference of upper/lower case
  181. is also 20 (HEX) for foreign chars */
  182. #ifdef JAPAN
  183. // check for half-size katakana.
  184. extern struct WWD rgwwd[];
  185. extern BOOL IsKanaInDBCS(int);
  186. static TEXTMETRIC tm;
  187. /**/
  188. BOOL ret1;
  189. BOOL ret2;
  190. #if 0 //T-HIROYN
  191. ret1 = IsWindow(wwdCurrentDoc.wwptr);
  192. ret2 = GetTextMetrics(wwdCurrentDoc.hDC,(LPTEXTMETRIC)&tm);
  193. if(ret1 && ret2)
  194. {
  195. if(tm.tmCharSet == SHIFTJIS_CHARSET && IsKanaInDBCS((int)ch))
  196. return (int)(0x00ff&ch);
  197. }
  198. #else
  199. ret1 = IsWindow(wwdCurrentDoc.wwptr);
  200. if (ret1)
  201. {
  202. ret2 = GetTextMetrics(wwdCurrentDoc.hDC,(LPTEXTMETRIC)&tm);
  203. if(ret2)
  204. {
  205. if(tm.tmCharSet == SHIFTJIS_CHARSET && IsKanaInDBCS((int)ch))
  206. return (int)(0x00ff&ch);
  207. }
  208. }
  209. #endif
  210. #if 0
  211. if(IsWindow(wwdCurrentDoc.wwptr)
  212. && GetTextMetrics(wwdCurrentDoc.hDC,(LPTEXTMETRIC)&tm)){
  213. if(tm.tmCharSet == SHIFTJIS_CHARSET && IsKanaInDBCS((int)ch))
  214. return (int)(0x00ff&ch);
  215. }
  216. #endif
  217. #endif
  218. #ifdef KOREA
  219. if(isupper(ch) && !((ch > 0xa1) && (ch < 0xfe)))
  220. #else
  221. if(isupper(ch))
  222. #endif
  223. return(ch + ('a' - 'A')); /* foreign is taken care of */
  224. else
  225. return ch;
  226. } /* end of C h L o w e r */
  227. static int cLongOpCount = 0; /* to ensure we don't do too much hide cursor */
  228. StartLongOp()
  229. {
  230. extern int vfInLongOperation;
  231. extern int vfCursorVisible;
  232. extern int vfMouseExist;
  233. extern HCURSOR vhcHourGlass;
  234. int cursorlevel;
  235. if (cLongOpCount++ == 0)
  236. {
  237. vfInLongOperation = TRUE;
  238. vfCursorVisible = TRUE;
  239. if (!vfMouseExist)
  240. { /* in a mouseless system, set the cursor to middle of window */
  241. extern HWND vhWndMsgBoxParent;
  242. extern HWND hParentWw;
  243. extern int vfInitializing;
  244. RECT rect;
  245. POINT pt;
  246. HWND hWnd = vhWndMsgBoxParent;
  247. if (vhWndMsgBoxParent == NULL)
  248. hWnd = hParentWw; /* next choice */
  249. if (!vfInitializing && hWnd != NULL && IsWindow(hWnd))
  250. { /* we have a good window to put in */
  251. GetClientRect(hWnd, (LPRECT)&rect);
  252. pt.x = (rect.right - rect.left) / 2;
  253. pt.y = (rect.bottom - rect.top) / 2;
  254. ClientToScreen(hWnd, (LPPOINT)&pt);
  255. }
  256. else
  257. { /* put in the middle of screen */
  258. HDC hDCScreen = GetDC(NULL);
  259. if (hDCScreen == NULL)
  260. goto Out; /* the worst, setcursor only */
  261. pt.x = GetDeviceCaps(hDCScreen, HORZRES) / 2;
  262. pt.y = GetDeviceCaps(hDCScreen, VERTRES) / 2;
  263. ReleaseDC(NULL, hDCScreen);
  264. }
  265. SetCursorPos(pt.x, pt.y);
  266. }
  267. Out:
  268. SetCursor(vhcHourGlass);
  269. #if WINVER < 0x300
  270. ShowCursor(TRUE);
  271. /* precaution - make sure the cusor is visible */
  272. cursorlevel = GetSystemMetrics(SM_CURSORLEVEL);
  273. #else
  274. /* use a supported method to get cursor level! ..pault 2/6/90 */
  275. cursorlevel = ShowCursor(TRUE);
  276. #endif
  277. while (cursorlevel++ < 0)
  278. ShowCursor(TRUE);
  279. }
  280. }
  281. EndLongOp(hc)
  282. HCURSOR hc; /* cursor to be changed to */
  283. {
  284. extern int vfInLongOperation;
  285. extern int vfCursorVisible;
  286. extern int vfMouseExist;
  287. extern int vfDeactByOtherApp;
  288. int cursorlevel;
  289. #ifdef JAPAN // added by Hiraisi (BUG#3628/WIN31)
  290. {
  291. RECT rc;
  292. POINT pt;
  293. extern int xpSelBar, dxpScrlBar, dypScrlBar;
  294. extern HWND hParentWw;
  295. extern HCURSOR vhcArrow, vhcBarCur;
  296. GetClientRect(hParentWw, (LPRECT)&rc);
  297. rc.right -= dxpScrlBar;
  298. rc.bottom -= dypScrlBar;
  299. GetCursorPos((LPPOINT)&pt);
  300. ScreenToClient(hParentWw,(LPPOINT)&pt);
  301. if( !PtInRect((LPRECT)&rc, pt) ) // out of edit area
  302. hc = vhcArrow;
  303. else
  304. if( pt.x <= xpSelBar ) // within selection bar
  305. hc = vhcBarCur;
  306. }
  307. #endif
  308. if (cLongOpCount > 0)
  309. {
  310. if (vfDeactByOtherApp && (cLongOpCount == 1)) // OLE presents this case
  311. {
  312. vfInLongOperation = FALSE;
  313. vfCursorVisible = FALSE;
  314. SetCursor(vfMouseExist ? hc : NULL);
  315. }
  316. else if (--cLongOpCount == 0)
  317. {
  318. vfInLongOperation = FALSE;
  319. vfCursorVisible = FALSE;
  320. #if WINVER < 0x300
  321. ShowCursor(FALSE);
  322. SetCursor(vfMouseExist ? hc : NULL);
  323. /* make sure the cursor is still visible in a mouse system
  324. and invisible in a mouseless system */
  325. cursorlevel = GetSystemMetrics(SM_CURSORLEVEL);
  326. #else
  327. /* use a supported method to get cursor level! ..pault 2/6/90 */
  328. cursorlevel = ShowCursor(FALSE);
  329. SetCursor(vfMouseExist ? hc : NULL);
  330. #endif
  331. if (vfMouseExist)
  332. {
  333. while (cursorlevel++ < 0)
  334. ShowCursor(TRUE);
  335. }
  336. else /* no mouse */
  337. {
  338. while (cursorlevel-- >= 0)
  339. ShowCursor(FALSE);
  340. }
  341. }
  342. }
  343. }
  344. /* String utility functions - moved here from string.c */
  345. /* I N D E X */
  346. /* ** Returns pointer to first occurrence of character ch found in null-
  347. terminated string pch, or 0 if ch does not appear. If ch==0, we
  348. return a pointer to the null terminator. */
  349. /* In Kanji version, a kanji character is excluded from the search. */
  350. CHAR *index(pch, ch)
  351. REG1 CHAR *pch;
  352. REG2 CHAR ch; // fixed bug, previously int (2.11.91) D. Kent
  353. {
  354. while (low(*pch)!=ch)
  355. {
  356. #ifdef DBCS /* KenjiK '90-11-20 */
  357. if (*pch=='\0')
  358. #else
  359. if (*pch++=='\0')
  360. #endif
  361. return(NULL);
  362. #ifdef DBCS /* KenjiK '90-11-20 */
  363. pch = AnsiNext(pch);
  364. #endif
  365. }
  366. return(pch);
  367. }
  368. /* We may want to make these 'type' functions into macros */
  369. /* These are designed for ANSI character set (used by windows) only */
  370. /* I S A L P H A */
  371. /* ** TRUE if ch is a letter, FALSE otherwise */
  372. isalpha(ch)
  373. REG1 CHAR ch;
  374. {/* Note: even though DF and FF are lowercase, they have no
  375. corresponding uppercase, so they are excluded from the
  376. lowercase class, and simply mapped to themselves */
  377. return(islower(ch) || isupper(ch) || ch == 0x00FF || ch == 0x00DF);
  378. }
  379. /* ** TRUE if ch is a lowercase letter, FALSE otherwise */
  380. /* I S L O W E R */
  381. islower(ch)
  382. REG1 CHAR ch;
  383. {/* Note: even though DF and FF are lowercase, they have no
  384. corresponding uppercase, so they are excluded from the
  385. lowercase class, and simply mapped to themselves */
  386. return((ch >= 'a' && ch <= 'z') ||
  387. /* foreign */
  388. (ch >= 0x00E0 && ch <= 0x00F6) ||
  389. (ch >= 0x00F8 && ch <= 0x00FE) );
  390. }
  391. /* ** TRUE if ch is an uppercase letter, FALSE otherwise */
  392. isupper(ch)
  393. REG1 CHAR ch;
  394. {
  395. return((ch >= 'A' && ch <= 'Z') ||
  396. /* foreign */
  397. (ch >= 0x00C0 && ch <= 0x00D6) ||
  398. (ch >= 0x00D8 && ch <= 0x00DE));
  399. }
  400. /* ** TRUE if ch is a digit, FALSE otherwise */
  401. isdigit(ch)
  402. REG1 CHAR ch;
  403. {
  404. return(ch>='0' && ch<='9');
  405. }
  406. #ifdef ENABLE
  407. /* ** TRUE if ch is a character or a digit, FALSE otherwise */
  408. isalnum(ch)
  409. REG1 CHAR ch;
  410. {
  411. return(isalpha(ch) || isdigit(ch));
  412. }
  413. #endif
  414. int ChUpper(ch)
  415. REG1 CHAR ch;
  416. {
  417. #ifdef DBCS
  418. return AnsiUpper( ch );
  419. #else
  420. #ifdef BOGUS
  421. return (ch >= 'a' && ch <= 'z') ? ch + ('A' - 'a') : ch;
  422. #endif
  423. /* use Windows' ANSI char set, the difference of upper/lower case
  424. is also 20 (HEX) for foreign chars */
  425. if (islower(ch))
  426. return(ch + ('A' - 'a')); /* foreign is taken care of */
  427. else return(ch);
  428. #endif
  429. }
  430. /* similar to blcomp except compares by bytes and is not case sensitive */
  431. BOOL FRgchSame(rgch1, rgch2, cch)
  432. CHAR rgch1[], rgch2[];
  433. int cch;
  434. {
  435. short ich;
  436. for(ich = 0; ich < cch; ich++)
  437. {
  438. if(ChLower(rgch1[ich]) != ChLower(rgch2[ich]))
  439. return(FALSE);
  440. }
  441. return(TRUE);
  442. }
  443. /* PchStartBaseNameSz() ---- returns a character pointer to the
  444. beginning of a base file name. If
  445. the name only consists of a base
  446. name, sz is returned.
  447. Note: If sz ends with a back-slash or a colon, pch returned
  448. is pointing to the null terminator of the given string. */
  449. CHAR *PchStartBaseNameSz(sz)
  450. CHAR *sz;
  451. {
  452. CHAR *pchBS, *pchC, *pchLast;
  453. CHAR *PchLastSzCh();
  454. pchBS = PchLastSzCh(sz, '\\');
  455. pchC = PchLastSzCh(sz, ':');
  456. pchLast = (pchBS > pchC) ? pchBS : pchC;
  457. if (pchLast == NULL) {
  458. pchLast = sz;
  459. }
  460. else {
  461. pchLast++;
  462. }
  463. return (pchLast);
  464. }
  465. /* PchLastSzCh() ----- returns a pointer to the last occurrence of a given
  466. character in a given string. If it does not occur
  467. in the string, it returns NULL. If the given
  468. character is '\0', it returns sz itself.
  469. Note: All kanji characters are excluded from the search. */
  470. CHAR *PchLastSzCh(sz, ch)
  471. CHAR *sz;
  472. CHAR ch;
  473. {
  474. if (ch == '\0') {
  475. return (sz);
  476. }
  477. else {
  478. CHAR *pchCur, *pchLast;
  479. #ifdef DBCS
  480. for (pchLast = pchCur = sz; *pchCur != '\0'; pchCur = AnsiNext(pchCur))
  481. #else
  482. for (pchLast = pchCur = sz; *pchCur != '\0'; pchCur++)
  483. #endif
  484. {
  485. {
  486. if (low(*pchCur) == ch) {
  487. pchLast = pchCur;
  488. }
  489. }
  490. }
  491. return ((pchLast == sz) ? NULL : pchLast);
  492. }
  493. }
  494. #ifdef DEBUG
  495. _Assert(pch, line, f)
  496. PCH pch;
  497. int line;
  498. BOOL f;
  499. {
  500. if (!f)
  501. Do_Assert(pch, line, f);
  502. }
  503. #endif
  504. #ifdef JAPAN /*t-Yoshio*/
  505. myHantoZen(char *han_str,char *zen_str,int buffsize)
  506. {
  507. extern CHAR Zenstr1[256];
  508. extern CHAR Zenstr2[256];
  509. CHAR far *ZenTbl;
  510. int length = 0;
  511. int sub;
  512. while((CHAR)*han_str) {
  513. if(length+3 > buffsize)
  514. break;
  515. if((CHAR)*han_str >= 0x20 && (CHAR)*han_str < 0x7f) {
  516. ZenTbl = Zenstr1;
  517. sub = ((CHAR)*han_str-0x20)*2;
  518. han_str++;
  519. *zen_str = ZenTbl[sub];
  520. *(zen_str+1) = ZenTbl[sub+1];
  521. zen_str+=2;
  522. length+=2;
  523. continue;
  524. }
  525. else if((CHAR)*han_str >= 0xa1 && (CHAR)*han_str <= 0xdd) {
  526. ZenTbl = Zenstr2;
  527. if((CHAR)*han_str >= 0xca && (CHAR)*han_str <= 0xce) {
  528. if((CHAR)*(han_str+1) == 0xde ) {
  529. sub = ((CHAR)*han_str-0xa1+35)*2;
  530. han_str+=2;
  531. }
  532. else if((CHAR)*(han_str+1) == 0xdf ) {
  533. sub = ((CHAR)*han_str-0xa1+40)*2;
  534. han_str+=2;
  535. }
  536. else {
  537. sub = ((CHAR)*han_str-0xa1)*2;
  538. han_str++;
  539. }
  540. }
  541. else if((CHAR)*han_str >= 0xa6 && (CHAR)*han_str <= 0xc4) {
  542. if((CHAR)*(han_str+1) == 0xde ) {
  543. sub = ((CHAR)*han_str-0xa1+40)*2;
  544. han_str+=2;
  545. }
  546. else {
  547. sub = ((CHAR)*han_str-0xa1)*2;
  548. han_str++;
  549. }
  550. }
  551. else {
  552. sub = ((CHAR)*han_str-0xa1)*2;
  553. han_str++;
  554. }
  555. *zen_str = ZenTbl[sub];
  556. *(zen_str+1) = ZenTbl[sub+1];
  557. zen_str+=2;
  558. length+=2;
  559. continue;
  560. }
  561. else {
  562. if(IsDBCSLeadByte((BYTE)(*han_str))) {
  563. *zen_str = *han_str;
  564. *(zen_str+1) = (CHAR)*(han_str+1);
  565. zen_str+=2;
  566. length+=2;
  567. han_str+=2;
  568. }
  569. else {
  570. *zen_str = *han_str;
  571. *zen_str++;length++;han_str++;
  572. }
  573. continue;
  574. }
  575. }
  576. *zen_str = '\0';
  577. }
  578. myIsSonant(BYTE dbcshi,BYTE dbcslow)
  579. {
  580. static unsigned short hanzen[] = {
  581. 0x834b, 0x834d, 0x834f, 0x8351, 0x8353,
  582. 0x8355, 0x8357, 0x8359, 0x835b, 0x835d,
  583. 0x835f, 0x8361, 0x8364, 0x8366, 0x8368,
  584. 0x836f, 0x8370, 0x8372, 0x8373, 0x8375,
  585. 0x8376, 0x8378, 0x8379, 0x837b, 0x837c
  586. };
  587. unsigned int dbyte;
  588. int i;
  589. dbyte = (((WORD)(dbcshi) << 8) | ((WORD)(dbcslow) & 0x00ff));
  590. for(i = 0;i < 25;i++)
  591. {
  592. if(dbyte == hanzen[i])
  593. return TRUE;
  594. }
  595. return FALSE;
  596. }
  597. #elif defined(KOREA)
  598. myHantoZen(char *han_str,char *zen_str,int buffsize)
  599. {
  600. extern CHAR Zenstr1[256];
  601. CHAR far *ZenTbl;
  602. int length = 0;
  603. int sub;
  604. while((CHAR)*han_str) {
  605. if(length+3 > buffsize)
  606. break;
  607. if((CHAR)*han_str >= 0x20 && (CHAR)*han_str < 0x7f) {
  608. ZenTbl = Zenstr1;
  609. sub = ((CHAR)*han_str-0x20)*2;
  610. han_str++;
  611. *zen_str = ZenTbl[sub];
  612. *(zen_str+1) = ZenTbl[sub+1];
  613. zen_str+=2;
  614. length+=2;
  615. continue;
  616. }
  617. else {
  618. if(IsDBCSLeadByte((BYTE)(*han_str))) {
  619. *zen_str = *han_str;
  620. *(zen_str+1) = (CHAR)*(han_str+1);
  621. zen_str+=2;
  622. length+=2;
  623. han_str+=2;
  624. }
  625. else {
  626. *zen_str = *han_str;
  627. *zen_str++;length++;han_str++;
  628. }
  629. continue;
  630. }
  631. }
  632. *zen_str = '\0';
  633. }
  634. myIsSonant(BYTE dbcshi,BYTE dbcslow)
  635. {
  636. static unsigned short hanzen[] = {
  637. 0x834b, 0x834d, 0x834f, 0x8351, 0x8353,
  638. 0x8355, 0x8357, 0x8359, 0x835b, 0x835d,
  639. 0x835f, 0x8361, 0x8364, 0x8366, 0x8368,
  640. 0x836f, 0x8370, 0x8372, 0x8373, 0x8375,
  641. 0x8376, 0x8378, 0x8379, 0x837b, 0x837c
  642. };
  643. unsigned int dbyte;
  644. int i;
  645. dbyte = (((WORD)(dbcshi) << 8) | ((WORD)(dbcslow) & 0x00ff));
  646. for(i = 0;i < 25;i++)
  647. {
  648. if(dbyte == hanzen[i])
  649. return TRUE;
  650. }
  651. return FALSE;
  652. }
  653. #endif
  654.