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.

1859 lines
56 KiB

  1. /*************************************************
  2. * lcfile.c *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. //
  8. // Change Log:
  9. //
  10. // @C001 - Use _make\splitpath insteading of _wmake\splitpath
  11. // @C002 - Untest Chinese in assoc phrases
  12. // @C003 - Create tbl files always so phrases can be activated immediately
  13. //
  14. //
  15. // 1/27/96
  16. // @C004 Fix bug of error writing registy database
  17. #include <windows.h> // required for all Windows applications
  18. #include <windowsx.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <shlobj.h>
  22. #include "rc.h"
  23. #include "lctool.h"
  24. #define END_PHRASE 0x8000
  25. #define NOT_END_PHRASE 0x7fff
  26. #ifdef UNICODE
  27. #define PTRRECLEN 3 // Pointer file record length
  28. #else
  29. #define PTRRECLEN 4 // Pointer file record length
  30. #endif
  31. #define LCPTRFILE "LCPTR.TBL"
  32. #define LCPHRASEFILE "LCPHRASE.TBL"
  33. #define LCPHRASENOEXT "LCPHRASE"
  34. extern HWND subhWnd;
  35. // Local function prototypes.
  36. #ifdef UNICODE
  37. TCHAR g_szLCPhraseName[MAX_PATH];
  38. TCHAR g_szLCPtrName[MAX_PATH];
  39. TCHAR g_szLCUserPath[MAX_PATH];
  40. BOOL lcAddPhrase( TCHAR *, TCHAR *, UINT *, DWORD, DWORD, DWORD);
  41. BOOL lcFOpen( HWND hWnd)
  42. {
  43. HANDLE hLCPtr,hLCPhrase;
  44. HFILE hfLCPtr,hfLCPhrase;
  45. DWORD flen_Ptr,flen_Phrase;
  46. TCHAR szLCPtrName[MAX_PATH];
  47. TCHAR szLCPhraseName[MAX_PATH];
  48. TCHAR *szLCPtrBuf,*szLCPhraseBuf;
  49. UCHAR szTmp[MAX_PATH];
  50. BOOL rc;
  51. UINT i;
  52. DWORD lStart,lEnd;
  53. TCHAR szDispBuf[MAX_CHAR_NUM];
  54. UINT nDisp,len;
  55. HKEY hkey;
  56. LONG lResult;
  57. LONG lcount, lType;
  58. // Get the path for User Dictionary.
  59. SHGetSpecialFolderPath(NULL, g_szLCUserPath, CSIDL_APPDATA , FALSE);
  60. if ( g_szLCUserPath[lstrlen(g_szLCUserPath) - 1] == TEXT('\\') )
  61. g_szLCUserPath[lstrlen(g_szLCUserPath) - 1] = TEXT('\0');
  62. lstrcat(g_szLCUserPath, TEXT("\\Microsoft") );
  63. if ( GetFileAttributes(g_szLCUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  64. CreateDirectory(g_szLCUserPath, NULL);
  65. lstrcat(g_szLCUserPath, TEXT("\\LCTOOL") );
  66. if ( GetFileAttributes(g_szLCUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  67. CreateDirectory(g_szLCUserPath, NULL);
  68. // Get Current User Dictionary
  69. lResult = RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Input Method", 0,
  70. KEY_ALL_ACCESS, &hkey) ;
  71. if (lResult == ERROR_SUCCESS) {
  72. lcount = 2 * MAX_PATH;
  73. lType = REG_SZ;
  74. lResult = RegQueryValueEx(hkey, L"Phrase Prediction Dictionary",0,
  75. &lType, (LPBYTE)szLCPhraseName, &lcount);
  76. if (lResult == ERROR_SUCCESS) {
  77. lcount = 2 * MAX_PATH;
  78. lType = REG_SZ;
  79. lResult = RegQueryValueEx(hkey, L"Phrase Prediction Pointer",0,
  80. &lType, (LPBYTE)szLCPtrName, &lcount);
  81. }
  82. }
  83. if (lResult != ERROR_SUCCESS) {
  84. // Get system directory
  85. len = GetSystemDirectory(szLCPtrName, sizeof(szLCPtrName));
  86. if (szLCPtrName[len - 1] !=_TEXT('\\')) { // consider C:\ ;
  87. szLCPtrName[len++] =_TEXT('\\');
  88. szLCPtrName[len] = 0;
  89. }
  90. lstrcpy(szLCPhraseName, szLCPtrName);
  91. lstrcat(szLCPtrName,_TEXT(LCPTRFILE));
  92. lstrcat(szLCPhraseName,_TEXT(LCPHRASEFILE));
  93. }
  94. // Open LC pointer file
  95. WideCharToMultiByte(CP_ACP,0,szLCPtrName,-1,szTmp,MAX_PATH,NULL,0);
  96. hfLCPtr=_lopen(szTmp,OF_READ);
  97. if(hfLCPtr == -1){
  98. lcErrIOMsg(IDS_ERR_FILEOPEN, LCPTRFILE);
  99. return FALSE;
  100. }
  101. WideCharToMultiByte(CP_ACP,0,szLCPhraseName,-1,szTmp,MAX_PATH,NULL,0);
  102. hfLCPhrase=_lopen(szTmp,OF_READ);
  103. // Open LC phrase file
  104. if(hfLCPhrase == -1){
  105. _lclose(hfLCPtr);
  106. lcErrIOMsg(IDS_ERR_FILEOPEN, LCPTRFILE);
  107. return FALSE;
  108. }
  109. lstrcpy(g_szLCPhraseName, szLCPhraseName);
  110. lstrcpy(g_szLCPtrName, szLCPtrName);
  111. // get file length
  112. flen_Ptr=_llseek(hfLCPtr,0L,2); /* get file length */
  113. // Allocate Memory
  114. hLCPtr = GlobalAlloc(GMEM_FIXED, flen_Ptr);
  115. if(!hLCPtr) {
  116. lcErrMsg(IDS_ERR_MEMORY);
  117. goto error;
  118. }
  119. szLCPtrBuf = GlobalLock(hLCPtr);
  120. _llseek(hfLCPtr,0L,0); //set to beginning 4
  121. if(flen_Ptr != _lread(hfLCPtr,szLCPtrBuf,flen_Ptr)) {
  122. lcErrIOMsg(IDS_ERR_FILEREAD, LCPTRFILE);
  123. goto error;
  124. }
  125. _lclose(hfLCPtr);
  126. //get file length
  127. flen_Phrase=_llseek(hfLCPhrase,0L,2); /* get file length */
  128. // Allocate Memory
  129. hLCPhrase = GlobalAlloc(GMEM_MOVEABLE, flen_Phrase);
  130. if(!hLCPhrase) {
  131. lcErrMsg(IDS_ERR_MEMORY);
  132. goto error;
  133. }
  134. szLCPhraseBuf = GlobalLock(hLCPhrase);
  135. _llseek(hfLCPhrase,0L,0); //set to beginning
  136. if(flen_Phrase != _lread(hfLCPhrase,szLCPhraseBuf,flen_Phrase)) {
  137. lcErrIOMsg(IDS_ERR_FILEREAD, LCPHRASEFILE);
  138. goto error;
  139. }
  140. _lclose(hfLCPhrase);
  141. rc=TRUE;
  142. // Convert file to structured memory (WORDBUF & PHRASEBUF)
  143. // First record is Null record skip it
  144. for(i=1; i<((flen_Ptr/PTRRECLEN)>>1)-1; i++) {
  145. // If Allocated Word buffer not enough Reallocate it
  146. if(lWordBuff+1 == nWordBuffsize)
  147. if(!(rc=lcAllocWord())) break;
  148. lpWord[lWordBuff].wWord=szLCPtrBuf[i*PTRRECLEN];
  149. // If Allocated Phrase buffer not enough Reallocate it
  150. if(lPhraseBuff+1 == nPhraseBuffsize)
  151. if(!(rc=lcAllocPhrase())) break;
  152. lpWord[lWordBuff].lFirst_Seg=lPhraseBuff;
  153. lpPhrase[lPhraseBuff].lNext_Seg=NULL_SEG;
  154. lWordBuff++;
  155. lPhraseBuff++;
  156. nDisp=0;
  157. // Add Phrase to Display buffer
  158. lStart=*((LPUNADWORD)&szLCPtrBuf[i*PTRRECLEN+1]);
  159. lEnd=*((LPUNADWORD)&szLCPtrBuf[i*PTRRECLEN+PTRRECLEN+1]);
  160. if(lStart <= lEnd) {
  161. rc=lcAddPhrase(szLCPhraseBuf, szDispBuf, &nDisp,
  162. lStart, lEnd, flen_Phrase>>1);
  163. if(!rc) break;
  164. }
  165. // Put display buffer into Phrase buffer
  166. if(nDisp == 0) szDispBuf[0]=0;
  167. else szDispBuf[nDisp-1]=0;
  168. if(!(rc=lcDisp2Mem(lWordBuff-1, szDispBuf))) break;
  169. }
  170. GlobalUnlock(hLCPtr);
  171. GlobalUnlock(hLCPhrase);
  172. GlobalFree(hLCPtr);
  173. GlobalFree(hLCPhrase);
  174. return rc;
  175. error:
  176. _lclose(hfLCPtr);
  177. _lclose(hfLCPhrase);
  178. GlobalUnlock(hLCPtr);
  179. GlobalUnlock(hLCPhrase);
  180. GlobalFree(hLCPtr);
  181. GlobalFree(hLCPhrase);
  182. return FALSE;
  183. }
  184. BOOL lcAddPhrase(
  185. TCHAR *szLCWord, // LC Phrase buffer
  186. TCHAR *szDispBuf, // Display buffer
  187. UINT *nDisp, // Display buffer length
  188. DWORD lStart, // Start address of LC Phrase
  189. DWORD lEnd, // End address of LC Phrase
  190. DWORD lLen) // Total Length of LC Phrase
  191. {
  192. DWORD i,j;
  193. // Check length
  194. if(lLen < lStart) {
  195. lcErrMsg(IDS_ERR_LCPTRFILE);
  196. return FALSE;
  197. }
  198. j=(lLen < lEnd) ? lLen:lEnd;
  199. for(i=lStart; i < j; i++) {
  200. szDispBuf[(*nDisp)++]=szLCWord[i] ? szLCWord[i]:_TEXT(' ');
  201. if( ((*nDisp)+1) >= MAX_CHAR_NUM) {
  202. szDispBuf[(*nDisp)++]=0;
  203. lcErrMsg(IDS_ERR_OVERMAX);
  204. return FALSE;
  205. }
  206. }
  207. szDispBuf[(*nDisp)++]=0;
  208. return TRUE;
  209. }
  210. // @C001
  211. static void local_splitpath(TCHAR *szFilePath, TCHAR *szDriveBuf, TCHAR *szDirBuf, TCHAR *szFNameBuf, TCHAR *szExtBuf)
  212. {
  213. static UCHAR u_szFilePath[MAX_PATH];
  214. static UCHAR u_szDirBuf[_MAX_DIR];
  215. static UCHAR u_szDriveBuf[_MAX_DRIVE];
  216. static UCHAR u_szFNameBuf[_MAX_FNAME];
  217. static UCHAR u_szExtBuf[_MAX_EXT];
  218. WideCharToMultiByte(CP_ACP, 0, szFilePath, -1, u_szFilePath, MAX_PATH, NULL,0);
  219. _splitpath(u_szFilePath, u_szDriveBuf, u_szDirBuf, u_szFNameBuf, u_szExtBuf);
  220. MultiByteToWideChar(CP_ACP, 0, u_szDriveBuf, -1, szDriveBuf, _MAX_DRIVE);
  221. MultiByteToWideChar(CP_ACP, 0, u_szDirBuf, -1, szDirBuf, _MAX_DIR);
  222. MultiByteToWideChar(CP_ACP, 0, u_szFNameBuf, -1, szFNameBuf, _MAX_FNAME);
  223. MultiByteToWideChar(CP_ACP, 0, u_szExtBuf, -1, szExtBuf, _MAX_EXT);
  224. }
  225. // @C001
  226. static void local_makepath(TCHAR *szFilePath, TCHAR *szDriveBuf, TCHAR *szDirBuf, TCHAR *szFNameBuf, TCHAR *szExtBuf)
  227. {
  228. static UCHAR u_szFilePath[MAX_PATH];
  229. static UCHAR u_szDirBuf[_MAX_DIR];
  230. static UCHAR u_szDriveBuf[_MAX_DRIVE];
  231. static UCHAR u_szFNameBuf[_MAX_FNAME];
  232. static UCHAR u_szExtBuf[_MAX_EXT];
  233. WideCharToMultiByte(CP_ACP, 0, szDriveBuf, -1, u_szDriveBuf, _MAX_DRIVE, NULL,0);
  234. WideCharToMultiByte(CP_ACP, 0, szDirBuf, -1, u_szDirBuf, _MAX_DIR, NULL,0);
  235. WideCharToMultiByte(CP_ACP, 0, szFNameBuf, -1, u_szFNameBuf, _MAX_FNAME, NULL,0);
  236. WideCharToMultiByte(CP_ACP, 0, szExtBuf, -1, u_szExtBuf, _MAX_EXT, NULL,0);
  237. _makepath(u_szFilePath, u_szDriveBuf, u_szDirBuf, u_szFNameBuf, u_szExtBuf);
  238. MultiByteToWideChar(CP_ACP, 0, u_szFilePath, -1, szFilePath, MAX_PATH);
  239. }
  240. BOOL lcFSave(
  241. HWND hwnd, BOOL bSaveAs)
  242. {
  243. HANDLE hLCPtr, hLCPhrase;
  244. HFILE hfLCPtr,hfLCPhrase;
  245. TCHAR szLCSystemName[MAX_PATH];
  246. TCHAR szLCPtrName[MAX_PATH];
  247. TCHAR szLCPhraseName[MAX_PATH];
  248. TCHAR szLCPtrBuf[PTRRECLEN],szLCPhraseBuf[MAX_CHAR_NUM];
  249. UINT i,j;
  250. DWORD lStartPhrase;
  251. DWORD lPhraseLen;
  252. UINT len;
  253. UCHAR szUStr[MAX_CHAR_NUM],*pUStr;
  254. OPENFILENAME ofn;
  255. TCHAR szFileOpen[25];
  256. TCHAR szCustFilter[40];
  257. TCHAR szFileName[MAX_PATH];
  258. TCHAR szFilePath[MAX_PATH];
  259. TCHAR szDirBuf[_MAX_DIR];
  260. TCHAR szDriveBuf[_MAX_DRIVE];
  261. TCHAR szFNameBuf[_MAX_FNAME];
  262. TCHAR szExtBuf[_MAX_EXT];
  263. TCHAR szFilterSpec[MAX_PATH];
  264. TCHAR szExt[10];
  265. if(!lcSort(hwnd))
  266. return FALSE;
  267. if(wSameCode)
  268. return FALSE;
  269. DOSAVE:
  270. // Get system directory
  271. len = GetSystemDirectory(szLCSystemName, sizeof(szLCSystemName));
  272. if (szLCSystemName[len - 1] != _TEXT('\\')) { // consider C:\ ;
  273. szLCSystemName[len++] = _TEXT('\\');
  274. szLCSystemName[len] = 0;
  275. }
  276. if (bSaveAs) {
  277. LoadString (hInst, IDS_DICTFILTERSPEC, szFilterSpec, sizeof(szFilterSpec)/sizeof(TCHAR));
  278. LoadString (hInst, IDS_DICTDEFAULTFILEEXT, szExt, sizeof(szExt)/sizeof(TCHAR));
  279. szFilterSpec[lstrlen(szFilterSpec) + 2] = 0;
  280. szFileName[0]=0;
  281. LoadString (hInst, IDS_SAVETABLE, szFileOpen, sizeof(szFileOpen)/sizeof(TCHAR) );
  282. szCustFilter[0]=0;
  283. lstrcpy(&szCustFilter[1], szExt);
  284. szCustFilter[lstrlen(szExt) + 2] = 0;
  285. local_splitpath(g_szLCPhraseName, szDriveBuf, szDirBuf, szFNameBuf, szExtBuf); // @C001
  286. if (lstrcmpi(szFNameBuf, _TEXT(LCPHRASENOEXT)) == 0) {
  287. lstrcpy(szFilePath, szExt);
  288. } else {
  289. lstrcpy(szFilePath, szFNameBuf);
  290. lstrcat(szFilePath, szExtBuf);
  291. }
  292. /* fill in non-variant fields of OPENFILENAME struct. */
  293. ofn.lStructSize = sizeof(OPENFILENAME);
  294. ofn.hwndOwner = NULL;
  295. ofn.lpstrFilter = szFilterSpec;
  296. ofn.lpstrCustomFilter = szCustFilter;
  297. ofn.nMaxCustFilter = sizeof(szCustFilter);
  298. ofn.nFilterIndex = 1;
  299. ofn.lpstrFile = szFilePath;
  300. ofn.nMaxFile = MAX_PATH;
  301. ofn.lpstrInitialDir = g_szLCUserPath;
  302. ofn.lpstrFileTitle = szFileName;
  303. ofn.nMaxFileTitle = MAX_PATH;
  304. ofn.lpstrTitle = szFileOpen;
  305. ofn.lpstrDefExt = szExt+2;
  306. ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  307. if(!GetSaveFileName ((LPOPENFILENAME)&ofn))
  308. return FALSE;
  309. lstrcat(szLCSystemName, _TEXT(LCPHRASEFILE));
  310. lstrcpy(szLCPhraseName, szFilePath);
  311. if (lstrcmpi(szLCPhraseName, szLCSystemName) == 0) {
  312. lcErrMsg(IDS_ERR_SAVESYSTEMTBL);
  313. return FALSE;
  314. }
  315. local_splitpath(szFilePath, szDriveBuf, szDirBuf, szFNameBuf, szExtBuf); // @C001
  316. len=lstrlen(szFNameBuf);
  317. if(len > 5)
  318. len=5;
  319. szFNameBuf[len]=0;
  320. lstrcat(szFNameBuf, _TEXT("PTR"));
  321. local_makepath(szLCPtrName, szDriveBuf, szDirBuf, szFNameBuf, _TEXT(".TBL")); // @C001
  322. if (lstrcmpi(szLCPtrName, szLCPhraseName) == 0) {
  323. local_makepath(szLCPtrName, szDriveBuf, szDirBuf, szFNameBuf, _TEXT(".TB1")); // @C001
  324. }
  325. } else {
  326. lstrcpy(szLCPhraseName, g_szLCPhraseName);
  327. lstrcpy(szLCPtrName, g_szLCPtrName);
  328. lstrcat(szLCSystemName, _TEXT(LCPHRASEFILE));
  329. if (lstrcmpi(szLCPhraseName, szLCSystemName) == 0) {
  330. bSaveAs = TRUE;
  331. goto DOSAVE;
  332. }
  333. }
  334. // Open LC phrase file
  335. hLCPhrase = CreateFile(szLCPhraseName,
  336. GENERIC_READ | GENERIC_WRITE,
  337. FILE_SHARE_READ,
  338. NULL,
  339. OPEN_ALWAYS,
  340. FILE_ATTRIBUTE_NORMAL, // @C003
  341. NULL ) ;
  342. if(hLCPhrase == INVALID_HANDLE_VALUE) {
  343. lcErrMsg(IDS_ERR_FILESAVE);
  344. goto error;
  345. }
  346. hfLCPhrase = PtrToInt( hLCPhrase );
  347. // Open LC pointer file
  348. hLCPtr = CreateFile(szLCPtrName,
  349. GENERIC_READ | GENERIC_WRITE,
  350. FILE_SHARE_READ,
  351. NULL,
  352. OPEN_ALWAYS,
  353. FILE_ATTRIBUTE_NORMAL, // @C003
  354. NULL ) ;
  355. if(hLCPtr == INVALID_HANDLE_VALUE) {
  356. lcErrMsg(IDS_ERR_FILESAVE);
  357. goto error;
  358. }
  359. hfLCPtr = PtrToInt( hLCPtr );
  360. // Copy into global variable
  361. lstrcpy(g_szLCPhraseName, szLCPhraseName);
  362. lstrcpy(g_szLCPtrName, szLCPtrName);
  363. // Write a Null record into first record
  364. memset(szUStr,0,PTRRECLEN*2);
  365. if((PTRRECLEN*2) != _lwrite(hfLCPtr,szUStr,PTRRECLEN*2)) {
  366. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  367. goto error;
  368. }
  369. lStartPhrase=0;
  370. // initialize szLCPtrBuf and szLCPhraseBuf
  371. for ( i=0; i< PTRRECLEN; i++)
  372. szLCPtrBuf[i] = TEXT('\0');
  373. for ( i=0; i<MAX_CHAR_NUM; i++)
  374. szLCPhraseBuf[i] = TEXT('\0');
  375. for(i=0; i<lWordBuff; i++) {
  376. lPhraseLen=0;
  377. // Truncate same Word
  378. if(lpWord[i].wWord == *(szLCPtrBuf))
  379. continue;
  380. lPhraseLen=lcMem2Disp(i, szLCPhraseBuf);
  381. len=lPhraseLen << 1 ;
  382. for(j=0;j<lPhraseLen;j++) if(szLCPhraseBuf[j]==_TEXT(' ')) szLCPhraseBuf[j]=0;
  383. // Check register phrase over max length
  384. if(lStartPhrase > (0x0ffffffd-len)) {
  385. lcErrMsg(IDS_ERR_OVER_MAXLEN);
  386. goto error;
  387. }
  388. szLCPtrBuf[0]=lpWord[i].wWord;
  389. *((LPUNADWORD)&szLCPtrBuf[1])=lStartPhrase;
  390. pUStr=(UCHAR*)szLCPtrBuf;
  391. if(PTRRECLEN*2 != _lwrite(hfLCPtr,pUStr,PTRRECLEN*2)) {
  392. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  393. goto error;
  394. }
  395. if(lPhraseLen){
  396. pUStr=(UCHAR*)szLCPhraseBuf;
  397. if(len !=_lwrite(hfLCPhrase,pUStr,len)) {
  398. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPHRASEFILE);
  399. goto error;
  400. }
  401. }
  402. lStartPhrase+=lPhraseLen;
  403. }
  404. // Write the lasr record
  405. szLCPtrBuf[0]=0xffff;
  406. *((LPUNADWORD)&szLCPtrBuf[1])=lStartPhrase;
  407. pUStr=(UCHAR*)szLCPtrBuf;
  408. if(PTRRECLEN*2 != _lwrite(hfLCPtr,pUStr,PTRRECLEN*2)) {
  409. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  410. goto error;
  411. }
  412. SetEndOfFile(hLCPtr);
  413. SetEndOfFile(hLCPhrase);
  414. _lclose(hfLCPtr);
  415. _lclose(hfLCPhrase);
  416. bSaveFile=FALSE;
  417. {
  418. HKEY hkey;
  419. DWORD dwDisposition;
  420. LONG lResult;
  421. lResult= RegCreateKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Input Method", 0,
  422. L"Application Per-User Data", REG_OPTION_NON_VOLATILE,
  423. KEY_ALL_ACCESS,
  424. NULL, &hkey, &dwDisposition) ;
  425. lResult = RegSetValueEx(hkey, L"Phrase Prediction Dictionary",0,
  426. REG_SZ, (BYTE *)szLCPhraseName, 2 * (lstrlen(szLCPhraseName) + 1)); // <== @C004
  427. lResult = RegSetValueEx(hkey, L"Phrase Prediction Pointer",0,
  428. REG_SZ, (BYTE *)szLCPtrName, 2 * (lstrlen(szLCPtrName) + 1)); // <== @C004
  429. }
  430. return TRUE;
  431. error:
  432. _lclose(hfLCPtr);
  433. _lclose(hfLCPhrase);
  434. return FALSE;
  435. }
  436. BOOL lcInsline(
  437. TCHAR *szStr,
  438. UINT iWord,
  439. UINT len,
  440. BOOL *bOver)
  441. {
  442. WORD wWord;
  443. UINT iFree,nDisp;
  444. UINT i,j,buflen;
  445. TCHAR szDispBuf[MAX_CHAR_NUM];
  446. TCHAR szBuffer[MAX_CHAR_NUM*2];
  447. unsigned long l;
  448. szStr[len]=0; // Append Null to end of line
  449. // Skip lead spaces if exist
  450. for(i=0; (i<len) && (szStr[i] ==_TEXT(' ')); i++);
  451. if( ((i+1) >= len) || (szStr[i+1] !=_TEXT(' ')) ) {
  452. lcErrMsg(IDS_ERR_IMP_SEPRATOR);
  453. return FALSE;
  454. }
  455. if(!is_DBCS2(*((WORD *)(&szStr[i])), TRUE)) {
  456. return FALSE;
  457. }
  458. wWord=szStr[i];
  459. // Skip spaces after Word
  460. for(j=i+1; (j<len) && (szStr[j] ==_TEXT(' ')); j++);
  461. if(j == len) {
  462. lcErrMsg(IDS_ERR_IMP_NOPHRASE);
  463. return FALSE;
  464. }
  465. lstrcpy(szDispBuf, &szStr[j]);
  466. nDisp=lstrlen(szDispBuf)+1;
  467. #ifndef UNICODE // @C002
  468. // Check DBCS
  469. for(i=0; i<(nDisp-1); i++) {
  470. if(szDispBuf[i] ==_TEXT(' '))
  471. continue;
  472. if(!is_DBCS2(szDispBuf[i], TRUE)) {
  473. return FALSE;
  474. }
  475. i++;
  476. }
  477. #endif // @C002
  478. // Check same Word
  479. for(i=0; i<lWordBuff; i++) {
  480. if(lpWord[i].wWord==wWord) {
  481. buflen=lcMem2Disp(i, szBuffer);
  482. if((buflen + lstrlen(szDispBuf)) >= MAX_CHAR_NUM)
  483. *bOver=TRUE;
  484. lstrcat(szBuffer, szDispBuf);
  485. return(lcDisp2Mem(i, szBuffer));
  486. }
  487. }
  488. // Check Word buffer enough ?
  489. if(lWordBuff+1 == nWordBuffsize)
  490. if(!lcAllocWord())
  491. return FALSE;
  492. // Allocate a Phrase Buffer
  493. iFree=lcGetSeg();
  494. if(iFree == NULL_SEG)
  495. return FALSE;
  496. if(lWordBuff == 0) {
  497. lpWord[iWord].wWord=wWord;
  498. lpWord[iWord].lFirst_Seg=iFree;
  499. } else {
  500. for(l=lWordBuff; l >= iWord; l--) {
  501. lpWord[l+1].wWord=lpWord[l].wWord;
  502. lpWord[l+1].lFirst_Seg=lpWord[l].lFirst_Seg;
  503. }
  504. lpWord[iWord].wWord=wWord;
  505. lpWord[iWord].lFirst_Seg=iFree;
  506. }
  507. lWordBuff++;
  508. if(!lcDisp2Mem(iWord, szDispBuf))
  509. return FALSE;
  510. return TRUE;
  511. }
  512. BOOL lcAppend(
  513. HWND hwnd)
  514. {
  515. OPENFILENAME ofn;
  516. TCHAR szFileOpen[25];
  517. TCHAR szCustFilter[10];
  518. TCHAR szFileName[MAX_PATH];
  519. TCHAR szFilePath[MAX_PATH];
  520. UCHAR szUFilePath[MAX_PATH];
  521. HFILE hfImport;
  522. HANDLE hImport;
  523. TCHAR szStr[MAX_CHAR_NUM+10];
  524. UCHAR *szUBuf;
  525. TCHAR *szBuf;
  526. DWORD flen;
  527. BOOL bOver=FALSE;
  528. UINT i,len;
  529. UINT iEdit,iWord;
  530. BOOL is_WORD;
  531. iEdit=lcGetEditFocus(GetFocus(), &is_WORD);
  532. iWord=iDisp_Top+iEdit;
  533. if(iWord > lWordBuff)
  534. iWord=lWordBuff;
  535. if(!lcSaveEditText(iDisp_Top, 0))
  536. return FALSE;
  537. szFileName[0]=0;
  538. LoadString (hInst, IDS_APPENDTITLE, szFileOpen, sizeof(szFileOpen)/sizeof(TCHAR));
  539. szCustFilter[0]=0;
  540. lstrcpy(&szCustFilter[1], szExt);
  541. lstrcpy(szFilePath, szExt);
  542. /* fill in non-variant fields of OPENFILENAME struct. */
  543. ofn.lStructSize = sizeof(OPENFILENAME);
  544. ofn.hwndOwner = NULL;
  545. ofn.lpstrFilter = szFilterSpec;
  546. ofn.lpstrCustomFilter = szCustFilter;
  547. ofn.nMaxCustFilter = sizeof(szCustFilter);
  548. ofn.nFilterIndex = 1;
  549. ofn.lpstrFile = szFilePath;
  550. ofn.nMaxFile = MAX_PATH;
  551. ofn.lpstrInitialDir = g_szLCUserPath;
  552. ofn.lpstrFileTitle = szFileName;
  553. ofn.nMaxFileTitle = MAX_PATH;
  554. ofn.lpstrTitle = szFileOpen;
  555. ofn.lpstrDefExt = szExt+2;
  556. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  557. OFN_PATHMUSTEXIST;
  558. /* call common open dialog and return result */
  559. if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  560. {
  561. SetCursor(hCursorWait);
  562. WideCharToMultiByte(CP_ACP,0,szFilePath,-1,szUFilePath,MAX_PATH,NULL,0);
  563. hfImport=_lopen(szUFilePath,OF_READ);
  564. if(hfImport == -1){
  565. lcErrIOMsg(IDS_ERR_FILEOPEN, szUFilePath);
  566. return FALSE;
  567. }
  568. // get file length
  569. flen=_llseek(hfImport,0L,2);
  570. _llseek(hfImport,0L,0); //set to beginning
  571. // Allocate Memory
  572. hImport = GlobalAlloc(GMEM_FIXED, flen + 2);
  573. if(!hImport) {
  574. lcErrMsg(IDS_ERR_MEMORY);
  575. return FALSE;
  576. }
  577. szUBuf = GlobalLock(hImport);
  578. // Read file to memory
  579. if(flen != _lread(hfImport,szUBuf,flen)) {
  580. lcErrIOMsg(IDS_ERR_FILEREAD, szUFilePath);
  581. return FALSE;
  582. }
  583. _lclose(hfImport);
  584. szUBuf[flen] = 0;
  585. if(szUBuf[1]!=0xFE && szUBuf[0]!=0xFF) //not a unicode file
  586. {
  587. HANDLE hImport2 = GlobalAlloc(GMEM_FIXED, ((flen+2)<<1));
  588. if(!hImport2) {
  589. lcErrMsg(IDS_ERR_MEMORY);
  590. return FALSE;
  591. }
  592. szBuf = GlobalLock(hImport2);
  593. flen=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szUBuf,-1,szBuf+1,flen);
  594. GlobalUnlock(hImport);
  595. GlobalFree(hImport);
  596. hImport=hImport2;
  597. flen<<=1;
  598. flen-=2;
  599. }
  600. else
  601. szBuf=(TCHAR*)szUBuf;
  602. len=0;
  603. for(i=1; i<=((flen>>1)+1); i++) { //@D01C
  604. if((szBuf[i] == 0x000d) || (szBuf[i] == 0x000a)) {
  605. if(len != 0) {
  606. if(!lcInsline(szStr, iWord++, len, &bOver))
  607. break;
  608. len=0;
  609. }
  610. continue;
  611. }
  612. if((szBuf[i] == 0x001a) || (i == ((flen>>1)+1))) { //@D01C
  613. if(len != 0) {
  614. if(!lcInsline(szStr, iWord++, len, &bOver))
  615. break;
  616. }
  617. break;
  618. }
  619. if(len >= MAX_CHAR_NUM+3)
  620. bOver=TRUE;
  621. else
  622. szStr[len++]=szBuf[i];
  623. }
  624. if(bOver)
  625. lcErrMsg(IDS_ERR_OVERMAX);
  626. SetScrollRange(subhWnd, SB_VERT, 0, lWordBuff-iPage_line, FALSE);
  627. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE);
  628. lcSetEditText(iDisp_Top, FALSE);
  629. GlobalUnlock(hImport);
  630. GlobalFree(hImport);
  631. bSaveFile=TRUE;
  632. }
  633. return TRUE;
  634. }
  635. BOOL lcImport(
  636. HWND hwnd)
  637. {
  638. OPENFILENAME ofn;
  639. TCHAR szFileOpen[25];
  640. TCHAR szCustFilter[10];
  641. TCHAR szFileName[MAX_PATH];
  642. TCHAR szFilePath[MAX_PATH];
  643. UCHAR szUFilePath[MAX_PATH];
  644. HFILE hfImport;
  645. HANDLE hImport;
  646. TCHAR szStr[MAX_CHAR_NUM+10];
  647. TCHAR *szBuf;
  648. UCHAR *szUBuf;
  649. DWORD flen;
  650. BOOL bOver=FALSE;
  651. UINT i,len;
  652. UINT iWord; // @D04A
  653. if(!lcSaveEditText(iDisp_Top, 0))
  654. return FALSE;
  655. szFileName[0]=0;
  656. LoadString (hInst, IDS_IMPORTTITLE, szFileOpen, sizeof(szFileOpen)/sizeof(TCHAR));
  657. szCustFilter[0]=0;
  658. lstrcpy(&szCustFilter[1], szExt);
  659. lstrcpy(szFilePath, szExt);
  660. /* fill in non-variant fields of OPENFILENAME struct. */
  661. ofn.lStructSize = sizeof(OPENFILENAME);
  662. ofn.hwndOwner = NULL;
  663. ofn.lpstrFilter = szFilterSpec;
  664. ofn.lpstrCustomFilter = szCustFilter;
  665. ofn.nMaxCustFilter = sizeof(szCustFilter);
  666. ofn.nFilterIndex = 1;
  667. ofn.lpstrFile = szFilePath;
  668. ofn.nMaxFile = MAX_PATH;
  669. ofn.lpstrInitialDir = g_szLCUserPath;
  670. ofn.lpstrFileTitle = szFileName;
  671. ofn.nMaxFileTitle = MAX_PATH;
  672. ofn.lpstrTitle = szFileOpen;
  673. ofn.lpstrDefExt = szExt+2;
  674. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  675. OFN_PATHMUSTEXIST;
  676. /* call common open dialog and return result */
  677. if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  678. {
  679. SetCursor(hCursorWait);
  680. // Clear all flag first
  681. iWord=0; //@D04A
  682. iDisp_Top=0; //@D03A
  683. lWordBuff=0; //@D03A
  684. lPhraseBuff=0; //@D03A
  685. lcSetEditText(0, FALSE); //@D03A
  686. SetScrollRange(subhWnd, SB_VERT, 0, iPage_line, TRUE); //@D03A
  687. yPos=0; //@D03A
  688. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE); //@D03A
  689. bSaveFile=FALSE; //@D03A
  690. iFirstFree=NULL_SEG; //@D03A
  691. WideCharToMultiByte(CP_ACP,0,szFilePath,-1,szUFilePath,MAX_PATH,NULL,0);
  692. hfImport=_lopen(szUFilePath,OF_READ);
  693. if(hfImport == -1){
  694. lcErrIOMsg(IDS_ERR_FILEOPEN, szUFilePath);
  695. return FALSE;
  696. }
  697. // get file length
  698. flen=_llseek(hfImport,0L,2);
  699. _llseek(hfImport,0L,0); //set to beginning
  700. // Allocate Memory
  701. hImport = GlobalAlloc(GMEM_FIXED, flen + 2);
  702. if(!hImport) {
  703. lcErrMsg(IDS_ERR_MEMORY);
  704. _lclose(hfImport);
  705. return FALSE;
  706. }
  707. szUBuf = GlobalLock(hImport);
  708. // Read file to memory
  709. if(flen != _lread(hfImport,szUBuf,flen)) {
  710. lcErrIOMsg(IDS_ERR_FILEREAD, szUFilePath);
  711. return FALSE;
  712. }
  713. _lclose(hfImport);
  714. szUBuf[flen] = 0;
  715. if(szUBuf[1]!=0xFE && szUBuf[0]!=0xFF) //not a unicode file
  716. {
  717. HANDLE hImport2 = GlobalAlloc(GMEM_FIXED, (flen+2)<<1);
  718. if(!hImport2) {
  719. lcErrMsg(IDS_ERR_MEMORY);
  720. return FALSE;
  721. }
  722. szBuf = GlobalLock(hImport2);
  723. flen=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szUBuf,-1,szBuf+1,flen);
  724. GlobalUnlock(hImport);
  725. GlobalFree(hImport);
  726. hImport=hImport2;
  727. flen<<=1;
  728. flen-=2;
  729. }
  730. else
  731. szBuf=(TCHAR*)szUBuf;
  732. len=0;
  733. for(i=1; i<= ((flen>>1)+1); i++) { //@D01C
  734. if((szBuf[i] == 0x000d) || (szBuf[i] == 0x000a)) {
  735. if(len != 0) {
  736. if(!lcInsline(szStr, iWord++, len, &bOver))
  737. break;
  738. len=0;
  739. }
  740. continue;
  741. }
  742. if((szBuf[i] == 0x001a) || (i == ((flen>>1)+1))) { //@D01C
  743. if(len != 0) {
  744. if(!lcInsline(szStr, iWord++, len, &bOver))
  745. break;
  746. }
  747. break;
  748. }
  749. if(len >= MAX_CHAR_NUM+3)
  750. bOver=TRUE;
  751. else
  752. szStr[len++]=szBuf[i];
  753. }
  754. if(bOver)
  755. lcErrMsg(IDS_ERR_OVERMAX);
  756. SetScrollRange(subhWnd, SB_VERT, 0, lWordBuff-iPage_line, FALSE);
  757. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE);
  758. lcSetEditText(iDisp_Top, FALSE);
  759. GlobalUnlock(hImport);
  760. GlobalFree(hImport);
  761. bSaveFile=TRUE;
  762. SetFocus(hwndWord[0]); // @D04A
  763. }
  764. return TRUE;
  765. }
  766. BOOL lcExport(
  767. HWND hwnd,int mode)
  768. {
  769. OPENFILENAME ofn;
  770. TCHAR szFileOpen[25];
  771. TCHAR szCustFilter[10];
  772. TCHAR szFileName[MAX_PATH];
  773. TCHAR szFilePath[MAX_PATH];
  774. UCHAR szUStr[MAX_PATH];
  775. HFILE hfExport;
  776. UCHAR szStr[MAX_CHAR_NUM+10];
  777. UINT i,len;
  778. TCHAR *pTchar;
  779. if(!lcSaveEditText(iDisp_Top, 0))
  780. return FALSE;
  781. szFileName[0]=0;
  782. if (mode == FILE_UNICODE)
  783. LoadString (hInst, IDS_EXPORTTITLE, szFileOpen, sizeof(szFileOpen)/sizeof(TCHAR));
  784. else
  785. LoadString (hInst, IDS_EXPORTBIG5TITLE, szFileOpen, sizeof(szFileOpen)/sizeof(TCHAR) );
  786. szCustFilter[0]=0;
  787. lstrcpy(&szCustFilter[1], szExt);
  788. szCustFilter[lstrlen(szExt) + 1] = 0;
  789. lstrcpy(szFilePath, szExt);
  790. /* fill in non-variant fields of OPENFILENAME struct. */
  791. ofn.lStructSize = sizeof(OPENFILENAME);
  792. ofn.hwndOwner = hwnd;
  793. ofn.lpstrFilter = szFilterSpec;
  794. ofn.lpstrCustomFilter = szCustFilter;
  795. ofn.nMaxCustFilter = sizeof(szCustFilter);
  796. ofn.nFilterIndex = 1;
  797. ofn.lpstrFile = szFilePath;
  798. ofn.nMaxFile = MAX_PATH;
  799. ofn.lpstrInitialDir = g_szLCUserPath;
  800. ofn.lpstrFileTitle = szFileName;
  801. ofn.nMaxFileTitle = MAX_PATH;
  802. ofn.lpstrTitle = szFileOpen;
  803. ofn.lpstrDefExt = szExt+2;
  804. ofn.Flags = OFN_CREATEPROMPT | OFN_HIDEREADONLY |
  805. OFN_PATHMUSTEXIST;
  806. /* call common open dialog and return result */
  807. if(GetSaveFileName ((LPOPENFILENAME)&ofn))
  808. {
  809. HANDLE hExport;
  810. SetCursor(hCursorWait);
  811. hExport = CreateFile(szFilePath,
  812. GENERIC_READ | GENERIC_WRITE,
  813. FILE_SHARE_READ,
  814. NULL,
  815. CREATE_ALWAYS,
  816. FILE_ATTRIBUTE_NORMAL,
  817. NULL ) ;
  818. if(hExport == INVALID_HANDLE_VALUE){
  819. WideCharToMultiByte(CP_ACP,0,szFilePath,-1,szUStr,MAX_PATH,NULL,0);
  820. lcErrIOMsg(IDS_ERR_FILEOPEN, szUStr);
  821. return FALSE;
  822. }
  823. hfExport = PtrToInt( hExport );
  824. if(mode==FILE_UNICODE){
  825. szStr[0]=0xFF;
  826. szStr[1]=0xFE;
  827. _lwrite(hfExport,szStr,2);
  828. szStr[2]=' ';
  829. szStr[3]=0;
  830. pTchar=(TCHAR*)(szStr+4);
  831. for(i=0; i<lWordBuff; i++) {
  832. *((LPUNAWORD)szStr)=lpWord[i].wWord;
  833. len=lcMem2Disp(i, pTchar)+1;
  834. szStr[len<<1] = 0x0d;
  835. szStr[(len<<1)+1] = 0x00;
  836. szStr[(len<<1)+2] = 0x0a;
  837. szStr[(len<<1)+3] = 0x00;
  838. if((len<<1)+4 != _lwrite(hfExport,szStr,(len<<1)+4)) {
  839. WideCharToMultiByte(CP_ACP,0,szFilePath,-1,szUStr,MAX_PATH,NULL,0);
  840. lcErrIOMsg(IDS_ERR_FILEOPEN, szUStr);
  841. _lclose(hfExport);
  842. return FALSE;
  843. }
  844. }
  845. }else{ //write in BIG5 code
  846. TCHAR szTStr[MAX_CHAR_NUM+10];
  847. szStr[2]=0x20;
  848. for(i=0; i<lWordBuff; i++) {
  849. szTStr[1]=0;
  850. szTStr[0]=lpWord[i].wWord;
  851. WideCharToMultiByte(CP_ACP,0,szTStr,1,szStr,MAX_CHAR_NUM,NULL,0);
  852. lcMem2Disp(i,szTStr);
  853. len=WideCharToMultiByte(CP_ACP,0,szTStr,-1,szStr+3,MAX_CHAR_NUM,NULL,0);
  854. szStr[len+1] = 0x0d;
  855. szStr[len+2] = 0x0a;
  856. if( len+3 != _lwrite(hfExport,szStr,len+3)) {
  857. WideCharToMultiByte(CP_ACP,0,szFilePath,-1,szUStr,MAX_PATH,NULL,0);
  858. lcErrIOMsg(IDS_ERR_FILEOPEN, szUStr);
  859. _lclose(hfExport);
  860. return FALSE;
  861. }
  862. }
  863. }
  864. // Append EOF
  865. szStr[0]=0x1a;
  866. szStr[1]=0;
  867. _lwrite(hfExport,szStr,2);
  868. _lclose(hfExport);
  869. }
  870. return TRUE;
  871. }
  872. void lcQueryModify(
  873. HWND hwnd)
  874. {
  875. UINT i;
  876. if(!bSaveFile) {
  877. for(i=0; i<iPage_line; i++) {
  878. if(SendMessage(hwndWord[i], EM_GETMODIFY, 0, 0)) {
  879. bSaveFile=TRUE;
  880. break;
  881. }
  882. if(SendMessage(hwndPhrase[i], EM_GETMODIFY, 0, 0)) {
  883. bSaveFile=TRUE;
  884. break;
  885. }
  886. }
  887. }
  888. }
  889. BOOL lcQuerySave(
  890. HWND hwnd)
  891. {
  892. TCHAR szMsg1[MAX_PATH];
  893. TCHAR szMsg2[MAX_PATH];
  894. lcQueryModify(hwnd);
  895. if(bSaveFile) {
  896. LoadString(hInst, IDS_APPNAME, szMsg1, sizeof(szMsg1)/sizeof(TCHAR));
  897. LoadString(hInst, IDS_FILEMODIFIED, szMsg2, sizeof(szMsg2)/sizeof(TCHAR));
  898. if(MessageBox(hwnd, szMsg2, szMsg1,
  899. MB_ICONQUESTION | MB_YESNO) == IDYES) {
  900. if(!lcFSave(hwnd,TRUE))
  901. return FALSE;
  902. }
  903. }
  904. return TRUE;
  905. }
  906. void lcErrIOMsg(
  907. UINT iMsgID,
  908. UCHAR *szFileName)
  909. {
  910. TCHAR szErrStr[MAX_PATH];
  911. TCHAR szShowMsg[MAX_PATH];
  912. LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr) / sizeof(TCHAR) );
  913. wsprintf(szShowMsg, szErrStr, szFileName);
  914. MessageBox(hwndMain, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION);
  915. }
  916. #else // UNICODE
  917. BOOL lcAddPhrase( UCHAR *, UCHAR *, UINT *, WORD, WORD, DWORD);
  918. BOOL lcFOpen(
  919. HWND hWnd)
  920. {
  921. HANDLE hLCPtr,hLCPhrase;
  922. HFILE hfLCPtr,hfLCPhrase;
  923. DWORD flen_Ptr,flen_Phrase;
  924. UCHAR szLCPtrName[MAX_PATH];
  925. UCHAR szLCPhraseName[MAX_PATH];
  926. UCHAR *szLCPtrBuf,*szLCPhraseBuf;
  927. BOOL rc;
  928. UINT i;
  929. WORD wStart,wEnd;
  930. UCHAR szDispBuf[MAX_CHAR_NUM];
  931. UINT nDisp,len;
  932. // Get system directory
  933. len = GetSystemDirectory((LPSTR)szLCPtrName, sizeof(szLCPtrName));
  934. if (szLCPtrName[len - 1] != '\\') { // consider C:\ ;
  935. szLCPtrName[len++] = '\\';
  936. szLCPtrName[len] = 0;
  937. }
  938. lstrcpy(szLCPhraseName, szLCPtrName);
  939. lstrcat(szLCPtrName, LCPTRFILE);
  940. lstrcat(szLCPhraseName, LCPHRASEFILE);
  941. // Open LC pointer file
  942. hfLCPtr=_lopen(szLCPtrName,OF_READ);
  943. if(hfLCPtr == -1){
  944. lcErrIOMsg(IDS_ERR_FILEOPEN, LCPTRFILE);
  945. return FALSE;
  946. }
  947. hfLCPhrase=_lopen(szLCPhraseName,OF_READ);
  948. // Open LC phrase file
  949. if(hfLCPhrase == -1){
  950. _lclose(hfLCPtr);
  951. lcErrIOMsg(IDS_ERR_FILEOPEN, LCPTRFILE);
  952. return FALSE;
  953. }
  954. // get file length
  955. flen_Ptr=_llseek(hfLCPtr,0L,2); /* get file length */
  956. // Allocate Memory
  957. hLCPtr = GlobalAlloc(GMEM_FIXED, flen_Ptr);
  958. if(!hLCPtr) {
  959. lcErrMsg(IDS_ERR_MEMORY);
  960. goto error;
  961. }
  962. szLCPtrBuf = GlobalLock(hLCPtr);
  963. _llseek(hfLCPtr,0L,0); //set to beginning 4
  964. if(flen_Ptr != _lread(hfLCPtr,szLCPtrBuf,flen_Ptr)) {
  965. lcErrIOMsg(IDS_ERR_FILEREAD, LCPTRFILE);
  966. goto error;
  967. }
  968. _lclose(hfLCPtr);
  969. //get file length
  970. flen_Phrase=_llseek(hfLCPhrase,0L,2); /* get file length */
  971. // Allocate Memory
  972. hLCPhrase = GlobalAlloc(GMEM_MOVEABLE, flen_Phrase);
  973. if(!hLCPhrase) {
  974. lcErrMsg(IDS_ERR_MEMORY);
  975. goto error;
  976. }
  977. szLCPhraseBuf = GlobalLock(hLCPhrase);
  978. _llseek(hfLCPhrase,0L,0); //set to beginning
  979. if(flen_Phrase != _lread(hfLCPhrase,szLCPhraseBuf,flen_Phrase)) {
  980. lcErrIOMsg(IDS_ERR_FILEREAD, LCPHRASEFILE);
  981. goto error;
  982. }
  983. _lclose(hfLCPhrase);
  984. rc=TRUE;
  985. // Convert file to structured memory (WORDBUF & PHRASEBUF)
  986. // First record is Null record skip it
  987. for(i=1; i<(flen_Ptr/PTRRECLEN-1); i++) {
  988. // If Allocated Word buffer not enough Reallocate it
  989. if(iWordBuff+1 == nWordBuffsize)
  990. if(!(rc=lcAllocWord())) {
  991. break;
  992. }
  993. lpWord[iWordBuff].wWord=*((WORD *)&szLCPtrBuf[i*PTRRECLEN]);
  994. // If Allocated Phrase buffer not enough Reallocate it
  995. if(iPhraseBuff+1 == nPhraseBuffsize)
  996. if(!(rc=lcAllocPhrase())) {
  997. break;
  998. }
  999. lpWord[iWordBuff].iFirst_Seg=iPhraseBuff;
  1000. lpPhrase[iPhraseBuff].iNext_Seg=NULL_SEG;
  1001. iWordBuff++;
  1002. iPhraseBuff++;
  1003. nDisp=0;
  1004. // Add Phrase to Display buffer
  1005. wStart=*((WORD *)&szLCPtrBuf[i*PTRRECLEN+2]);
  1006. wEnd=*((WORD *)&szLCPtrBuf[i*PTRRECLEN+PTRRECLEN+2]);
  1007. if(wStart != wEnd) {
  1008. rc=lcAddPhrase(szLCPhraseBuf, szDispBuf, &nDisp,
  1009. wStart, wEnd, flen_Phrase);
  1010. if(!rc)
  1011. break;
  1012. }
  1013. // Put display buffer into Phrase buffer
  1014. if(nDisp == 0)
  1015. szDispBuf[0]=0;
  1016. else
  1017. szDispBuf[nDisp-1]=0;
  1018. if(!(rc=lcDisp2Mem(iWordBuff-1, szDispBuf)))
  1019. break;
  1020. }
  1021. GlobalUnlock(hLCPtr);
  1022. GlobalUnlock(hLCPhrase);
  1023. GlobalFree(hLCPtr);
  1024. GlobalFree(hLCPhrase);
  1025. return rc;
  1026. error:
  1027. _lclose(hfLCPtr);
  1028. _lclose(hfLCPhrase);
  1029. GlobalUnlock(hLCPtr);
  1030. GlobalUnlock(hLCPhrase);
  1031. GlobalFree(hLCPtr);
  1032. GlobalFree(hLCPhrase);
  1033. return FALSE;
  1034. }
  1035. BOOL lcAddPhrase(
  1036. UCHAR *szLCWord, // LC Phrase buffer
  1037. UCHAR *szDispBuf, // Display buffer
  1038. UINT *nDisp, // Display buffer length
  1039. WORD wStart, // Start address of LC Phrase
  1040. WORD wEnd, // End address of LC Phrase
  1041. DWORD lLen) // Total Length of LC Phrase
  1042. {
  1043. UINT i;
  1044. WORD wWord;
  1045. // Check length
  1046. if(lLen < ((DWORD)wEnd)*2) {
  1047. lcErrMsg(IDS_ERR_LCPTRFILE);
  1048. return FALSE;
  1049. }
  1050. for(i=wStart; i < wEnd; i++) {
  1051. wWord=*((WORD *)&szLCWord[i*2]);
  1052. wWord |= END_PHRASE;
  1053. if(!is_DBCS(wWord, TRUE))
  1054. return FALSE;
  1055. szDispBuf[(*nDisp)++]=HIBYTE(wWord);
  1056. szDispBuf[(*nDisp)++]=LOBYTE(wWord);
  1057. // If End of Phrase append space
  1058. if( !( (*((WORD *)&szLCWord[i*2])) & END_PHRASE) )
  1059. szDispBuf[(*nDisp)++]=' ';
  1060. // Check Disply buffer length
  1061. if( ((*nDisp)+3) >= MAX_CHAR_NUM) {
  1062. lcErrMsg(IDS_ERR_OVERMAX);
  1063. return FALSE;
  1064. }
  1065. }
  1066. return TRUE;
  1067. }
  1068. BOOL lcFSave(
  1069. HWND hwnd)
  1070. {
  1071. HFILE hfLCPtr,hfLCPhrase;
  1072. UCHAR szLCPtrName[MAX_PATH];
  1073. UCHAR szLCPhraseName[MAX_PATH];
  1074. UCHAR szLCPtrBuf[PTRRECLEN],szLCPhraseBuf[MAX_CHAR_NUM];
  1075. UINT i,j;
  1076. WORD wStartPhrase;
  1077. WORD wPhraseLen;
  1078. UCHAR szStr[MAX_CHAR_NUM];
  1079. UINT len,tmplen;
  1080. if(!lcSort(hwnd))
  1081. return FALSE;
  1082. if(wSameCode)
  1083. return FALSE;
  1084. // Get system directory
  1085. len = GetSystemDirectory((LPSTR)szLCPtrName, sizeof(szLCPtrName));
  1086. if (szLCPtrName[len - 1] != '\\') { // consider C:\ ;
  1087. szLCPtrName[len++] = '\\';
  1088. szLCPtrName[len] = 0;
  1089. }
  1090. lstrcpy(szLCPhraseName, szLCPtrName);
  1091. lstrcat(szLCPtrName, LCPTRFILE);
  1092. lstrcat(szLCPhraseName, LCPHRASEFILE);
  1093. // Open LC phrase file
  1094. hfLCPhrase=(int)CreateFile(szLCPhraseName, GENERIC_READ | GENERIC_WRITE,
  1095. FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  1096. (HANDLE)NULL ) ;
  1097. if(hfLCPhrase == -1) {
  1098. lcErrMsg(IDS_ERR_FILESAVE);
  1099. goto error;
  1100. }
  1101. // Open LC pointer file
  1102. hfLCPtr=(int)CreateFile(szLCPtrName, GENERIC_READ | GENERIC_WRITE,
  1103. FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  1104. (HANDLE)NULL ) ;
  1105. if(hfLCPtr == -1) {
  1106. lcErrMsg(IDS_ERR_FILESAVE);
  1107. goto error;
  1108. }
  1109. // Write a Null record into first record
  1110. *((WORD *)(&szLCPtrBuf))=0;
  1111. *((WORD *)(&szLCPtrBuf[2]))=0;
  1112. if(PTRRECLEN != _lwrite(hfLCPtr,szLCPtrBuf,PTRRECLEN)) {
  1113. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  1114. goto error;
  1115. }
  1116. wStartPhrase=0;
  1117. for(i=0; i<iWordBuff; i++) {
  1118. wPhraseLen=0;
  1119. // Truncate same Word
  1120. if(lpWord[i].wWord == *((WORD *)(&szLCPtrBuf)))
  1121. continue;
  1122. len=lcMem2Disp(i, szStr);
  1123. tmplen=0;
  1124. for(j=0; j<len; j++) {
  1125. if(szStr[j] == ' ') {
  1126. if(tmplen != 0) {
  1127. *((WORD *)(&szLCPhraseBuf[wPhraseLen*2+tmplen-2]))&=
  1128. (NOT_END_PHRASE);
  1129. wPhraseLen+=(tmplen/2);
  1130. tmplen=0;
  1131. }
  1132. continue;
  1133. }
  1134. szLCPhraseBuf[wPhraseLen*2+tmplen]=szStr[j+1];
  1135. szLCPhraseBuf[wPhraseLen*2+tmplen+1]=szStr[j];
  1136. tmplen+=2;
  1137. j++;
  1138. }
  1139. // In case not end of space
  1140. if(tmplen != 0) {
  1141. *((WORD *)(&szLCPhraseBuf[wPhraseLen*2+tmplen-2]))&=
  1142. (NOT_END_PHRASE);
  1143. wPhraseLen+=(tmplen/2);
  1144. tmplen=0;
  1145. }
  1146. // Check register phrase over max length
  1147. if(wStartPhrase > (0xfffd-wPhraseLen)) {
  1148. lcErrMsg(IDS_ERR_OVER_MAXLEN);
  1149. goto error;
  1150. }
  1151. *((WORD *)(&szLCPtrBuf))=lpWord[i].wWord;
  1152. *((WORD *)(&szLCPtrBuf[2]))=wStartPhrase;
  1153. if(PTRRECLEN != _lwrite(hfLCPtr,szLCPtrBuf,PTRRECLEN)) {
  1154. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  1155. goto error;
  1156. }
  1157. if(wPhraseLen)
  1158. if(((UINT)wPhraseLen*2) !=
  1159. _lwrite(hfLCPhrase,szLCPhraseBuf,wPhraseLen*2)) {
  1160. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPHRASEFILE);
  1161. goto error;
  1162. }
  1163. wStartPhrase+=wPhraseLen;
  1164. }
  1165. // Write the lasr record
  1166. *((WORD *)(&szLCPtrBuf))=0xffff;
  1167. *((WORD *)(&szLCPtrBuf[2]))=wStartPhrase;
  1168. if(PTRRECLEN != _lwrite(hfLCPtr,szLCPtrBuf,PTRRECLEN)) {
  1169. lcErrIOMsg(IDS_ERR_FILEWRITE, LCPTRFILE);
  1170. goto error;
  1171. }
  1172. SetEndOfFile((HANDLE)hfLCPtr);
  1173. SetEndOfFile((HANDLE)hfLCPhrase);
  1174. _lclose(hfLCPtr);
  1175. _lclose(hfLCPhrase);
  1176. bSaveFile=FALSE;
  1177. return TRUE;
  1178. error:
  1179. _lclose(hfLCPtr);
  1180. _lclose(hfLCPhrase);
  1181. return FALSE;
  1182. }
  1183. BOOL lcInsline(
  1184. UCHAR *szStr,
  1185. UINT iWord,
  1186. UINT len,
  1187. BOOL *bOver)
  1188. {
  1189. WORD wWord;
  1190. UINT iFree,nDisp;
  1191. UINT i,j,buflen;
  1192. UCHAR szDispBuf[MAX_CHAR_NUM];
  1193. UCHAR szBuffer[MAX_CHAR_NUM*2];
  1194. int l;
  1195. szStr[len]=0; // Append Null to end of line
  1196. // Skip lead spaces if exist
  1197. for(i=0; (i<len) && (szStr[i] == ' '); i++);
  1198. if( ((i+2) >= len) || (szStr[i+2] != ' ') ) {
  1199. lcErrMsg(IDS_ERR_IMP_SEPRATOR);
  1200. return FALSE;
  1201. }
  1202. if(!is_DBCS2(*((WORD *)(&szStr[i])), TRUE)) {
  1203. return FALSE;
  1204. }
  1205. wWord=(szStr[i] << 8)+szStr[i+1];
  1206. // Skip spaces after Word
  1207. for(j=i+2; (j<len) && (szStr[j] == ' '); j++);
  1208. if(j == len) {
  1209. lcErrMsg(IDS_ERR_IMP_NOPHRASE);
  1210. return FALSE;
  1211. }
  1212. lstrcpy(szDispBuf, &szStr[j]);
  1213. nDisp=lstrlen(szDispBuf)+1;
  1214. // Check DBCS
  1215. for(i=0; i<(nDisp-1); i++) {
  1216. if(szDispBuf[i] == ' ')
  1217. continue;
  1218. if(!is_DBCS2(*((WORD *)(&szDispBuf[i])), TRUE)) {
  1219. return FALSE;
  1220. }
  1221. i++;
  1222. }
  1223. // Check same Word
  1224. for(i=0; i<iWordBuff; i++) {
  1225. if(lpWord[i].wWord==wWord) {
  1226. buflen=lcMem2Disp(i, szBuffer);
  1227. if((buflen + lstrlen(szDispBuf)) >= MAX_CHAR_NUM)
  1228. *bOver=TRUE;
  1229. lstrcat(szBuffer, szDispBuf);
  1230. return(lcDisp2Mem(i, szBuffer));
  1231. }
  1232. }
  1233. // Check Word buffer enough ?
  1234. if(iWordBuff+1 == nWordBuffsize)
  1235. if(!lcAllocWord())
  1236. return FALSE;
  1237. // Allocate a Phrase Buffer
  1238. iFree=lcGetSeg();
  1239. if(iFree == NULL_SEG)
  1240. return FALSE;
  1241. if(iWordBuff == 0) {
  1242. lpWord[iWord].wWord=wWord;
  1243. lpWord[iWord].iFirst_Seg=iFree;
  1244. } else {
  1245. for(l=iWordBuff; l >= (int)iWord; l--) {
  1246. lpWord[l+1].wWord=lpWord[l].wWord;
  1247. lpWord[l+1].iFirst_Seg=lpWord[l].iFirst_Seg;
  1248. }
  1249. lpWord[iWord].wWord=wWord;
  1250. lpWord[iWord].iFirst_Seg=iFree;
  1251. }
  1252. iWordBuff++;
  1253. if(!lcDisp2Mem(iWord, szDispBuf))
  1254. return FALSE;
  1255. return TRUE;
  1256. }
  1257. BOOL lcAppend(
  1258. HWND hwnd)
  1259. {
  1260. OPENFILENAME ofn;
  1261. UCHAR szFileOpen[25];
  1262. UCHAR szCustFilter[10];
  1263. UCHAR szFileName[MAX_PATH];
  1264. UCHAR szFilePath[MAX_PATH];
  1265. HFILE hfImport;
  1266. HANDLE hImport;
  1267. UCHAR szStr[MAX_CHAR_NUM+10];
  1268. UCHAR *szBuf;
  1269. DWORD flen;
  1270. BOOL bOver=FALSE;
  1271. UINT i,len;
  1272. UINT iEdit,iWord;
  1273. BOOL is_WORD;
  1274. iEdit=lcGetEditFocus(GetFocus(), &is_WORD);
  1275. iWord=iDisp_Top+iEdit;
  1276. if(iWord > iWordBuff)
  1277. iWord=iWordBuff;
  1278. if(!lcSaveEditText(iDisp_Top, 0))
  1279. return FALSE;
  1280. szFileName[0]=0;
  1281. LoadString (hInst, IDS_APPENDTITLE, szFileOpen, sizeof(szFileOpen));
  1282. szCustFilter[0]=0;
  1283. lstrcpy(&szCustFilter[1], szExt);
  1284. lstrcpy(szFilePath, szExt);
  1285. /* fill in non-variant fields of OPENFILENAME struct. */
  1286. ofn.lStructSize = sizeof(OPENFILENAME);
  1287. ofn.hwndOwner = NULL;
  1288. ofn.lpstrFilter = szFilterSpec;
  1289. ofn.lpstrCustomFilter = szCustFilter;
  1290. ofn.nMaxCustFilter = sizeof(szCustFilter);
  1291. ofn.nFilterIndex = 1;
  1292. ofn.lpstrFile = szFilePath;
  1293. ofn.nMaxFile = MAX_PATH;
  1294. ofn.lpstrInitialDir = NULL;
  1295. ofn.lpstrFileTitle = szFileName;
  1296. ofn.nMaxFileTitle = MAX_PATH;
  1297. ofn.lpstrTitle = szFileOpen;
  1298. ofn.lpstrDefExt = szExt+3;
  1299. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  1300. OFN_PATHMUSTEXIST;
  1301. /* call common open dialog and return result */
  1302. if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  1303. {
  1304. SetCursor(hCursorWait);
  1305. hfImport=_lopen(szFilePath,OF_READ);
  1306. if(hfImport == -1){
  1307. lcErrIOMsg(IDS_ERR_FILEOPEN, szFilePath);
  1308. return FALSE;
  1309. }
  1310. // get file length
  1311. flen=_llseek(hfImport,0L,2);
  1312. _llseek(hfImport,0L,0); //set to beginning
  1313. // Allocate Memory
  1314. hImport = GlobalAlloc(GMEM_FIXED, flen);
  1315. if(!hImport) {
  1316. lcErrMsg(IDS_ERR_MEMORY);
  1317. return FALSE;
  1318. }
  1319. szBuf = GlobalLock(hImport);
  1320. // Read file to memory
  1321. if(flen != _lread(hfImport,szBuf,flen)) {
  1322. lcErrIOMsg(IDS_ERR_FILEREAD, szFilePath);
  1323. return FALSE;
  1324. }
  1325. _lclose(hfImport);
  1326. len=0;
  1327. //@D01D for(i=0; i<flen; i++) {
  1328. for(i=0; i<(flen+1); i++) { //@D01C
  1329. if((szBuf[i] == 0x0d) || (szBuf[i] == 0x0a)) {
  1330. if(len != 0) {
  1331. if(!lcInsline(szStr, iWord++, len, &bOver))
  1332. break;
  1333. len=0;
  1334. }
  1335. continue;
  1336. }
  1337. //@D01D if(szBuf[i] == 0x1a) {
  1338. if((szBuf[i] == 0x1a) || (i == flen)) { //@D01C
  1339. if(len != 0) {
  1340. if(!lcInsline(szStr, iWord++, len, &bOver))
  1341. break;
  1342. }
  1343. break;
  1344. }
  1345. if(len >= MAX_CHAR_NUM+3)
  1346. bOver=TRUE;
  1347. else
  1348. szStr[len++]=szBuf[i];
  1349. }
  1350. if(bOver)
  1351. lcErrMsg(IDS_ERR_OVERMAX);
  1352. SetScrollRange(subhWnd, SB_VERT, 0, iWordBuff-iPage_line, FALSE);
  1353. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE);
  1354. lcSetEditText(iDisp_Top, FALSE);
  1355. GlobalUnlock(hImport);
  1356. GlobalFree(hImport);
  1357. bSaveFile=TRUE;
  1358. }
  1359. return TRUE;
  1360. }
  1361. BOOL lcImport(
  1362. HWND hwnd)
  1363. {
  1364. OPENFILENAME ofn;
  1365. UCHAR szFileOpen[25];
  1366. UCHAR szCustFilter[10];
  1367. UCHAR szFileName[MAX_PATH];
  1368. UCHAR szFilePath[MAX_PATH];
  1369. HFILE hfImport;
  1370. HANDLE hImport;
  1371. UCHAR szStr[MAX_CHAR_NUM+10];
  1372. UCHAR *szBuf;
  1373. DWORD flen;
  1374. BOOL bOver=FALSE;
  1375. UINT i,len;
  1376. UINT iWord; // @D04A
  1377. //UINT iEdit,iWord; @D04D
  1378. //BOOL is_WORD; @D04D
  1379. //iEdit=lcGetEditFocus(GetFocus(), &is_WORD); @D04D
  1380. //iWord=iDisp_Top+iEdit; @D04D
  1381. //if(iWord > iWordBuff) @D04D
  1382. // iWord=iWordBuff; @D04D
  1383. if(!lcSaveEditText(iDisp_Top, 0))
  1384. return FALSE;
  1385. szFileName[0]=0;
  1386. LoadString (hInst, IDS_IMPORTTITLE, szFileOpen, sizeof(szFileOpen));
  1387. szCustFilter[0]=0;
  1388. lstrcpy(&szCustFilter[1], szExt);
  1389. lstrcpy(szFilePath, szExt);
  1390. /* fill in non-variant fields of OPENFILENAME struct. */
  1391. ofn.lStructSize = sizeof(OPENFILENAME);
  1392. ofn.hwndOwner = NULL;
  1393. ofn.lpstrFilter = szFilterSpec;
  1394. ofn.lpstrCustomFilter = szCustFilter;
  1395. ofn.nMaxCustFilter = sizeof(szCustFilter);
  1396. ofn.nFilterIndex = 1;
  1397. ofn.lpstrFile = szFilePath;
  1398. ofn.nMaxFile = MAX_PATH;
  1399. ofn.lpstrInitialDir = NULL;
  1400. ofn.lpstrFileTitle = szFileName;
  1401. ofn.nMaxFileTitle = MAX_PATH;
  1402. ofn.lpstrTitle = szFileOpen;
  1403. ofn.lpstrDefExt = szExt+3;
  1404. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  1405. OFN_PATHMUSTEXIST;
  1406. /* call common open dialog and return result */
  1407. if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  1408. {
  1409. SetCursor(hCursorWait);
  1410. // Clear all flag first
  1411. iWord=0; //@D04A
  1412. iDisp_Top=0; //@D03A
  1413. iWordBuff=0; //@D03A
  1414. iPhraseBuff=0; //@D03A
  1415. lcSetEditText(0, FALSE); //@D03A
  1416. SetScrollRange(subhWnd, SB_VERT, 0, iPage_line, TRUE); //@D03A
  1417. yPos=0; //@D03A
  1418. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE); //@D03A
  1419. bSaveFile=FALSE; //@D03A
  1420. iFirstFree=NULL_SEG; //@D03A
  1421. hfImport=_lopen(szFilePath,OF_READ);
  1422. if(hfImport == -1){
  1423. lcErrIOMsg(IDS_ERR_FILEOPEN, szFilePath);
  1424. return FALSE;
  1425. }
  1426. // get file length
  1427. flen=_llseek(hfImport,0L,2);
  1428. _llseek(hfImport,0L,0); //set to beginning
  1429. // Allocate Memory
  1430. hImport = GlobalAlloc(GMEM_FIXED, flen);
  1431. if(!hImport) {
  1432. lcErrMsg(IDS_ERR_MEMORY);
  1433. return FALSE;
  1434. }
  1435. szBuf = GlobalLock(hImport);
  1436. // Read file to memory
  1437. if(flen != _lread(hfImport,szBuf,flen)) {
  1438. lcErrIOMsg(IDS_ERR_FILEREAD, szFilePath);
  1439. return FALSE;
  1440. }
  1441. _lclose(hfImport);
  1442. len=0;
  1443. //@D01D for(i=0; i<flen; i++) {
  1444. for(i=0; i<(flen+1); i++) { //@D01C
  1445. if((szBuf[i] == 0x0d) || (szBuf[i] == 0x0a)) {
  1446. if(len != 0) {
  1447. if(!lcInsline(szStr, iWord++, len, &bOver))
  1448. break;
  1449. len=0;
  1450. }
  1451. continue;
  1452. }
  1453. //@D01D if(szBuf[i] == 0x1a) {
  1454. if((szBuf[i] == 0x1a) || (i == flen)) { //@D01C
  1455. if(len != 0) {
  1456. if(!lcInsline(szStr, iWord++, len, &bOver))
  1457. break;
  1458. }
  1459. break;
  1460. }
  1461. if(len >= MAX_CHAR_NUM+3)
  1462. bOver=TRUE;
  1463. else
  1464. szStr[len++]=szBuf[i];
  1465. }
  1466. if(bOver)
  1467. lcErrMsg(IDS_ERR_OVERMAX);
  1468. SetScrollRange(subhWnd, SB_VERT, 0, iWordBuff-iPage_line, FALSE);
  1469. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE);
  1470. lcSetEditText(iDisp_Top, FALSE);
  1471. GlobalUnlock(hImport);
  1472. GlobalFree(hImport);
  1473. bSaveFile=TRUE;
  1474. SetFocus(hwndWord[0]); // @D04A
  1475. }
  1476. return TRUE;
  1477. }
  1478. BOOL lcExport(
  1479. HWND hwnd)
  1480. {
  1481. OPENFILENAME ofn;
  1482. UCHAR szFileOpen[25];
  1483. UCHAR szCustFilter[10];
  1484. UCHAR szFileName[MAX_PATH];
  1485. UCHAR szFilePath[MAX_PATH];
  1486. HFILE hfExport;
  1487. UCHAR szStr[MAX_CHAR_NUM+10];
  1488. UINT i,len;
  1489. if(!lcSaveEditText(iDisp_Top, 0))
  1490. return FALSE;
  1491. szFileName[0]=0;
  1492. LoadString (hInst, IDS_EXPORTTITLE, szFileOpen, sizeof(szFileOpen));
  1493. szCustFilter[0]=0;
  1494. lstrcpy(&szCustFilter[1], szExt);
  1495. lstrcpy(szFilePath, szExt);
  1496. /* fill in non-variant fields of OPENFILENAME struct. */
  1497. ofn.lStructSize = sizeof(OPENFILENAME);
  1498. ofn.hwndOwner = hwnd;
  1499. ofn.lpstrFilter = szFilterSpec;
  1500. ofn.lpstrCustomFilter = szCustFilter;
  1501. ofn.nMaxCustFilter = sizeof(szCustFilter);
  1502. ofn.nFilterIndex = 1;
  1503. ofn.lpstrFile = szFilePath;
  1504. ofn.nMaxFile = MAX_PATH;
  1505. ofn.lpstrInitialDir = NULL;
  1506. ofn.lpstrFileTitle = szFileName;
  1507. ofn.nMaxFileTitle = MAX_PATH;
  1508. ofn.lpstrTitle = szFileOpen;
  1509. ofn.lpstrDefExt = szExt+3;
  1510. ofn.Flags = OFN_CREATEPROMPT | OFN_HIDEREADONLY |
  1511. OFN_PATHMUSTEXIST;
  1512. /* call common open dialog and return result */
  1513. if(GetSaveFileName ((LPOPENFILENAME)&ofn))
  1514. {
  1515. SetCursor(hCursorWait);
  1516. hfExport=(int)CreateFile(szFilePath, GENERIC_READ | GENERIC_WRITE,
  1517. FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  1518. (HANDLE)NULL ) ;
  1519. if(hfExport == -1){
  1520. lcErrIOMsg(IDS_ERR_FILEOPEN, szFilePath);
  1521. return FALSE;
  1522. }
  1523. szStr[2]=' ';
  1524. szStr[3]=' ';
  1525. for(i=0; i<iWordBuff; i++) {
  1526. szStr[0]=HIBYTE(lpWord[i].wWord);
  1527. szStr[1]=LOBYTE(lpWord[i].wWord);
  1528. len=lcMem2Disp(i, &szStr[4])+4;
  1529. szStr[len] = 0x0d;
  1530. szStr[len+1] = 0x0a;
  1531. if((len+2) != _lwrite(hfExport,szStr,len+2)) {
  1532. lcErrIOMsg(IDS_ERR_FILEWRITE, szFilePath);
  1533. _lclose(hfExport);
  1534. return FALSE;
  1535. }
  1536. }
  1537. // Append EOF
  1538. szStr[0]=0x1a;
  1539. _lwrite(hfExport,szStr,1);
  1540. _lclose(hfExport);
  1541. }
  1542. return TRUE;
  1543. }
  1544. void lcQueryModify(
  1545. HWND hwnd)
  1546. {
  1547. UINT i;
  1548. if(!bSaveFile) {
  1549. for(i=0; i<iPage_line; i++) {
  1550. if(SendMessage(hwndWord[i], EM_GETMODIFY, 0, 0)) {
  1551. bSaveFile=TRUE;
  1552. break;
  1553. }
  1554. if(SendMessage(hwndPhrase[i], EM_GETMODIFY, 0, 0)) {
  1555. bSaveFile=TRUE;
  1556. break;
  1557. }
  1558. }
  1559. }
  1560. }
  1561. BOOL lcQuerySave(
  1562. HWND hwnd)
  1563. {
  1564. UCHAR szMsg1[MAX_PATH];
  1565. UCHAR szMsg2[MAX_PATH];
  1566. lcQueryModify(hwnd);
  1567. if(bSaveFile) {
  1568. LoadString(hInst, IDS_APPNAME, szMsg1, sizeof(szMsg1));
  1569. LoadString(hInst, IDS_FILEMODIFIED, szMsg2, sizeof(szMsg2));
  1570. if(MessageBox(hwnd, szMsg2, szMsg1,
  1571. MB_ICONQUESTION | MB_YESNO) == IDYES) {
  1572. if(!lcFSave(hwnd))
  1573. return FALSE;
  1574. }
  1575. }
  1576. return TRUE;
  1577. }
  1578. void lcErrIOMsg(
  1579. UINT iMsgID,
  1580. UCHAR *szFileName)
  1581. {
  1582. UCHAR szErrStr[MAX_PATH];
  1583. UCHAR szShowMsg[MAX_PATH];
  1584. LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr));
  1585. wsprintf(szShowMsg, szErrStr, szFileName);
  1586. MessageBox(hwndMain, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION);
  1587. }
  1588. #endif