Leaked source code of windows server 2003
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.

2224 lines
62 KiB

  1. /*************************************************
  2. * uimetool.c *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. //
  8. // Change log:
  9. // define UNIIME identifier
  10. // @D03 Fix Bug Use wrong miniime.tpl file name
  11. // @D04 Fix Bug Does show error message when invalid table file
  12. // @D05 Modified Add UNALIGNED to meet MIPS system
  13. //
  14. // 1/17/96
  15. // @E01 Change for multi-threading
  16. // @E02 Untest DBCS for NT version
  17. // @E03 Change for multi-threading without extending function
  18. #include <windows.h> // required for all Windows applications
  19. #include <windowsx.h>
  20. #include <tchar.h>
  21. #define STRSAFE_NO_DEPRECATE
  22. #include "strsafe.h"
  23. #include "rc.h" // prototypes specific to this application
  24. #include "uimetool.h"
  25. #include "imeattr.h"
  26. #include "imerc.h"
  27. #ifdef UNICODE
  28. typedef DWORD UNALIGNED FAR *LPUNADWORD;
  29. typedef WORD UNALIGNED FAR *LPUNAWORD;
  30. typedef TCHAR UNALIGNED FAR *LPUNATCHAR;
  31. #else
  32. typedef DWORD FAR *LPUNADWORD;
  33. typedef WORD FAR *LPUNAWORD;
  34. typedef TCHAR FAR *LPUNATCHAR;
  35. #define TCHAR BYTE
  36. #endif
  37. HWND hwndMain;
  38. TCHAR szIme_Name[IME_NAME_LEN_TOOL];
  39. TCHAR szTab_Name[MAX_PATH];
  40. TCHAR szKey_Num_Str[KEY_NUM_STR_LEN];
  41. TCHAR szFile_Out_Name[TAB_NAME_LEN];
  42. TCHAR Show_Mess[MAX_PATH];
  43. TCHAR Msg_buf[MAX_PATH];
  44. BOOL bCandBeep;
  45. BOOL bOverMaxRadical; //@D02A
  46. HCURSOR hCursorWait;
  47. HCURSOR hCursorArrow;
  48. VALIDCHAR Valid;
  49. TABLEFILES Table;
  50. UINT uGenericID[]={ IDS_FILEDESCRIPTION_STR,
  51. IDS_VER_INTERNALNAME_STR,
  52. IDS_PRODUCTNAME_STR,
  53. IDS_IMENAME };
  54. #ifdef UNICODE
  55. int cntChar = 2;
  56. #else
  57. int cntChar = 1;
  58. #endif
  59. UINT idxLine;
  60. extern HINSTANCE hInst;
  61. UINT SearchMem(BYTE *, UINT, BYTE *, UINT);
  62. BOOL Process_Bitmap(HWND, BYTE *, UINT);
  63. BOOL Process_Icon(HWND, BYTE *, UINT);
  64. BOOL Process_RT(HFILE, BYTE *, UINT, TCHAR *);
  65. BOOL WritetoFile(TCHAR *);
  66. WORD GetPhrase(UINT, TCHAR *);
  67. BOOL Parse(TCHAR *, UINT);
  68. BOOL PutRadical(TCHAR, WORD);
  69. BOOL PutPhrase(TCHAR *, TCHAR *, UINT);
  70. BOOL AllocRadical();
  71. BOOL AllocPhrase();
  72. void ErrMsg(UINT, UINT);
  73. void ErrIOMsg(UINT, TCHAR *);
  74. void MyFillMemory(TCHAR *dst, DWORD cnt, TCHAR v);
  75. void GetOpenFile(
  76. HWND hDlg)
  77. {
  78. OPENFILENAME ofn;
  79. TCHAR *pszFilterSpec;
  80. TCHAR szFilterSpec[128];
  81. TCHAR szFileOpen[25];
  82. TCHAR szExt[10];
  83. TCHAR szCustFilter[10];
  84. TCHAR szFileName[MAX_PATH];
  85. TCHAR szFilePath[MAX_PATH];
  86. TCHAR szStr[MAX_PATH];
  87. szFileName[0]=0;
  88. LoadString (hInst, IDS_FILTERSPEC, szFilterSpec, sizeof(szFilterSpec) / sizeof(TCHAR));
  89. LoadString (hInst, IDS_DEFAULTFILEEXT, szExt, sizeof(szExt) / sizeof(TCHAR));
  90. pszFilterSpec = szFilterSpec;
  91. pszFilterSpec += lstrlen(pszFilterSpec) + 1;
  92. StringCchCopy(pszFilterSpec,
  93. ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec), szExt);
  94. LoadString (hInst, IDS_FILTERSPEC_ALL, szStr, sizeof(szStr) / sizeof(TCHAR));
  95. pszFilterSpec += lstrlen(pszFilterSpec) + 1;
  96. if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
  97. {
  98. StringCchCopy(
  99. pszFilterSpec,
  100. ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec),
  101. szStr);
  102. LoadString (hInst, IDS_ALLFILEEXT, szStr, sizeof(szStr) / sizeof(TCHAR));
  103. pszFilterSpec += lstrlen(pszFilterSpec) + 1;
  104. }
  105. if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
  106. {
  107. StringCchCopy(
  108. pszFilterSpec,
  109. ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec),
  110. szStr);
  111. pszFilterSpec += lstrlen(pszFilterSpec) + 1;
  112. }
  113. if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
  114. {
  115. *pszFilterSpec = 0;
  116. }
  117. LoadString (hInst, IDS_OPENTITLE, szFileOpen, sizeof(szFileOpen) / sizeof(TCHAR));
  118. szCustFilter[0] = 0;
  119. lstrcpy(&szCustFilter[1], szExt);
  120. lstrcpy(szFilePath, szExt);
  121. /* fill in non-variant fields of OPENFILENAME struct. */
  122. ofn.lStructSize = sizeof(OPENFILENAME);
  123. ofn.hwndOwner = hDlg;
  124. ofn.lpstrFilter = szFilterSpec;
  125. ofn.lpstrCustomFilter = szCustFilter;
  126. ofn.nMaxCustFilter = sizeof(szCustFilter) / sizeof(TCHAR);
  127. ofn.nFilterIndex = 1;
  128. ofn.lpstrFile = szFilePath;
  129. ofn.nMaxFile = MAX_PATH;
  130. ofn.lpstrInitialDir = NULL;
  131. ofn.lpstrFileTitle = szFileName;
  132. ofn.nMaxFileTitle = MAX_PATH;
  133. ofn.lpstrTitle = szFileOpen;
  134. ofn.lpstrDefExt = szExt + 3;
  135. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  136. OFN_PATHMUSTEXIST;
  137. /* call common open dialog and return result */
  138. if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  139. SetDlgItemText(hDlg, IDD_TABLE_NAME, szFilePath);
  140. }
  141. // <== @E01
  142. //unsigned _stdcall MakeNewImeThread(LPVOID voidparam)
  143. void MakeNewImeThread(LPVOID voidparam) // <== @E03
  144. {
  145. BOOL bOk;
  146. extern HWND hProgMain;
  147. extern BOOL bFinish;
  148. bOk = MakeNewIme(NULL);
  149. if (hProgMain)
  150. PostMessage(hProgMain, WM_CLOSE, 0, 0);
  151. if (!bOk)
  152. bFinish = 0;
  153. else
  154. bFinish = 1;
  155. //return bOk;
  156. }
  157. // <== @E01
  158. void HideProgress(void)
  159. {
  160. extern HWND hProgMain;
  161. if (hProgMain)
  162. ShowWindow(hProgMain, SW_HIDE);
  163. }
  164. // <== @E01
  165. void ShowProgress(void)
  166. {
  167. extern HWND hProgMain;
  168. if (hProgMain)
  169. ShowWindow(hProgMain, SW_SHOWNORMAL);
  170. }
  171. #define IDM_NEWSHELL 249
  172. void HandleTaskBar_IME( )
  173. {
  174. HWND hwndIndicate;
  175. TCHAR szIndicator[] = TEXT("Indicator");
  176. // Handle the task bar indicator option.
  177. hwndIndicate = FindWindow(szIndicator, NULL);
  178. //
  179. // See if the indicator is already enabled.
  180. //
  181. if (hwndIndicate && IsWindow(hwndIndicate))
  182. {
  183. SendMessage(hwndIndicate, WM_COMMAND, IDM_NEWSHELL, 0L);
  184. }
  185. }
  186. BOOL MakeNewIme(HWND hWnd)
  187. {
  188. HFILE hfFile,hfMainFile;
  189. BYTE *szImeBuf;
  190. TCHAR szBig5[MAX_PATH],szUniCode[MAX_PATH],szGeneric[MAX_PATH];
  191. TCHAR szClass[MAX_PATH];
  192. TCHAR szPure_Name[100];
  193. TCHAR Ime_File_Name[MAX_PATH];
  194. TCHAR Src_File_Name[MAX_PATH];
  195. TCHAR szSystem[MAX_PATH];
  196. UINT uLen,flen,len,unilen,classlen,genericlen;
  197. UINT uAddr;
  198. int i;
  199. // Get Windows System directory
  200. uLen = GetSystemDirectory((LPTSTR)szSystem, ARRAYSIZE(szSystem));
  201. if (szSystem[uLen - 1] != _TEXT('\\')) // consider C:\ ;
  202. {
  203. szSystem[uLen ++] = _TEXT('\\');
  204. szSystem[uLen] = 0;
  205. }
  206. //---------------------------------------------------------------------------
  207. // Check input data
  208. //---------------------------------------------------------------------------
  209. //let Pure_Name be without .ime name, this is prevent user to input .ime
  210. for(i = 0; i < (int)lstrlen(szFile_Out_Name); i++)
  211. {
  212. if(szFile_Out_Name[i] == _TEXT('.'))
  213. break;
  214. szPure_Name[i] = szFile_Out_Name[i];
  215. }
  216. szPure_Name[i] = 0; //end of string
  217. if(szPure_Name[0] == 0)
  218. {
  219. ErrMsg(IDS_ERR_INPUTIME, 0);
  220. return FALSE; //do nothing because didnt set ok
  221. }
  222. //limit it length <= 8
  223. if(lstrlen(szPure_Name) > 8) szPure_Name[8] = 0;
  224. //Check if is reserved name miniime
  225. if(!lstrcmp(SOURCE_IME_NAME, szPure_Name))
  226. {
  227. //is with reserved file name for .ime
  228. ErrMsg(IDS_ERR_USE_RESERVE, 0);
  229. return FALSE;
  230. }
  231. //Check input IME Name
  232. len = lstrlen(szIme_Name);
  233. #ifdef UNICODE
  234. if(len < 2)
  235. szIme_Name[1] = 0x3000;
  236. szIme_Name[2]=0;
  237. {
  238. char fname[MAX_PATH * 2];
  239. int lenx = lstrlen(szTab_Name);
  240. WideCharToMultiByte(950, WC_COMPOSITECHECK, szTab_Name, lenx,
  241. (LPSTR)fname, lenx, NULL, NULL);
  242. fname[lenx] = 0;
  243. hfMainFile=_lopen(fname, OF_READ);
  244. }
  245. #else
  246. if(len < 4)
  247. {
  248. szIme_Name[2] = (BYTE) 0xa1;
  249. szIme_Name[3] = (BYTE) 0x40;
  250. }
  251. szIme_Name[4]=0;
  252. hfMainFile=_lopen(szTab_Name, OF_READ);
  253. #endif
  254. if(hfMainFile==-1)
  255. {
  256. ErrIOMsg(IDS_ERR_FILEOPEN, szTab_Name);
  257. return FALSE;
  258. }
  259. //---------------------------------------------------------------------------
  260. // Read Base IME file - miniime.tpl
  261. //---------------------------------------------------------------------------
  262. StringCchCopy(Src_File_Name, ARRAYSIZE(Src_File_Name), szSystem); //System directory
  263. StringCchCat(Src_File_Name, ARRAYSIZE(Src_File_Name), LIBRARY_NAME);
  264. #ifdef UNICODE
  265. {
  266. char fname[MAX_PATH * 2];
  267. int ilen = lstrlen(Src_File_Name); // <== @D03
  268. WideCharToMultiByte(950, WC_COMPOSITECHECK, Src_File_Name, ilen,
  269. (LPSTR)fname, sizeof(fname), NULL, NULL);
  270. fname[ilen] = 0;
  271. hfFile=_lopen(fname,OF_READ);
  272. }
  273. #else
  274. hfFile=_lopen(Src_File_Name, OF_READ);
  275. #endif
  276. if(hfFile==-1)
  277. {
  278. ErrIOMsg(IDS_ERR_FILEOPEN, Src_File_Name);
  279. _lclose(hfMainFile);
  280. return TRUE; // Can not continue
  281. }
  282. flen=_llseek(hfFile, 0L, 2); // get file length
  283. // Allocate Memory
  284. szImeBuf = (BYTE *)GlobalAlloc(GMEM_FIXED, flen);
  285. if(!szImeBuf)
  286. {
  287. ErrMsg(IDS_ERR_MEMORY, 0);
  288. _lclose(hfMainFile);
  289. return TRUE; // Can not continue
  290. }
  291. _llseek(hfFile, 0L, 0); //set to beginning
  292. if(flen != _lread(hfFile,szImeBuf,flen))
  293. {
  294. ErrIOMsg(IDS_ERR_FILEREAD, Src_File_Name);
  295. _lclose(hfMainFile);
  296. GlobalFree((HGLOBAL)szImeBuf);
  297. return TRUE; // Can not continue
  298. }
  299. _lclose(hfFile);
  300. //---------------------------------------------------------------------------
  301. // Search string and Patch them
  302. //---------------------------------------------------------------------------
  303. // Translate input IME name to Unicod to instead of generic string
  304. LoadString(hInst, IDS_IMENAME, szBig5, sizeof(szBig5) / sizeof(TCHAR));
  305. len = lstrlen(szBig5);
  306. #ifdef UNICODE
  307. lstrcpy(szUniCode, szBig5);
  308. unilen = len;
  309. #else
  310. unilen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  311. (LPWSTR)szUniCode, len);
  312. #endif
  313. lstrcpy(szBig5, szIme_Name);
  314. len=lstrlen(szBig5);
  315. #ifdef UNICODE
  316. lstrcpy(szGeneric, szBig5);
  317. genericlen = lstrlen(szBig5);
  318. #else
  319. for(i = len; i < (int)(len+unilen-2); i++)
  320. szBig5[i] = ' ';
  321. szBig5[i] = 0;
  322. len = lstrlen(szBig5);
  323. genericlen = MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  324. (LPWSTR)szGeneric, len);
  325. genericlen *= 2;
  326. #endif
  327. // Process Generic string
  328. #ifdef UNICODE
  329. for(i=0; i<(sizeof(uGenericID)/sizeof(UINT)); i++)
  330. {
  331. LoadString(hInst, uGenericID[i], szBig5, sizeof(szBig5) / sizeof(TCHAR));
  332. len=lstrlen(szBig5);
  333. uAddr=SearchMem((LPSTR)szBig5, len * 2, szImeBuf, flen);
  334. if(uAddr == 0) {
  335. continue;
  336. } else
  337. if ( i == 0 ) {
  338. // this is for IDS_FILEDESCRIPTION_STR,
  339. // We just replace the first two Chinese Characters
  340. // and keep the rest.
  341. CopyMemory(&szImeBuf[uAddr], szGeneric,genericlen*2 );
  342. }
  343. else
  344. CopyMemory(&szImeBuf[uAddr], szGeneric, (genericlen + 1) * 2);
  345. }
  346. #else
  347. for(i=0; i<(sizeof(uGenericID)/sizeof(UINT)); i++)
  348. {
  349. LoadString(hInst, uGenericID[i], szBig5, sizeof(szBig5) / sizeof(TCHAR));
  350. len=lstrlen(szBig5);
  351. unilen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  352. (LPWSTR)szUniCode, len);
  353. uAddr=SearchMem(szUniCode, unilen*2, szImeBuf, flen);
  354. if(uAddr == 0) {
  355. // ErrMsg(IDS_ERR_BASEIME, 0);
  356. // _lclose(hfMainFile);
  357. // GlobalFree((HGLOBAL)szImeBuf);
  358. // return TRUE;
  359. continue;
  360. }
  361. CopyMemory(&szImeBuf[uAddr], szGeneric, genericlen);
  362. }
  363. #endif
  364. // Process LIBERAY NAME
  365. {
  366. TCHAR szLibName[MAX_PATH];
  367. int liblen;
  368. LoadString(hInst, IDS_LIBERARY_NAME, szLibName, sizeof(szLibName) / sizeof(TCHAR));
  369. liblen = lstrlen(szLibName);
  370. #ifdef UNICODE
  371. {
  372. char name[MAX_PATH * 2];
  373. WideCharToMultiByte(950, WC_COMPOSITECHECK, szLibName, liblen,
  374. (LPSTR)name, liblen, NULL, NULL);
  375. uAddr=SearchMem((LPSTR)name, liblen, szImeBuf, flen);
  376. }
  377. #else
  378. uAddr=SearchMem((LPSTR)szLibName, liblen, szImeBuf, flen);
  379. #endif
  380. if(uAddr == 0)
  381. {
  382. ErrMsg(IDS_ERR_BASEIME, 0);
  383. _lclose(hfMainFile);
  384. GlobalFree((HGLOBAL)szImeBuf);
  385. return TRUE;
  386. }
  387. lstrcpy(szLibName, szPure_Name);
  388. len=lstrlen(szPure_Name);
  389. szLibName[liblen-4] = 0;
  390. for(i=len; i<liblen-4; i++)
  391. szLibName[i] = _TEXT('$');
  392. lstrcat(szLibName, _TEXT(".IME"));
  393. #ifdef UNICODE
  394. {
  395. char name[MAX_PATH * 2];
  396. WideCharToMultiByte(950, WC_COMPOSITECHECK, szLibName, liblen,
  397. (LPSTR)name, liblen, NULL, NULL);
  398. CopyMemory(&szImeBuf[uAddr], name, liblen * sizeof(TCHAR));
  399. }
  400. #else
  401. CopyMemory(&szImeBuf[uAddr], szLibName, liblen * sizeof(TCHAR));
  402. #endif
  403. }
  404. // Process DEFINETION NAME
  405. // Process IMEUICLASS String
  406. LoadString(hInst, IDS_IMEUICLASS, szBig5, sizeof(szBig5) / sizeof(TCHAR));
  407. len=lstrlen(szBig5);
  408. #ifdef UNICODE
  409. uAddr=SearchMem((LPSTR)szBig5, len*2, szImeBuf, flen);
  410. #else
  411. classlen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  412. (LPWSTR)szClass, len);
  413. uAddr=SearchMem((LPSTR)szClass, classlen*2, szImeBuf, flen);
  414. #endif
  415. if(uAddr == 0)
  416. {
  417. ErrMsg(IDS_ERR_BASEIME, 0);
  418. _lclose(hfMainFile);
  419. GlobalFree((HGLOBAL)szImeBuf);
  420. return TRUE;
  421. }
  422. lstrcpy(szBig5, szPure_Name);
  423. len=lstrlen(szBig5);
  424. for(i = len; i < 8; i++) szBig5[i] = _TEXT(' ');
  425. szBig5[8] = 0;
  426. len = 8;
  427. #ifdef UNICODE
  428. lstrcpy(szUniCode, szBig5);
  429. unilen = len;
  430. #else
  431. unilen = MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  432. (LPWSTR)szUniCode, len);
  433. #endif
  434. while(TRUE)
  435. {
  436. LoadString(hInst, IDS_IMEUICLASS, szBig5, sizeof(szBig5) / sizeof(TCHAR));
  437. len=lstrlen(szBig5);
  438. #ifdef UNICODE
  439. lstrcpy(szClass, szBig5);
  440. classlen = len;
  441. #else
  442. classlen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
  443. (LPWSTR)szClass, len);
  444. #endif
  445. uAddr=SearchMem((BYTE *)szClass, classlen * 2, szImeBuf, flen);
  446. if(uAddr == 0)
  447. break;
  448. CopyMemory(&szImeBuf[uAddr], szUniCode, unilen * 2);
  449. }
  450. // Process Bitmap file
  451. if(!Process_Bitmap(hWnd, szImeBuf, flen))
  452. {
  453. _lclose(hfMainFile);
  454. GlobalFree((HGLOBAL)szImeBuf);
  455. return TRUE;
  456. }
  457. // Process Icon file
  458. if(!Process_Icon(hWnd, szImeBuf, flen))
  459. {
  460. _lclose(hfMainFile);
  461. GlobalFree((HGLOBAL)szImeBuf);
  462. return TRUE;
  463. }
  464. // Process RT_RCDATA
  465. bOverMaxRadical=FALSE;
  466. if(!Process_RT(hfMainFile, szImeBuf, flen, szPure_Name))
  467. {
  468. _lclose(hfMainFile);
  469. // Bug #53630
  470. // _lclose(hfFile);
  471. GlobalFree((HGLOBAL)szImeBuf);
  472. // ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name); // <== @D04
  473. if(bOverMaxRadical)
  474. return FALSE;
  475. else
  476. return TRUE;
  477. }
  478. _lclose(hfMainFile);
  479. //---------------------------------------------------------------------------
  480. // Save to input IME file
  481. //---------------------------------------------------------------------------
  482. StringCchCopy(Ime_File_Name, ARRAYSIZE(Ime_File_Name), szSystem);
  483. StringCchCat(Ime_File_Name, ARRAYSIZE(Ime_File_Name), szPure_Name);
  484. StringCchCat(Ime_File_Name, ARRAYSIZE(Ime_File_Name), _TEXT(".IME"));
  485. #ifdef UNICODE
  486. {
  487. char fname[MAX_PATH * 2];
  488. int ulen = lstrlen(Ime_File_Name);
  489. WideCharToMultiByte(950, WC_COMPOSITECHECK, Ime_File_Name, ulen,
  490. (LPSTR)fname, ulen, NULL, NULL);
  491. fname[ulen] = 0;
  492. hfFile=_lcreat(fname,0);
  493. }
  494. #else
  495. hfFile=_lcreat(Ime_File_Name,0);
  496. #endif
  497. if(hfFile==-1)
  498. {
  499. ErrIOMsg(IDS_ERR_FILEOPEN, Ime_File_Name);
  500. return TRUE;
  501. }
  502. if(flen != _lwrite(hfFile, szImeBuf, flen))
  503. {
  504. ErrIOMsg(IDS_ERR_FILEREAD, Ime_File_Name);
  505. _lclose(hfFile);
  506. return TRUE;
  507. }
  508. _lclose(hfFile);
  509. GlobalFree((HGLOBAL)szImeBuf);
  510. //---------------------------------------------------------------------------
  511. // Install IME and register it
  512. //---------------------------------------------------------------------------
  513. if(!ImmInstallIME(Ime_File_Name,szIme_Name))
  514. {
  515. HideProgress(); // <== @E01
  516. LoadString(hInst, IDS_ERR_IME_ACCESS, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
  517. wsprintf(Show_Mess, Msg_buf, Ime_File_Name);
  518. LoadString(hInst, IDS_ERR_ERROR, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
  519. MessageBox(NULL, Show_Mess, Msg_buf, MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
  520. return TRUE;
  521. }
  522. HandleTaskBar_IME( );
  523. // show message for had produced files
  524. //let Show_Mess be message to be shown
  525. HideProgress(); // <== @E01
  526. LoadString(hInst, IDS_MSG_PROCESS_OK, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
  527. wsprintf(Show_Mess, Msg_buf, szPure_Name);
  528. LoadString(hInst, IDS_MSG_INFOMATION, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
  529. MessageBox(NULL, Show_Mess, Msg_buf,MB_OK|MB_ICONINFORMATION | MB_SETFOREGROUND);
  530. return TRUE;
  531. }
  532. BOOL Process_Bitmap(
  533. HWND hWnd,
  534. BYTE *szImeBuf,
  535. UINT flen)
  536. {
  537. BITMAPINFO *bmif;
  538. HRSRC hResource,hMem;
  539. HBITMAP hBitmap, hOldBitmap;
  540. BYTE *lpBitmap;
  541. UINT reslen,uAddr,nColor,nHead;
  542. HDC hDC,hMemDC;
  543. HFONT hOldFont;
  544. LOGFONT lfFont;
  545. TCHAR szFont[MAX_PATH];
  546. RECT rect;
  547. UINT i,nBitmap;
  548. // Get bitmap from resource, use to find base ime bitmap address
  549. hResource=FindResource(hInst, MAKEINTRESOURCE(IDBM_CMODE_NATIVE), RT_BITMAP);
  550. if (hResource == NULL )
  551. return FALSE;
  552. hMem=LoadResource(hInst, hResource);
  553. if ( hMem == NULL )
  554. return FALSE;
  555. lpBitmap=LockResource(hMem);
  556. if ( lpBitmap == NULL )
  557. {
  558. FreeResource(hMem);
  559. return FALSE;
  560. }
  561. reslen=SizeofResource(hInst,hResource);
  562. uAddr=SearchMem(lpBitmap, reslen, szImeBuf, flen);
  563. if(uAddr == 0) {
  564. UnlockResource(hMem);
  565. FreeResource(hMem);
  566. ErrMsg(IDS_ERR_BASEIME, 0);
  567. return FALSE;
  568. }
  569. bmif=(BITMAPINFO *)lpBitmap;
  570. for(nColor=1, i=0; i<bmif->bmiHeader.biBitCount; i++)
  571. nColor*=2;
  572. nHead=sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD);
  573. bmif=(BITMAPINFO *)GlobalAlloc(LMEM_FIXED, nHead);
  574. if(!bmif) {
  575. UnlockResource(hMem);
  576. FreeResource(hMem);
  577. ErrMsg(IDS_ERR_BASEIME, 0);
  578. return FALSE;
  579. }
  580. CopyMemory(bmif, lpBitmap, nHead);
  581. UnlockResource(hMem);
  582. FreeResource(hMem);
  583. // Create a Memory DC, and load bitmap to it
  584. hDC = GetDC(hWnd);
  585. hMemDC = CreateCompatibleDC(hDC);
  586. hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_NATIVE));
  587. ReleaseDC(hWnd, hDC);
  588. hOldBitmap = SelectObject(hMemDC, hBitmap);
  589. // Select 16 point size font
  590. hOldFont = GetCurrentObject(hMemDC, OBJ_FONT);
  591. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  592. lfFont.lfWeight=400;
  593. lfFont.lfHeight=-16;
  594. lfFont.lfWidth = 8;
  595. lfFont.lfOutPrecision= OUT_TT_ONLY_PRECIS;
  596. lfFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
  597. LoadString(hInst, IDS_FONT_NAME, szFont, sizeof(szFont) / sizeof(TCHAR));
  598. lstrcpy(lfFont.lfFaceName, szFont);
  599. SelectObject(hMemDC, CreateFontIndirect(&lfFont));
  600. // Set color
  601. SetTextColor(hMemDC, RGB(0x80, 0x00, 0x00)); // Dark red
  602. SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0)); // Light gray
  603. // Set rectangle, and write IME name 1st DBCS to Memory DC
  604. rect.left=3;
  605. rect.top=3;
  606. rect.right=rect.left-lfFont.lfHeight;
  607. rect.bottom=rect.top-lfFont.lfHeight;
  608. ExtTextOut(hMemDC, rect.left, rect.top, ETO_OPAQUE,
  609. &rect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
  610. // Allocate bitmap buffer
  611. nBitmap=(UINT)bmif->bmiHeader.biSizeImage;
  612. lpBitmap=(BYTE *)GlobalAlloc(LMEM_FIXED, nBitmap);
  613. if(!lpBitmap) {
  614. GlobalFree((HGLOBAL)bmif);
  615. DeleteObject(SelectObject(hMemDC, hOldFont));
  616. DeleteObject(SelectObject(hMemDC, hOldBitmap));
  617. DeleteDC(hMemDC);
  618. ErrMsg(IDS_ERR_BASEIME, 0);
  619. return FALSE;
  620. }
  621. // Get Device Independent bitmap from Memory DC
  622. GetDIBits(hMemDC, hBitmap, 0, bmif->bmiHeader.biHeight,
  623. lpBitmap, bmif, DIB_RGB_COLORS);
  624. CopyMemory(&szImeBuf[uAddr], bmif, nHead);
  625. CopyMemory(&szImeBuf[uAddr+nHead], lpBitmap, nBitmap);
  626. DeleteObject(SelectObject(hMemDC, hOldFont));
  627. DeleteObject(SelectObject(hMemDC, hOldBitmap));
  628. DeleteDC(hMemDC);
  629. GlobalFree((HGLOBAL)bmif);
  630. GlobalFree((HGLOBAL)lpBitmap);
  631. return TRUE;
  632. }
  633. #define ENBOLD_ICONSIZE 24
  634. BOOL UpdateMiniIMEIcon(
  635. HWND hWnd,
  636. LPBYTE lpbMiniImeFileImage,
  637. UINT uLen,
  638. int nIconID)
  639. {
  640. UINT uAddr;
  641. LPBITMAPINFOHEADER lpbmIconInfoHeader;
  642. DWORD dwHeaderSize;
  643. HDC hMemDC;
  644. HBITMAP hBitmap, hOldBitmap;
  645. LPVOID lpBitmap, lpBitmap_Section;
  646. DWORD dwBitmap;
  647. {
  648. HRSRC hResIcon;
  649. DWORD dwSize;
  650. LPBITMAPINFOHEADER lpResIcon;
  651. hResIcon = LoadResource(hInst, FindResource(hInst,
  652. MAKEINTRESOURCE(nIconID), RT_ICON));
  653. if (!hResIcon) {
  654. HideProgress(); // <== @E01
  655. MessageBox(NULL, _TEXT("Load icon fail !"), _TEXT("Bug"), MB_OK | MB_SETFOREGROUND );
  656. return (FALSE);
  657. }
  658. dwSize = SizeofResource(hInst, hResIcon);
  659. uAddr = 0;
  660. lpResIcon = LockResource(hResIcon);
  661. if (!lpResIcon) {
  662. goto UpdateIconFreeRes;
  663. }
  664. uAddr = SearchMem((LPBYTE)lpResIcon, dwSize, lpbMiniImeFileImage, uLen);
  665. if (uAddr) {
  666. DWORD nColors;
  667. if (lpResIcon->biBitCount != 24) {
  668. UINT i;
  669. for (nColors = 1, i = 0; i < lpResIcon->biBitCount; i++) {
  670. nColors *= 2;
  671. }
  672. } else {
  673. // no RGBQUAD for 24 bit per pixel format
  674. nColors = 0;
  675. }
  676. dwHeaderSize = lpResIcon->biSize + nColors * sizeof(RGBQUAD);
  677. lpbmIconInfoHeader = (LPBITMAPINFOHEADER)GlobalAlloc(GMEM_FIXED,
  678. dwHeaderSize);
  679. if (lpbmIconInfoHeader) {
  680. CopyMemory(lpbmIconInfoHeader, lpResIcon, dwHeaderSize);
  681. lpbmIconInfoHeader->biHeight /= 2;
  682. dwBitmap = (lpbmIconInfoHeader->biWidth + 7) / 8 *
  683. lpbmIconInfoHeader->biHeight * lpResIcon->biBitCount;
  684. } else {
  685. uAddr = 0;
  686. }
  687. lpBitmap = GlobalAlloc(GMEM_FIXED, dwBitmap);
  688. if (!lpBitmap) {
  689. uAddr = 0;
  690. }
  691. }
  692. UnlockResource(hResIcon);
  693. UpdateIconFreeRes:
  694. FreeResource(hResIcon);
  695. if (uAddr == 0) {
  696. return (FALSE);
  697. }
  698. }
  699. {
  700. HDC hDC;
  701. // create a memory DC
  702. hDC = GetDC(hWnd);
  703. hMemDC = CreateCompatibleDC(hDC);
  704. ReleaseDC(hWnd, hDC);
  705. }
  706. hBitmap = CreateDIBSection(hMemDC, (LPBITMAPINFO)lpbmIconInfoHeader,
  707. DIB_RGB_COLORS, &lpBitmap_Section, NULL, 0);
  708. hOldBitmap = SelectObject(hMemDC, hBitmap);
  709. {
  710. HFONT hOldFont;
  711. LOGFONT lfFont;
  712. RECT rcRect;
  713. POINT ptOffset;
  714. rcRect.left = rcRect.top = 0;
  715. // biHeight - 1, biHeight is not including
  716. rcRect.right = rcRect.bottom = lpbmIconInfoHeader->biHeight;
  717. hOldFont = GetCurrentObject(hMemDC, OBJ_FONT);
  718. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  719. if (lpbmIconInfoHeader->biHeight >= ENBOLD_ICONSIZE) {
  720. lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4 - 2) * (-1);
  721. ptOffset.x = 4;
  722. ptOffset.y = 3;
  723. } else if (lpbmIconInfoHeader->biHeight >= 22) {
  724. lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4) * (-1);
  725. ptOffset.x = 3;
  726. ptOffset.y = 3;
  727. } else if (lpbmIconInfoHeader->biHeight >= 18) {
  728. lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 3) * (-1);
  729. ptOffset.x = 3;
  730. ptOffset.y = 3;
  731. } else {
  732. lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4) * (-1);
  733. ptOffset.x = 3;
  734. ptOffset.y = 3;
  735. }
  736. lfFont.lfWidth = 0;
  737. lfFont.lfWeight = 100;
  738. lfFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  739. lfFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
  740. lfFont.lfFaceName[0] = '\0';
  741. LoadString(hInst, IDS_FONT_NAME, lfFont.lfFaceName,
  742. sizeof(lfFont.lfFaceName) / sizeof(TCHAR));
  743. hOldFont = SelectObject(hMemDC, CreateFontIndirect(&lfFont));
  744. SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0)); // light gray
  745. // write 1st DBCS to memory DC for shadow
  746. SetTextColor(hMemDC, RGB(0xFF, 0xFF, 0xFF)); // white
  747. ExtTextOut(hMemDC, rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
  748. ETO_OPAQUE, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
  749. // write 1st DBCS to memory DC
  750. SetTextColor(hMemDC, RGB(0x00, 0x00, 0xFF)); // blue
  751. SetBkMode(hMemDC, TRANSPARENT);
  752. ptOffset.x -= 1;
  753. ptOffset.y -= 1;
  754. ExtTextOut(hMemDC, rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
  755. ETO_CLIPPED, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
  756. // write 1st DBCS to memory DC to enbold it
  757. if (lpbmIconInfoHeader->biHeight > ENBOLD_ICONSIZE) {
  758. ptOffset.x -= 1;
  759. ExtTextOut(hMemDC,
  760. rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
  761. ETO_CLIPPED, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
  762. }
  763. SelectObject(hMemDC, GetStockObject(NULL_BRUSH));
  764. SelectObject(hMemDC, GetStockObject(BLACK_PEN));
  765. Rectangle(hMemDC, rcRect.left, rcRect.top,
  766. rcRect.right, rcRect.bottom);
  767. rcRect.right = rcRect.bottom = lpbmIconInfoHeader->biHeight - 1;
  768. MoveToEx(hMemDC, rcRect.left, rcRect.top + 1, NULL);
  769. LineTo(hMemDC, rcRect.left + 2, rcRect.top + 1);
  770. MoveToEx(hMemDC, rcRect.right, rcRect.top + 1, NULL);
  771. LineTo(hMemDC, rcRect.right - 2, rcRect.top + 1);
  772. MoveToEx(hMemDC, rcRect.left, rcRect.bottom - 1, NULL);
  773. LineTo(hMemDC, rcRect.left + 2, rcRect.bottom - 1);
  774. MoveToEx(hMemDC, rcRect.right, rcRect.bottom - 1, NULL);
  775. LineTo(hMemDC, rcRect.right - 2, rcRect.bottom - 1);
  776. GetDIBits(hMemDC, hBitmap, 0, lpbmIconInfoHeader->biHeight, lpBitmap,
  777. (LPBITMAPINFO)lpbmIconInfoHeader, DIB_RGB_COLORS);
  778. CopyMemory(&lpbMiniImeFileImage[uAddr + dwHeaderSize], lpBitmap, dwBitmap);
  779. }
  780. DeleteObject(SelectObject(hMemDC, hOldBitmap));
  781. DeleteObject(hMemDC);
  782. GlobalFree((HGLOBAL)lpbmIconInfoHeader);
  783. GlobalFree((HGLOBAL)lpBitmap);
  784. return (TRUE);
  785. }
  786. BOOL Process_Icon(
  787. HWND hWnd,
  788. LPBYTE lpbMiniImeFileImage,
  789. UINT uLen)
  790. {
  791. HRSRC hResIcon;
  792. LPVOID lpResIcon;
  793. int nIconID32, nIconID16, nIconID18, nIconID22;
  794. // Get Icon from resource, use to find base IME Icon address
  795. hResIcon = LoadResource(hInst, FindResource(hInst,
  796. MAKEINTRESOURCE(IDIC_IME_ICON), RT_GROUP_ICON));
  797. if ( hResIcon == NULL )
  798. return FALSE;
  799. lpResIcon = LockResource(hResIcon);
  800. if ( lpResIcon == NULL )
  801. {
  802. FreeResource(hResIcon);
  803. return FALSE;
  804. }
  805. nIconID32 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
  806. 32, 32, LR_DEFAULTCOLOR);
  807. nIconID16 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
  808. 16, 16, LR_DEFAULTCOLOR);
  809. nIconID18 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
  810. 18, 18, LR_DEFAULTCOLOR);
  811. nIconID22 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
  812. 22, 22, LR_DEFAULTCOLOR);
  813. UnlockResource(hResIcon);
  814. FreeResource(hResIcon);
  815. if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID32)) {
  816. return (FALSE);
  817. }
  818. if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID16)) {
  819. return (FALSE);
  820. }
  821. if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID18)) {
  822. return (FALSE);
  823. }
  824. if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID22)) {
  825. return (FALSE);
  826. }
  827. return (TRUE);
  828. }
  829. BOOL Process_RT(HFILE hfFile, BYTE *szImeBuf, UINT Imelen, TCHAR *szPure_Name)
  830. {
  831. HGLOBAL hResData;
  832. TCHAR szStr[MAX_CHAR_NUM+10];
  833. TCHAR *szBuf;
  834. UINT uAddr1,uAddr2;
  835. UINT len,flen,i;
  836. #ifdef UNICODE
  837. BOOL bUniCode = TRUE;
  838. TCHAR *buf;
  839. #endif
  840. LPVALIDCHAR lpValidChar;
  841. // load valid char in choose/input state
  842. hResData = LoadResource(hInst, FindResource(hInst,
  843. MAKEINTRESOURCE(IDRC_VALIDCHAR), RT_RCDATA));
  844. if ( hResData == NULL )
  845. {
  846. return FALSE;
  847. }
  848. lpValidChar = (LPVALIDCHAR)LockResource(hResData);
  849. if ( lpValidChar == NULL )
  850. {
  851. FreeResource(hResData);
  852. return FALSE;
  853. }
  854. *(LPVALIDCHAR)&Valid = *lpValidChar;
  855. UnlockResource(hResData);
  856. FreeResource(hResData);
  857. uAddr1 = SearchMem((BYTE *)&Valid, sizeof(VALIDCHAR), szImeBuf, Imelen);
  858. if(uAddr1 == 0)
  859. {
  860. ErrMsg(IDS_ERR_BASEIME, 0);
  861. return FALSE;
  862. }
  863. // IME table files
  864. hResData = LoadResource(hInst, FindResource(hInst,
  865. MAKEINTRESOURCE(IDRC_TABLEFILES), RT_RCDATA));
  866. if ( hResData == NULL )
  867. return FALSE;
  868. *(LPTABLEFILES)&Table = *(LPTABLEFILES)LockResource(hResData);
  869. UnlockResource(hResData);
  870. FreeResource(hResData);
  871. uAddr2 = SearchMem((BYTE *)&Table, sizeof(TABLEFILES), szImeBuf, Imelen);
  872. if(uAddr2 == 0)
  873. {
  874. ErrMsg(IDS_ERR_BASEIME, 0);
  875. return FALSE;
  876. }
  877. // get file length
  878. flen = _llseek(hfFile, 0L, 2);
  879. // Allocate Memory
  880. szBuf = (TCHAR *)GlobalAlloc(GMEM_FIXED, flen);
  881. if(!szBuf)
  882. {
  883. ErrMsg(IDS_ERR_MEMORY, 0);
  884. return FALSE;
  885. }
  886. #ifdef UNICODE
  887. _llseek(hfFile,0L,0); // Skip 'FF FE'
  888. {
  889. BYTE ubuf[3];
  890. if(2 != _lread(hfFile, ubuf, 2))
  891. {
  892. GlobalFree((HGLOBAL)szBuf);
  893. ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name);
  894. return FALSE;
  895. }
  896. if(ubuf[0] == 0xff && ubuf[1] == 0xfe) // UNICODE
  897. flen -= 2;
  898. else
  899. {
  900. _llseek(hfFile, 0L, 0);
  901. bUniCode = 0;
  902. }
  903. }
  904. #else
  905. _llseek(hfFile,0L,0); // Move file pointer to begining
  906. #endif
  907. // Read file to memory
  908. if(flen != _lread(hfFile, szBuf, flen))
  909. {
  910. GlobalFree((HGLOBAL)szBuf);
  911. ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name);
  912. return FALSE;
  913. }
  914. #ifdef UNICODE
  915. if(!bUniCode)
  916. {
  917. buf = (TCHAR *)GlobalAlloc(GMEM_FIXED, flen * 2);
  918. if(!buf)
  919. {
  920. GlobalFree((HGLOBAL)szBuf);
  921. ErrMsg(IDS_ERR_MEMORY, 0);
  922. return FALSE;
  923. }
  924. i = MultiByteToWideChar(950, MB_PRECOMPOSED, (BYTE *)szBuf, flen,
  925. (LPTSTR)buf, flen);
  926. GlobalFree((HGLOBAL)szBuf);
  927. szBuf = buf;
  928. flen = i * 2;
  929. }
  930. #endif
  931. // Allocate global memory
  932. hRadical = GlobalAlloc(GMEM_MOVEABLE, ALLOCBLOCK * sizeof(RADICALBUF));
  933. if(!hRadical)
  934. {
  935. GlobalFree((HGLOBAL)szBuf);
  936. ErrMsg(IDS_ERR_MEMORY, 0);
  937. return FALSE;
  938. }
  939. nRadicalBuffsize = ALLOCBLOCK;
  940. iRadicalBuff = 0;
  941. lpRadical = (LPRADICALBUF)GlobalLock(hRadical);
  942. if(!lpRadical)
  943. {
  944. GlobalFree((HGLOBAL)szBuf);
  945. GlobalFree(hRadical);
  946. ErrMsg(IDS_ERR_MEMORY, 0);
  947. return FALSE;
  948. }
  949. hPhrase = GlobalAlloc(GMEM_MOVEABLE, ALLOCBLOCK * sizeof(PHRASEBUF));
  950. if(!hPhrase)
  951. {
  952. GlobalFree((HGLOBAL)szBuf);
  953. GlobalUnlock(hRadical);
  954. GlobalFree(hRadical);
  955. ErrMsg(IDS_ERR_MEMORY, 0);
  956. return FALSE;
  957. }
  958. nPhraseBuffsize = ALLOCBLOCK;
  959. iPhraseBuff = 0;
  960. lpPhrase = (LPPHRASEBUF)GlobalLock(hPhrase);
  961. if(!lpPhrase)
  962. {
  963. GlobalFree((HGLOBAL)szBuf);
  964. GlobalUnlock(hRadical);
  965. GlobalFree(hRadical);
  966. GlobalFree(hPhrase);
  967. ErrMsg(IDS_ERR_MEMORY, 0);
  968. return FALSE;
  969. }
  970. len=0;
  971. idxLine = 0;
  972. for(i = 0; i < (flen/cntChar+1); i++)
  973. {
  974. if((szBuf[i] == 0x0d) || (szBuf[i] == 0x0a))
  975. {
  976. if(len != 0)
  977. {
  978. if(!Parse(szStr, len))
  979. break;
  980. len=0;
  981. idxLine ++;
  982. }
  983. continue;
  984. }
  985. if((szBuf[i] == 0x1a) || (i == flen/cntChar))
  986. {
  987. if(len != 0)
  988. {
  989. if(!Parse(szStr, len))
  990. break;
  991. }
  992. break;
  993. }
  994. if(len < MAX_CHAR_NUM)
  995. szStr[len ++] = szBuf[i];
  996. }
  997. GlobalFree((HGLOBAL)szBuf);
  998. if(!WritetoFile(szPure_Name))
  999. {
  1000. GlobalUnlock(hRadical);
  1001. GlobalUnlock(hPhrase);
  1002. GlobalFree(hRadical);
  1003. GlobalFree(hPhrase);
  1004. return FALSE;
  1005. }
  1006. GlobalUnlock(hRadical);
  1007. GlobalUnlock(hPhrase);
  1008. GlobalFree(hRadical);
  1009. GlobalFree(hPhrase);
  1010. // Set Beep for candidates status
  1011. Valid.fwProperties1 = (WORD)(bCandBeep ? 0 : 1);
  1012. CopyMemory(&szImeBuf[uAddr1], &Valid, sizeof(VALIDCHAR));
  1013. CopyMemory(&szImeBuf[uAddr2], &Table, sizeof(TABLEFILES));
  1014. return TRUE;
  1015. }
  1016. int __cdecl subComp(const void *Pointer1, const void *Pointer2)
  1017. {
  1018. LPRADICALBUF lpRadical1 = (LPRADICALBUF)Pointer1;
  1019. LPRADICALBUF lpRadical2 = (LPRADICALBUF)Pointer2;
  1020. WORD wWord1,wWord2;
  1021. UINT i;
  1022. for(i = 0; i < Valid.nMaxKey; i++)
  1023. {
  1024. wWord1 = Valid.wChar2SeqTbl[lpRadical1->szRadical[i] - 0x20];
  1025. wWord2 = Valid.wChar2SeqTbl[lpRadical2->szRadical[i] - 0x20];
  1026. if(wWord1 == wWord2)
  1027. continue;
  1028. if(wWord1 > wWord2)
  1029. return 1;
  1030. else
  1031. return -1;
  1032. }
  1033. return 0;
  1034. }
  1035. BOOL WritetoFile(
  1036. TCHAR *szPure_Name)
  1037. {
  1038. HFILE hTbl,hTblPtr,hTblCode;
  1039. HANDLE hKey;
  1040. UCHAR *szKey;
  1041. UCHAR szPtr[MAX_CHAR_NUM+10];
  1042. TCHAR szWindows[MAX_PATH];
  1043. TCHAR szFName[MAX_PATH];
  1044. TCHAR szTotal[MAX_CHAR_NUM];
  1045. UCHAR szPhrase[MAX_CHAR_NUM];
  1046. UINT len, i, j, k, l;
  1047. UINT nKey,nPtr,nBit,nByte;
  1048. WORD wlen,wTotalLen;
  1049. WORD wSeq;
  1050. WORD wWord;
  1051. DWORD dwRadical;
  1052. BOOL bPhrase;
  1053. UINT nAlloc;
  1054. #ifdef UNICODE
  1055. DWORD lPtrlen,lPrevlen;
  1056. UINT ii;
  1057. #else
  1058. WORD wPtrlen,wPrevlen;
  1059. #endif
  1060. // Get System directory
  1061. len = GetSystemDirectory((LPTSTR)szWindows, ARRAYSIZE(szWindows) - 1);
  1062. if (szWindows[len - 1] != '\\') { // consider C:\ ;
  1063. szWindows[len++] = '\\';
  1064. szWindows[len] = 0;
  1065. }
  1066. Valid.nMaxKey=szKey_Num_Str[0] - _TEXT('0');
  1067. j=(UINT)Valid.nSeqCode;
  1068. if(j < 1) {
  1069. ErrMsg(IDS_ERR_NORADICAL, 0);
  1070. return FALSE;
  1071. }
  1072. for(nBit=1; (j/=2) != 0; nBit++) ;
  1073. nByte=(nBit * Valid.nMaxKey + 7) / 8;
  1074. if(nByte > MAX_BYTE) {
  1075. TCHAR szErrStr[MAX_PATH];
  1076. TCHAR szShowMsg[MAX_PATH];
  1077. UINT nMaxKey;
  1078. nMaxKey=(MAX_BYTE*8)/nBit;
  1079. HideProgress();// <== @E01
  1080. LoadString(hInst, IDS_ERR_OVER_BITLEN, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
  1081. wsprintf(szShowMsg, szErrStr, Valid.nSeqCode, nMaxKey);
  1082. MessageBox(NULL, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
  1083. bOverMaxRadical=TRUE;
  1084. return FALSE;
  1085. }
  1086. qsort(lpRadical, iRadicalBuff, sizeof(RADICALBUF), subComp);
  1087. // Allocate Memory
  1088. nAlloc=ALLOCBLOCK*(nByte+sizeof(WORD));
  1089. hKey = GlobalAlloc(GMEM_MOVEABLE, nAlloc+100);
  1090. if(!hKey) {
  1091. ErrMsg(IDS_ERR_MEMORY, 0);
  1092. return FALSE;
  1093. }
  1094. szKey = GlobalLock(hKey);
  1095. if(!szKey) {
  1096. GlobalFree(hKey);
  1097. ErrMsg(IDS_ERR_MEMORY, 0);
  1098. return FALSE;
  1099. }
  1100. nKey=nByte+sizeof(WORD);
  1101. ZeroMemory(szKey, nKey);
  1102. ZeroMemory(szPtr, nKey); //@D02A
  1103. nPtr=0;
  1104. bPhrase=FALSE;
  1105. for(i=0; i<iRadicalBuff; i++)
  1106. {
  1107. dwRadical=0;
  1108. for(j=0; j<Valid.nMaxKey; j++)
  1109. {
  1110. wSeq=Valid.wChar2SeqTbl[lpRadical[i].szRadical[j]-0x20];
  1111. // Check using undefined radical
  1112. if((wSeq == 0) && (lpRadical[i].szRadical[j] != _TEXT(' ')))
  1113. break;
  1114. dwRadical=(dwRadical << nBit)+wSeq;
  1115. }
  1116. if(j == Valid.nMaxKey)
  1117. {
  1118. wWord=lpRadical[i].wCode;
  1119. if(wWord != 0)
  1120. {
  1121. if(nKey == nAlloc)
  1122. {
  1123. HANDLE hTemp;
  1124. nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
  1125. GlobalUnlock(hKey);
  1126. hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
  1127. if(hTemp == NULL)
  1128. {
  1129. GlobalFree(hKey);
  1130. ErrMsg(IDS_ERR_MEMORY, 0);
  1131. return FALSE;
  1132. }
  1133. hKey=hTemp;
  1134. szKey=GlobalLock(hKey);
  1135. if(szKey == NULL)
  1136. {
  1137. GlobalFree(hKey);
  1138. ErrMsg(IDS_ERR_MEMORY, 0);
  1139. return FALSE;
  1140. }
  1141. }
  1142. *((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
  1143. *((LPUNAWORD)&szKey[nKey+nByte])=wWord;// <== @D05
  1144. // *((DWORD *)&szKey[nKey])=dwRadical;
  1145. // *((WORD *)&szKey[nKey+nByte])=wWord;
  1146. nKey+=(nByte+sizeof(WORD));
  1147. }
  1148. wTotalLen=GetPhrase(i, szTotal);
  1149. if(wTotalLen == 0)
  1150. continue;
  1151. #ifdef UNICODE
  1152. ZeroMemory(szPhrase, MAX_CHAR_NUM);
  1153. wlen=0;
  1154. for(k = 0; k < wTotalLen; k++)
  1155. {
  1156. if(szTotal[k+1] != 1)
  1157. {
  1158. for(l = k; l < wTotalLen; l++)
  1159. {
  1160. *((TCHAR *)&szPhrase[wlen]) = szTotal[l];
  1161. wlen += 2;
  1162. if(szTotal[l] == 1)
  1163. break;
  1164. }
  1165. k = l;
  1166. }
  1167. else
  1168. {
  1169. if(nKey == nAlloc)
  1170. {
  1171. HANDLE hTemp;
  1172. nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
  1173. GlobalUnlock(hKey);
  1174. hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
  1175. if(hTemp == NULL)
  1176. {
  1177. GlobalFree(hKey);
  1178. ErrMsg(IDS_ERR_MEMORY, 0);
  1179. return FALSE;
  1180. }
  1181. hKey=hTemp;
  1182. szKey=GlobalLock(hKey);
  1183. if(szKey == NULL)
  1184. {
  1185. GlobalFree(hKey);
  1186. ErrMsg(IDS_ERR_MEMORY, 0);
  1187. return FALSE;
  1188. }
  1189. }
  1190. // *((DWORD *)&szKey[nKey])=dwRadical;
  1191. *((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
  1192. //*((TCHAR *)&szKey[nKey+nByte]) = szTotal[k];
  1193. *((LPUNATCHAR)&szKey[nKey+nByte]) = szTotal[k]; // <== @D05
  1194. nKey += (nByte+sizeof(WORD));
  1195. if(szTotal[k+1] == 1) k ++;
  1196. }
  1197. }
  1198. #else
  1199. wlen=0;
  1200. for(k=0; k<wTotalLen; k += 2)
  1201. {
  1202. if(szTotal[k+1] & 0x80)
  1203. {
  1204. for(l=k; l<wTotalLen; l += 2)
  1205. {
  1206. szPhrase[wlen++] = szTotal[l];
  1207. szPhrase[wlen++] = szTotal[l+1];
  1208. if(!(szTotal[l+1] & 0x80))
  1209. break;
  1210. }
  1211. k = l;
  1212. }
  1213. else
  1214. {
  1215. if(nKey == nAlloc)
  1216. {
  1217. HANDLE hTemp;
  1218. nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
  1219. GlobalUnlock(hKey);
  1220. hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
  1221. if(hTemp == NULL)
  1222. {
  1223. GlobalFree(hKey);
  1224. ErrMsg(IDS_ERR_MEMORY, 0);
  1225. return FALSE;
  1226. }
  1227. hKey=hTemp;
  1228. szKey=GlobalLock(hKey);
  1229. if(szKey == NULL)
  1230. {
  1231. GlobalFree(hKey);
  1232. ErrMsg(IDS_ERR_MEMORY, 0);
  1233. return FALSE;
  1234. }
  1235. }
  1236. *((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
  1237. szKey[nKey+nByte] = szTotal[k];
  1238. szKey[nKey+nByte+1] = szTotal[k+1] | 0x80;
  1239. nKey += (nByte+sizeof(WORD));
  1240. }
  1241. }
  1242. #endif
  1243. if(wlen == 0)
  1244. continue;
  1245. if(!bPhrase)
  1246. {
  1247. // Use first 5 characters of IME filename as table header name
  1248. len=lstrlen(szPure_Name);
  1249. if(len > 5)
  1250. len=5;
  1251. CopyMemory(Table.szTblFile[0], szPure_Name, len * cntChar);
  1252. Table.szTblFile[0][len]=0;
  1253. lstrcpy(Table.szTblFile[1], Table.szTblFile[0]);
  1254. lstrcpy(Table.szTblFile[2], Table.szTblFile[0]);
  1255. lstrcat(Table.szTblFile[0], _TEXT(".TBL"));
  1256. lstrcat(Table.szTblFile[1], _TEXT("PTR.TBL"));
  1257. lstrcat(Table.szTblFile[2], _TEXT("PHR.TBL"));
  1258. StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
  1259. StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[0]);
  1260. #ifdef UNICODE
  1261. {
  1262. char fname[MAX_PATH * 2];
  1263. int lenx = lstrlen(szFName);
  1264. WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
  1265. (LPSTR)fname, lenx, NULL, NULL);
  1266. fname[lenx] = 0;
  1267. hTbl=_lcreat(fname, 0);
  1268. }
  1269. #else
  1270. hTbl=_lcreat(szFName, 0);
  1271. #endif
  1272. if(hTbl == -1)
  1273. {
  1274. ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[0]);
  1275. GlobalUnlock(hKey);
  1276. GlobalFree(hKey);
  1277. return FALSE;
  1278. }
  1279. StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
  1280. StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[1]);
  1281. #ifdef UNICODE
  1282. {
  1283. char fname[MAX_PATH * 2];
  1284. int lenx = lstrlen(szFName);
  1285. WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
  1286. (LPSTR)fname, lenx, NULL, NULL);
  1287. fname[lenx] = 0;
  1288. hTblPtr = _lcreat(fname, 0);
  1289. }
  1290. #else
  1291. hTblPtr = _lcreat(szFName, 0);
  1292. #endif
  1293. if(hTblPtr == -1)
  1294. {
  1295. ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[1]);
  1296. GlobalUnlock(hKey);
  1297. GlobalFree(hKey);
  1298. return FALSE;
  1299. }
  1300. StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
  1301. StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[2]);
  1302. #ifdef UNICODE
  1303. {
  1304. char fname[MAX_PATH * 2];
  1305. int lenx = lstrlen(szFName);
  1306. WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
  1307. (LPSTR)fname, lenx, NULL, NULL);
  1308. fname[lenx] = 0;
  1309. hTblCode = _lcreat(fname, 0);
  1310. }
  1311. #else
  1312. hTblCode = _lcreat(szFName, 0);
  1313. #endif
  1314. if(hTblCode == -1) {
  1315. ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[2]);
  1316. GlobalUnlock(hKey);
  1317. GlobalFree(hKey);
  1318. return FALSE;
  1319. }
  1320. #ifdef UNICODE
  1321. nPtr = nByte+sizeof(DWORD);
  1322. #else
  1323. nPtr = nByte+sizeof(WORD);
  1324. #endif
  1325. //ZeroMemory(szKey, nPtr*2);
  1326. ZeroMemory(szKey, nByte+sizeof(WORD) );
  1327. #ifdef UNICODE
  1328. lPtrlen=0;
  1329. lPrevlen=0;
  1330. #else
  1331. wPtrlen=0;
  1332. wPrevlen=0;
  1333. #endif
  1334. bPhrase=TRUE;
  1335. }
  1336. #ifdef UNICODE
  1337. CopyMemory(szTotal, szPhrase, wlen + cntChar);
  1338. ii = 0;
  1339. for(j = 0; j < (UINT)wlen / cntChar; j ++)
  1340. {
  1341. if(lPtrlen >= 0xfffffffd)
  1342. {
  1343. #else
  1344. for(j = 0; j < (UINT)wlen; j += 2)
  1345. {
  1346. if(wPtrlen >= 0xfffd)
  1347. {
  1348. #endif
  1349. ErrMsg(IDS_ERR_OVER_MAXLEN, 0);
  1350. GlobalUnlock(hKey);
  1351. GlobalFree(hKey);
  1352. return FALSE;
  1353. }
  1354. #ifdef UNICODE
  1355. if(szTotal[j] != 1)
  1356. {
  1357. lPtrlen++;
  1358. // *((TCHAR *)&szPhrase[ii]) = szTotal[j];
  1359. *((LPUNATCHAR)&szPhrase[ii]) = szTotal[j]; // <== @D05
  1360. ii += 2;
  1361. continue;
  1362. }
  1363. #else
  1364. wPtrlen++;
  1365. if(*((LPUNAWORD)&szPhrase[j]) & END_PHRASE) // <== @D05
  1366. continue;
  1367. #endif
  1368. if(nPtr >= MAX_CHAR_NUM)
  1369. {
  1370. // Write file from key buffer
  1371. if(nPtr != _lwrite(hTblPtr, (BYTE *)szPtr, nPtr))
  1372. {
  1373. ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[1]);
  1374. GlobalUnlock(hKey);
  1375. GlobalFree(hKey);
  1376. return FALSE;
  1377. }
  1378. nPtr=0;
  1379. }
  1380. #ifndef UNICODE
  1381. *((LPUNAWORD)&szPhrase[j]) |= END_PHRASE; // <== @D05
  1382. *((LPUNADWORD)&szPtr[nPtr])=dwRadical; // <== @D05
  1383. *((LPUNAWORD)&szPtr[nPtr+nByte])=wPrevlen; // <== @D05
  1384. nPtr+=(nByte+sizeof(WORD));
  1385. wPrevlen=wPtrlen;
  1386. #else
  1387. *((LPUNADWORD)&szPtr[nPtr])=dwRadical; // <== @D05
  1388. *((LPUNADWORD)&szPtr[nPtr+nByte])=lPrevlen; // <== @D05
  1389. nPtr+=(nByte+sizeof(DWORD));
  1390. lPrevlen=lPtrlen;
  1391. #endif
  1392. }
  1393. #ifdef UNICODE
  1394. wlen = ii / 2;
  1395. #endif
  1396. if((wlen * (UINT)cntChar) != _lwrite(hTblCode, szPhrase, wlen * cntChar))
  1397. {
  1398. ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[2]);
  1399. GlobalUnlock(hKey);
  1400. GlobalFree(hKey);
  1401. return FALSE;
  1402. }
  1403. }
  1404. }
  1405. if(bPhrase)
  1406. {
  1407. szPhrase[0] = (BYTE) 0xff;
  1408. szPhrase[1] = (BYTE) 0xff;
  1409. if(2 != _lwrite(hTblCode, (BYTE *)szPhrase, 2))
  1410. {
  1411. ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[2]);
  1412. GlobalUnlock(hKey);
  1413. GlobalFree(hKey);
  1414. return FALSE;
  1415. }
  1416. _lclose(hTblCode);
  1417. }
  1418. else
  1419. {
  1420. lstrcpy(Table.szTblFile[0], szPure_Name);
  1421. lstrcat(Table.szTblFile[0], _TEXT(".TBL"));
  1422. StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
  1423. StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[0]);
  1424. #ifdef UNICODE
  1425. {
  1426. char fname[MAX_PATH * 2];
  1427. int lenx = lstrlen(szFName);
  1428. WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
  1429. (LPSTR)fname, lenx, NULL, NULL);
  1430. fname[lenx] = 0;
  1431. hTbl = _lcreat(fname, 0);
  1432. }
  1433. #else
  1434. hTbl = _lcreat(szFName, 0);
  1435. #endif
  1436. if(hTbl == -1)
  1437. {
  1438. ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[0]);
  1439. GlobalUnlock(hKey);
  1440. GlobalFree(hKey);
  1441. return FALSE;
  1442. }
  1443. }
  1444. for(i = 0; i < nByte+sizeof(WORD); i++)
  1445. szKey[nKey++] = (BYTE) 0xff;
  1446. // Write file from key buffer
  1447. if(nKey != _lwrite(hTbl, szKey, nKey))
  1448. {
  1449. ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[0]);
  1450. GlobalUnlock(hKey);
  1451. GlobalFree(hKey);
  1452. return FALSE;
  1453. }
  1454. _lclose(hTbl);
  1455. GlobalUnlock(hKey);
  1456. GlobalFree(hKey);
  1457. if(bPhrase)
  1458. {
  1459. for(i = 0; i < nByte; i++)
  1460. szPtr[nPtr++] = (BYTE) 0xff;
  1461. #ifdef UNICODE
  1462. *((LPUNADWORD)&szPtr[nPtr]) = lPtrlen; // <== @D05
  1463. nPtr += 4;
  1464. #else
  1465. *((LPUNAWORD)&szPtr[nPtr]) = wPtrlen; // <== @D05
  1466. nPtr += 2;
  1467. #endif
  1468. // Write file from key buffer
  1469. if(nPtr != _lwrite(hTblPtr, (BYTE *)szPtr, nPtr))
  1470. {
  1471. ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[1]);
  1472. return FALSE;
  1473. }
  1474. _lclose(hTblPtr);
  1475. }
  1476. return TRUE;
  1477. }
  1478. WORD GetPhrase(UINT iRadical, TCHAR *szPhrase)
  1479. {
  1480. LPPHRASEBUF Phrase;
  1481. WORD wLen=0;
  1482. UINT iAddr;
  1483. iAddr = lpRadical[iRadical].iFirst_Seg;
  1484. if(iAddr == NULL_SEG)
  1485. return 0;
  1486. Phrase=&lpPhrase[iAddr];
  1487. while(Phrase->iNext_Seg != NULL_SEG)
  1488. {
  1489. if((wLen+SEGMENT_SIZE) > MAX_CHAR_NUM )
  1490. {
  1491. CopyMemory(&szPhrase[wLen], Phrase->szPhrase, (MAX_CHAR_NUM-wLen) * cntChar);
  1492. wLen = MAX_CHAR_NUM;
  1493. szPhrase[wLen] = 0;
  1494. return wLen;
  1495. }
  1496. CopyMemory((char *)(szPhrase + wLen), Phrase->szPhrase, SEGMENT_SIZE * cntChar);
  1497. Phrase = &lpPhrase[Phrase->iNext_Seg];
  1498. wLen += SEGMENT_SIZE;
  1499. }
  1500. if((wLen+SEGMENT_SIZE) > MAX_CHAR_NUM )
  1501. {
  1502. CopyMemory(szPhrase + wLen, Phrase->szPhrase, (MAX_CHAR_NUM-wLen) * cntChar);
  1503. wLen = MAX_CHAR_NUM;
  1504. }
  1505. else
  1506. {
  1507. CopyMemory(szPhrase + wLen, Phrase->szPhrase, SEGMENT_SIZE * cntChar);
  1508. wLen += SEGMENT_SIZE;
  1509. }
  1510. szPhrase[wLen] = 0;
  1511. wLen = (WORD)lstrlen(szPhrase);
  1512. return wLen;
  1513. }
  1514. BOOL Parse(TCHAR *szStr, UINT len)
  1515. {
  1516. UINT i,j,k;
  1517. TCHAR szRadical[MAX_RADICAL];
  1518. // Skip blank
  1519. for(i=0; (i<len) && (szStr[i] == _TEXT(' ') || szStr[i] == _TEXT('\t')); i++) ;
  1520. if(i == len)
  1521. return TRUE;
  1522. j = len - 1;
  1523. while(szStr[j] == _TEXT(' ') || szStr[j] == _TEXT('\t'))
  1524. {
  1525. j --;
  1526. len --;
  1527. }
  1528. // Check Command Code 9/29/97 change logic
  1529. if(szStr[i] == _TEXT('/'))
  1530. {
  1531. // Check Radical Command
  1532. switch (szStr[i+1])
  1533. {
  1534. // Symbol
  1535. case _TEXT('s'):
  1536. case _TEXT('S'):
  1537. for(j=i+2; (j<len) && (szStr[j] == _TEXT(' ') || szStr[j] == _TEXT('\t')); j++) ;
  1538. if(j >= len)
  1539. return TRUE;
  1540. for(i=j+1; i<len; i++)
  1541. {
  1542. if(!PutRadical(szStr[j]++, *((LPUNAWORD)(&szStr[i])))) // <== @D05
  1543. return TRUE;
  1544. #ifndef UNICODE
  1545. i++;
  1546. #endif
  1547. }
  1548. break;
  1549. // Interpret '/' literally
  1550. case _TEXT('/'):
  1551. i++;
  1552. goto GET_RADICAL;
  1553. // Reserve for future use
  1554. default:
  1555. return TRUE;
  1556. }
  1557. }
  1558. else
  1559. {
  1560. GET_RADICAL:
  1561. // Get Radical
  1562. MyFillMemory(szRadical, MAX_RADICAL, _TEXT(' '));
  1563. k=0;
  1564. for(j=i; (j<len) && (k<MAX_RADICAL) && ((szStr[j] != _TEXT(' ')) && (szStr[j] != _TEXT('\t'))); j++)
  1565. {
  1566. // Make Uppercase
  1567. if((szStr[j] >= _TEXT('a')) && (szStr[j] <= _TEXT('z')))
  1568. szStr[j] -= ('a'-'A');
  1569. szRadical[k++] = szStr[j];
  1570. }
  1571. if(j == len)
  1572. return TRUE;
  1573. if(k==MAX_RADICAL)
  1574. {
  1575. // Skip radical of over length
  1576. for(i=j; (j<len) && (szStr[j] != _TEXT(' ')); j++) ;
  1577. if(i == len)
  1578. return TRUE;
  1579. j=i;
  1580. }
  1581. // Skip blank
  1582. for(i=j; (i<len) && (szStr[i] == _TEXT(' ') || szStr[i] == _TEXT('\t')); i++) ;
  1583. if(i == len)
  1584. return TRUE;
  1585. if(!PutPhrase(szRadical, &szStr[i], len-i))
  1586. return FALSE;
  1587. }
  1588. return TRUE;
  1589. }
  1590. UINT SearchMem(BYTE *szSrc, UINT nSrc, BYTE *szTag, UINT nTar)
  1591. {
  1592. UINT i,j;
  1593. for(i = 0; i < nTar; i ++)
  1594. {
  1595. for(j = 0; j < nSrc; j ++)
  1596. if(szSrc[j] != szTag[i+j])
  1597. break;
  1598. if(j == nSrc)
  1599. return(i);
  1600. }
  1601. return(0);
  1602. }
  1603. BOOL PutRadical(TCHAR cRadical, WORD wChinese)
  1604. {
  1605. UINT iAddr;
  1606. // Make Uppercase
  1607. if((cRadical >= _TEXT('a')) && (cRadical <= _TEXT('z')))
  1608. cRadical -= ('a' - 'A');
  1609. // Check Radical
  1610. if((cRadical < 0x20) || (cRadical > 0x5f))
  1611. return FALSE;
  1612. // Check DBCS
  1613. if(!is_DBCS(wChinese))
  1614. {
  1615. ErrMsg(IDS_ERR_SBCS, 0);
  1616. return FALSE;
  1617. }
  1618. iAddr = cRadical - 0x20;
  1619. if(Valid.wChar2SeqTbl[iAddr] != 0)
  1620. return FALSE;
  1621. Valid.wChar2SeqTbl[iAddr] = (++Valid.nSeqCode);
  1622. Valid.wSeq2CompTbl[Valid.nSeqCode] = wChinese;
  1623. Valid.fChooseChar[iAddr/16] |= (1 << (iAddr % 16));
  1624. Valid.fCompChar[iAddr/16] |= (1 << (iAddr % 16));
  1625. return TRUE;
  1626. }
  1627. BOOL PutPhrase(TCHAR *szRadical, TCHAR *szPhrase, UINT len)
  1628. {
  1629. LPPHRASEBUF Phrase;
  1630. UINT iAddr,iRadical;
  1631. UINT iStart,i,j;
  1632. TCHAR szBuf[MAX_PATH];
  1633. UINT iBuflen;
  1634. #ifndef UNICODE // <== @E02
  1635. // Check DBCS
  1636. for(i = 0; i < len; i++)
  1637. {
  1638. if(szPhrase[i] == _TEXT(' '))
  1639. continue;
  1640. if(!is_DBCS(*((LPUNAWORD)(&szPhrase[i])))) // <== @D05
  1641. {
  1642. //ErrMsg(IDS_ERR_SBCS, 0);
  1643. TCHAR szErrStr[MAX_PATH];
  1644. TCHAR szStr1[MAX_PATH];
  1645. TCHAR szStr2[MAX_PATH];
  1646. LoadString(hInst, IDS_ERR_SBCS, szStr1, sizeof(szStr1) / sizeof(TCHAR));
  1647. StringCchPrintf(szErrStr, ARRAYSIZE(szErrStr), _TEXT("�� %d �� : "), idxLine + 1);
  1648. CopyMemory(szStr2, szPhrase, len * cntChar);
  1649. szStr2[len] = 0;
  1650. StringCchCat(szErrStr, ARRAYSIZE(szErrStr), szStr2);
  1651. StringCchCat(szErrStr, ARRAYSIZE(szErrStr), _TEXT("\n"));
  1652. StringCchCat(szErrStr, ARRAYSIZE(szErrStr), szStr1);
  1653. if (MessageBox(NULL, szErrStr, NULL, MB_OKCANCEL | MB_ICONEXCLAMATION | MB_SETFOREGROUND)
  1654. == IDCANCEL)
  1655. return FALSE;
  1656. else
  1657. return TRUE; // ������
  1658. }
  1659. i++;
  1660. }
  1661. #endif // <== @E02
  1662. // Search Radical buffer
  1663. for(i = 0; i < iRadicalBuff; i++)
  1664. {
  1665. for(j = 0; j < MAX_RADICAL; j++)
  1666. if(lpRadical[i].szRadical[j] != szRadical[j])
  1667. break;
  1668. if(j == MAX_RADICAL)
  1669. break;
  1670. }
  1671. // Allocate new buffer if New Radical
  1672. if(i == iRadicalBuff)
  1673. {
  1674. if(iRadicalBuff+1 == nRadicalBuffsize)
  1675. if(!AllocRadical())
  1676. return FALSE;
  1677. CopyMemory(lpRadical[i].szRadical, szRadical, MAX_RADICAL * cntChar);
  1678. iRadicalBuff++;
  1679. lpRadical[i].iFirst_Seg = NULL_SEG;
  1680. lpRadical[i].wCode = 0;
  1681. }
  1682. // Search Starting address in Phrase table
  1683. iRadical = i;
  1684. iAddr = lpRadical[i].iFirst_Seg;
  1685. if(iAddr != NULL_SEG)
  1686. {
  1687. Phrase = &lpPhrase[iAddr];
  1688. while(Phrase->iNext_Seg != NULL_SEG)
  1689. Phrase=&lpPhrase[Phrase->iNext_Seg];
  1690. for(i = 0; i < SEGMENT_SIZE; i++)
  1691. if(Phrase->szPhrase[i] == 0)
  1692. break;
  1693. iStart = i;
  1694. }
  1695. // Put Phrase
  1696. iBuflen = 0;
  1697. for(i = 0; i < len; i++)
  1698. {
  1699. if(szPhrase[i] != _TEXT(' ') && (szPhrase[i] != _TEXT('\t')))
  1700. {
  1701. szBuf[iBuflen++] = szPhrase[i];
  1702. if((i+1) != len)
  1703. continue;
  1704. }
  1705. if(iBuflen == 0)
  1706. continue;
  1707. #ifdef UNICODE
  1708. if((iBuflen == 1) && (lpRadical[iRadical].wCode == 0))
  1709. {
  1710. lpRadical[iRadical].wCode = szBuf[0];
  1711. }
  1712. else
  1713. {
  1714. #else
  1715. if((iBuflen == 2) && (lpRadical[iRadical].wCode == 0))
  1716. {
  1717. lpRadical[iRadical].wCode = (((WORD)szBuf[0])<< 8)+
  1718. (WORD)szBuf[1];
  1719. }
  1720. else
  1721. {
  1722. szBuf[iBuflen-2] &= 0x7f;
  1723. #endif
  1724. // if(lpRadical[iRadical].wCode == 0)
  1725. // return FALSE;
  1726. if(iAddr == NULL_SEG)
  1727. {
  1728. if(iPhraseBuff + 1 == nPhraseBuffsize)
  1729. if(!AllocPhrase())
  1730. return FALSE;
  1731. lpRadical[iRadical].iFirst_Seg=iPhraseBuff;
  1732. iAddr=iPhraseBuff;
  1733. Phrase=&lpPhrase[iAddr];
  1734. ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
  1735. Phrase->iNext_Seg=NULL_SEG;
  1736. iPhraseBuff++;
  1737. iStart=0;
  1738. }
  1739. #ifdef UNICODE
  1740. for(j = 0; j < iBuflen; j ++)
  1741. #else
  1742. for(j = 0; j < iBuflen; j += 2)
  1743. #endif
  1744. {
  1745. if(iStart == SEGMENT_SIZE)
  1746. {
  1747. if(iPhraseBuff + 1 == nPhraseBuffsize)
  1748. if(!AllocPhrase())
  1749. return FALSE;
  1750. Phrase=&lpPhrase[iAddr];
  1751. while (Phrase->iNext_Seg != NULL_SEG)
  1752. Phrase=&lpPhrase[Phrase->iNext_Seg];
  1753. Phrase->iNext_Seg=iPhraseBuff;
  1754. Phrase=&lpPhrase[iPhraseBuff];
  1755. ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
  1756. Phrase->iNext_Seg=NULL_SEG;
  1757. iPhraseBuff++;
  1758. iStart=0;
  1759. }
  1760. #ifdef UNICODE
  1761. *((LPUNAWORD)&Phrase->szPhrase[iStart ++]) = szBuf[j]; // <== @D05
  1762. #else
  1763. *((LPUNAWORD)&Phrase->szPhrase[iStart])= // <== @D05
  1764. (((WORD)szBuf[j])<< 8)+ (WORD)szBuf[j+1];
  1765. iStart += 2;
  1766. #endif
  1767. }
  1768. #ifdef UNICODE
  1769. if(iStart == SEGMENT_SIZE)
  1770. {
  1771. if(iPhraseBuff + 1 == nPhraseBuffsize)
  1772. if(!AllocPhrase())
  1773. return FALSE;
  1774. Phrase=&lpPhrase[iAddr];
  1775. while (Phrase->iNext_Seg != NULL_SEG)
  1776. Phrase=&lpPhrase[Phrase->iNext_Seg];
  1777. Phrase->iNext_Seg=iPhraseBuff;
  1778. Phrase=&lpPhrase[iPhraseBuff];
  1779. ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
  1780. Phrase->iNext_Seg=NULL_SEG;
  1781. iPhraseBuff++;
  1782. iStart=0;
  1783. }
  1784. *((LPUNAWORD)&Phrase->szPhrase[iStart ++]) = 1; // <== @D05
  1785. #endif
  1786. }
  1787. iBuflen=0;
  1788. }
  1789. return TRUE;
  1790. }
  1791. BOOL AllocRadical()
  1792. {
  1793. HANDLE hTemp;
  1794. nRadicalBuffsize += ALLOCBLOCK;
  1795. GlobalUnlock(hRadical);
  1796. hTemp= GlobalReAlloc(hRadical, nRadicalBuffsize * sizeof(RADICALBUF),
  1797. GMEM_MOVEABLE);
  1798. if(hTemp == NULL)
  1799. {
  1800. nRadicalBuffsize -= ALLOCBLOCK;
  1801. ErrMsg(IDS_ERR_MEMORY, 0);
  1802. return FALSE;
  1803. }
  1804. hRadical=hTemp;
  1805. lpRadical=(LPRADICALBUF)GlobalLock(hRadical);
  1806. if(lpRadical == NULL)
  1807. {
  1808. nRadicalBuffsize -= ALLOCBLOCK;
  1809. ErrMsg(IDS_ERR_MEMORY, 0);
  1810. return FALSE;
  1811. }
  1812. return TRUE;
  1813. }
  1814. BOOL AllocPhrase()
  1815. {
  1816. HANDLE hTemp;
  1817. nPhraseBuffsize += ALLOCBLOCK;
  1818. GlobalUnlock(hPhrase);
  1819. hTemp= GlobalReAlloc(hPhrase, nPhraseBuffsize * sizeof(PHRASEBUF),
  1820. GMEM_MOVEABLE);
  1821. if(hTemp == NULL)
  1822. {
  1823. nPhraseBuffsize -= ALLOCBLOCK;
  1824. ErrMsg(IDS_ERR_MEMORY, 0);
  1825. return FALSE;
  1826. }
  1827. hPhrase=hTemp;
  1828. lpPhrase=(LPPHRASEBUF)GlobalLock(hPhrase);
  1829. if(lpPhrase == NULL)
  1830. {
  1831. nPhraseBuffsize -= ALLOCBLOCK;
  1832. ErrMsg(IDS_ERR_MEMORY, 0);
  1833. return FALSE;
  1834. }
  1835. return TRUE;
  1836. }
  1837. BOOL is_DBCS(UINT wWord)
  1838. {
  1839. #ifdef UNICODE
  1840. if(wWord < 0x0080)
  1841. return FALSE;
  1842. #else
  1843. if((LOBYTE(wWord) < 0x81) || (LOBYTE(wWord) > 0xFE))
  1844. return FALSE;
  1845. if((HIBYTE(wWord) < 0x40) || (HIBYTE(wWord) > 0xFE))
  1846. return FALSE;
  1847. #endif
  1848. return TRUE;
  1849. }
  1850. void ErrMsg(UINT iMsgID, UINT iTitle)
  1851. {
  1852. TCHAR szErrStr[MAX_PATH];
  1853. TCHAR szTitle[MAX_PATH];
  1854. HideProgress(); // <== @E01
  1855. LoadString(hInst, iTitle, szTitle, sizeof(szTitle) / sizeof(TCHAR));
  1856. LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
  1857. MessageBox(NULL, szErrStr, (iTitle) ? szTitle : NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TASKMODAL);
  1858. ShowProgress();// <== @E01
  1859. }
  1860. void ErrIOMsg(UINT iMsgID, TCHAR *szFileName)
  1861. {
  1862. TCHAR szErrStr[MAX_PATH];
  1863. TCHAR szShowMsg[MAX_PATH];
  1864. HideProgress();// <== @E01
  1865. LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
  1866. wsprintf(szShowMsg, szErrStr, szFileName);
  1867. MessageBox(NULL, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TASKMODAL);
  1868. ShowProgress();// <== @E01
  1869. }
  1870. void MyFillMemory(TCHAR *dst, DWORD cnt, TCHAR v)
  1871. {
  1872. #ifdef UNICODE
  1873. DWORD i;
  1874. for(i = 0; i < cnt; i ++)
  1875. dst[i] = v;
  1876. #else
  1877. FillMemory(dst, cnt, v);
  1878. #endif
  1879. }