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.

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