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.

1113 lines
26 KiB

  1. /*************************************************
  2. * lcfunc.c *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. //
  8. // Change Log:
  9. //
  10. // @D01 Fix Bug #11204 Goto function with save text will error
  11. // @D02 Fix Bug None Only check modify status for available lines 10/04
  12. //
  13. // Change log by Eric
  14. //
  15. // @E01 Fix Bug use "Delete line" doesn't enable "Save" and "Save As"
  16. //
  17. #include <windows.h> // required for all Windows applications
  18. #include <windowsx.h>
  19. #include <stdlib.h>
  20. #include <memory.h>
  21. #include "rc.h"
  22. #include "lctool.h"
  23. #ifndef UNICODE
  24. #define lWordBuff iWordBuff
  25. #define lPhraseBuff iPhraseBuff
  26. #define lNext_Seg iNext_Seg
  27. #define lFirst_Seg iFirst_Seg
  28. #endif
  29. extern HWND subhWnd;
  30. TCHAR szEditStr[MAX_PATH];
  31. WORD wOldID=IDE_WORD_START;
  32. // Local function prototypes.
  33. INT_PTR FAR PASCAL GotoDialogProc(HWND, UINT, WPARAM, LPARAM);
  34. INT_PTR FAR PASCAL SearchDialogProc(HWND, UINT, WPARAM, LPARAM);
  35. BOOL lcKey(
  36. HWND hwnd,
  37. WPARAM wParam,
  38. USHORT uKeyState)
  39. {
  40. switch (wParam) {
  41. case VK_UP:
  42. lcUp_key(hwnd);
  43. break;
  44. case VK_DOWN:
  45. lcDown_key(hwnd);
  46. break;
  47. case VK_PRIOR :
  48. lcPgUp_key(hwnd);
  49. break;
  50. case VK_NEXT :
  51. lcPgDown_key(hwnd);
  52. break;
  53. case VK_HOME :
  54. if(uKeyState != (USHORT)CTRL_STATE)
  55. return FALSE;
  56. iDisp_Top=0;
  57. yPos=0;
  58. SetFocus(hwndWord[0]);
  59. lcSetEditText(0, TRUE);
  60. break;
  61. case VK_END :
  62. if(uKeyState != (USHORT)CTRL_STATE)
  63. return FALSE;
  64. if(lWordBuff <= iPage_line) {
  65. SetFocus(hwndWord[lWordBuff-1]);
  66. } else {
  67. iDisp_Top=lWordBuff-iPage_line;
  68. yPos=lWordBuff;
  69. lcSetEditText(iDisp_Top, TRUE);
  70. SetFocus(hwndWord[iPage_line-1]);
  71. }
  72. break;
  73. default:
  74. return FALSE;
  75. }
  76. PostMessage(hwndMain, WM_COMMAND, IDM_VSCROLL, 0);
  77. return TRUE;
  78. }
  79. BOOL lcTab_key(
  80. HWND hwnd)
  81. {
  82. UINT iEdit;
  83. BOOL is_WORD;
  84. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  85. if(is_WORD) {
  86. SetFocus(hwndPhrase[iEdit]);
  87. } else {
  88. iEdit++;
  89. if(iEdit == iPage_line)
  90. iEdit=0;
  91. SetFocus(hwndWord[iEdit]);
  92. }
  93. return TRUE;
  94. }
  95. void lcUp_key(
  96. HWND hwnd)
  97. {
  98. UINT iEdit;
  99. BOOL is_WORD;
  100. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  101. if(iEdit == 0) {
  102. if(iDisp_Top != 0) {
  103. iDisp_Top--;
  104. if(!lcSetEditText(iDisp_Top, TRUE)) {
  105. iDisp_Top++;
  106. return;
  107. }
  108. yPos--;
  109. } else
  110. MessageBeep(MB_OK);
  111. return;
  112. }
  113. iEdit--;
  114. if(is_WORD) {
  115. SetFocus(hwndWord[iEdit]);
  116. }else {
  117. SetFocus(hwndPhrase[iEdit]);
  118. }
  119. yPos--;
  120. }
  121. void lcDown_key(
  122. HWND hwnd)
  123. {
  124. UINT iEdit;
  125. BOOL is_WORD;
  126. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  127. if((iEdit+1) == iPage_line) {
  128. if((iDisp_Top+iPage_line) < lWordBuff) {
  129. iDisp_Top++;
  130. if(!lcSetEditText(iDisp_Top, TRUE)) {
  131. iDisp_Top--;
  132. return;
  133. }
  134. yPos++;
  135. } else
  136. MessageBeep(MB_OK);
  137. return;
  138. }
  139. iEdit++;
  140. if(is_WORD) {
  141. SetFocus(hwndWord[iEdit]);
  142. }else {
  143. SetFocus(hwndPhrase[iEdit]);
  144. }
  145. yPos++;
  146. }
  147. void lcPgUp_key(
  148. HWND hwnd)
  149. {
  150. UINT iEdit,iDisp_temp;
  151. BOOL is_WORD;
  152. if(iDisp_Top == 0) {
  153. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  154. if(iEdit != 0) {
  155. if(is_WORD) {
  156. SetFocus(hwndWord[0]);
  157. }else {
  158. SetFocus(hwndPhrase[0]);
  159. }
  160. yPos=0;
  161. } else
  162. MessageBeep(MB_OK);
  163. return;
  164. }
  165. yPos-=iPage_line;
  166. if(yPos < 0)
  167. yPos=0;
  168. if(iDisp_Top < iPage_line) {
  169. iDisp_temp=0;
  170. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  171. if(is_WORD) {
  172. SetFocus(hwndWord[yPos]);
  173. }else {
  174. SetFocus(hwndPhrase[yPos]);
  175. }
  176. } else
  177. iDisp_temp=iDisp_Top-iPage_line;
  178. if(lcSetEditText(iDisp_temp, TRUE))
  179. iDisp_Top=iDisp_temp;
  180. }
  181. void lcPgDown_key(
  182. HWND hwnd)
  183. {
  184. UINT iEdit,iDisp_temp;
  185. BOOL is_WORD;
  186. if(lWordBuff < iPage_line) {
  187. MessageBeep(MB_OK);
  188. return;
  189. }
  190. if((iDisp_Top+iPage_line) == lWordBuff) {
  191. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  192. if((iEdit+1) != iPage_line) {
  193. if(is_WORD) {
  194. SetFocus(hwndWord[iPage_line-1]);
  195. }else {
  196. SetFocus(hwndPhrase[iPage_line-1]);
  197. }
  198. yPos=lWordBuff-iPage_line;
  199. } else
  200. MessageBeep(MB_OK);
  201. return;
  202. }
  203. yPos+=iPage_line;
  204. if((UINT)yPos > (lWordBuff-iPage_line))
  205. yPos=lWordBuff-iPage_line;
  206. if((iDisp_Top+(iPage_line*2)) < lWordBuff)
  207. iDisp_temp=iDisp_Top+iPage_line;
  208. else {
  209. iDisp_temp=lWordBuff-iPage_line;
  210. iEdit=lcGetEditFocus(hwnd, &is_WORD);
  211. if(is_WORD) {
  212. SetFocus(hwndWord[yPos+(iPage_line*2)-lWordBuff-1]);
  213. }else {
  214. SetFocus(hwndPhrase[yPos+(iPage_line*2)-lWordBuff-1]);
  215. }
  216. }
  217. if(lcSetEditText(iDisp_temp, TRUE))
  218. iDisp_Top=iDisp_temp;
  219. }
  220. void lcGoto(
  221. HWND hwnd)
  222. {
  223. UINT iDiff,iDisp_save;
  224. int is_OK;
  225. if(!lcSaveEditText(iDisp_Top, 0))
  226. return;
  227. iDisp_save=iDisp_Top;
  228. is_OK=(int)DialogBox(hInst,
  229. _TEXT("GotoDialog"),
  230. hwndMain,
  231. (DLGPROC)GotoDialogProc);
  232. // Check cancel by user
  233. if(!is_OK) {
  234. SetFocus(hwndFocus);
  235. return;
  236. }
  237. if(iDisp_Top > (lWordBuff-iPage_line)) {
  238. iDiff=iDisp_Top-lWordBuff+iPage_line;
  239. iDisp_Top=lWordBuff-iPage_line;
  240. SetFocus(hwndWord[iDiff]);
  241. } else
  242. SetFocus(hwndWord[0]);
  243. if(!lcSetEditText(iDisp_Top, FALSE))
  244. iDisp_Top=iDisp_save;
  245. yPos=iDisp_Top;
  246. }
  247. INT_PTR FAR PASCAL GotoDialogProc(
  248. HWND hDlg,
  249. UINT message,
  250. WPARAM wParam,
  251. LPARAM lParam)
  252. {
  253. TCHAR szWordstr[MAX_PATH];
  254. TCHAR szShowMsg[MAX_PATH];
  255. WORD wWord;
  256. UINT i;
  257. switch (message) {
  258. case WM_INITDIALOG:
  259. szWordstr[0]=0; //set to be null
  260. return TRUE;
  261. case WM_COMMAND:
  262. switch (wParam) {
  263. case IDOK:
  264. case IDB_OK:
  265. GetDlgItemText(hDlg,IDD_INDEX_NAME,szWordstr, sizeof(szWordstr)/sizeof(TCHAR) );
  266. #ifdef UNICODE
  267. wWord=szWordstr[0];
  268. #else
  269. wWord=(szWordstr[0] << 8)+szWordstr[1];
  270. #endif
  271. for(i=0; i<lWordBuff; i++)
  272. if(wWord == lpWord[i].wWord)
  273. break;
  274. if(i == lWordBuff) {
  275. LoadString(hInst, IDS_ERR_NOT_FOUND,
  276. szShowMsg, sizeof(szShowMsg)/sizeof(TCHAR));
  277. MessageBox(hDlg, szShowMsg, NULL,
  278. MB_OK | MB_ICONEXCLAMATION);
  279. return TRUE;
  280. }
  281. iDisp_Top=i;
  282. EndDialog (hDlg, TRUE) ;
  283. return TRUE;
  284. case IDB_CANCEL:
  285. case IDCANCEL:
  286. EndDialog (hDlg, FALSE) ;
  287. return TRUE;
  288. case IDD_INDEX_NAME:
  289. return TRUE;
  290. }
  291. break ;
  292. case WM_CLOSE:
  293. EndDialog(hDlg, FALSE);
  294. return TRUE;
  295. }
  296. return FALSE;
  297. }
  298. UINT lcGetEditFocus(
  299. HWND hwnd,
  300. BOOL *is_WORD)
  301. {
  302. UINT i;
  303. for(i=0; i<iPage_line; i++)
  304. if(hwnd == hwndWord[i]) {
  305. *is_WORD= TRUE;
  306. return i;
  307. }
  308. for(i=0; i<iPage_line; i++)
  309. if(hwnd == hwndPhrase[i]) {
  310. *is_WORD= FALSE;
  311. return i;
  312. }
  313. // In case focus not in EDIT CONTROL, set to WORD 0
  314. *is_WORD=TRUE;
  315. return 0;
  316. }
  317. void lcErrMsg(
  318. UINT iMsgID)
  319. {
  320. TCHAR szErrStr[MAX_PATH];
  321. static fShown=FALSE;
  322. if ( fShown==TRUE )
  323. return;
  324. fShown=TRUE;
  325. LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr)/sizeof(TCHAR));
  326. MessageBox(hwndMain, szErrStr, NULL, MB_OK | MB_ICONEXCLAMATION);
  327. fShown=FALSE;
  328. }
  329. BOOL lcSetEditText(
  330. UINT iTopAddr,
  331. BOOL bSaveText)
  332. {
  333. static UINT iWord=1;
  334. TCHAR szStr[MAX_CHAR_NUM+1];
  335. UINT i,j;
  336. if(bSaveText)
  337. if(!lcSaveEditText(iWord, 0))
  338. return FALSE;
  339. iWord=iTopAddr;
  340. for(i=0; i<iPage_line; i++) {
  341. // Set Word string
  342. if(iWord == lWordBuff)
  343. break;
  344. #ifdef UNICODE
  345. szStr[0]=(TCHAR) lpWord[iWord].wWord;
  346. szStr[1]=0;
  347. #else
  348. szStr[0]=HIBYTE(lpWord[iWord].wWord);
  349. szStr[1]=LOBYTE(lpWord[iWord].wWord);
  350. szStr[2]=0;
  351. #endif
  352. SendMessage(hwndWord[i], WM_SETTEXT, 0,(LPARAM) szStr);
  353. // Set Phrase string
  354. lcMem2Disp(iWord, szStr);
  355. SendMessage(hwndPhrase[i], WM_SETTEXT, 0,(LPARAM)szStr);
  356. iWord++;
  357. }
  358. iWord=iTopAddr;
  359. // If Still have not in memory item set to null string
  360. if(i != iPage_line) {
  361. szStr[0]=0;
  362. for(j=i; j<iPage_line; j++) {
  363. SendMessage(hwndWord[j], WM_SETTEXT, 0,(LPARAM)szStr);
  364. SendMessage(hwndPhrase[j], WM_SETTEXT, 0,(LPARAM)szStr);
  365. }
  366. }
  367. return TRUE;
  368. }
  369. BOOL lcSaveEditText(
  370. UINT iWord,
  371. UINT iSkip)
  372. {
  373. TCHAR szStr[MAX_CHAR_NUM];
  374. UINT i,len,phraselen=0;
  375. UINT j;
  376. //for(i=0; i<iPage_line; i++) {
  377. for(i=0; i<min(iPage_line,lWordBuff); i++) { // @D02C
  378. if(i+1 == iSkip)
  379. continue;
  380. // Get Word string
  381. if(SendMessage(hwndWord[i], EM_GETMODIFY, 0, 0)) {
  382. bSaveFile=TRUE;
  383. SendMessage(hwndWord[i], WM_GETTEXT, 3, (LPARAM)szStr);
  384. if(lstrlen(szStr) == 0) {
  385. MessageBeep(MB_OK);
  386. SetFocus(hwndWord[i]);
  387. return FALSE;
  388. }
  389. if(!is_DBCS2(*((LPUNAWORD)(szStr)), TRUE)) {
  390. SetFocus(hwndWord[i]);
  391. return FALSE;
  392. }
  393. #ifdef UNICODE
  394. lpWord[iWord+i].wWord=szStr[0];
  395. #else
  396. lpWord[iWord+i].wWord=(szStr[0] << 8)+szStr[1];
  397. #endif
  398. SendMessage(hwndWord[i], EM_SETMODIFY, FALSE, 0); //@D01A
  399. }
  400. // Get Phrase string
  401. if(SendMessage(hwndPhrase[i], EM_GETMODIFY, 0, 0)) {
  402. bSaveFile=TRUE;
  403. SendMessage(hwndPhrase[i], WM_GETTEXT, MAX_CHAR_NUM-1, (LPARAM)szStr);
  404. len=lstrlen(szStr);
  405. if(len == 0) {
  406. MessageBeep(MB_OK);
  407. SetFocus(hwndPhrase[i]);
  408. return FALSE;
  409. }
  410. len++;
  411. //#53609 Limit phrase lenght to MAX_PHRASE_LEN.
  412. for (j=0; j<len-1; j++) {
  413. phraselen++;
  414. if(szStr[j] ==TEXT(' '))
  415. if (phraselen > MAX_PHRASE_LEN)
  416. {
  417. TCHAR szStr[128],szShowMsg[128];
  418. LoadString(hInst, IDS_OVERPHRASELEN, szStr, sizeof(szStr));
  419. wsprintf(szShowMsg, szStr, MAX_PHRASE_LEN);
  420. MessageBox(hwndMain,szShowMsg,NULL,MB_OK);
  421. SetFocus(hwndPhrase[i]);
  422. return FALSE;
  423. }
  424. else
  425. {
  426. phraselen = 0;
  427. continue;
  428. }
  429. }
  430. // Check DBCS
  431. #ifndef UNICODE
  432. for(j=0; j<len-1; j++) {
  433. if(szStr[j] ==_TEXT(' '))
  434. continue;
  435. if(!is_DBCS2(*((LPUNAWORD)(&szStr[j])), TRUE)) {
  436. SetFocus(hwndPhrase[i]);
  437. return FALSE;
  438. }
  439. j++;
  440. }
  441. #endif
  442. if(!lcDisp2Mem(iWord+i, szStr))
  443. return FALSE;
  444. SendMessage(hwndPhrase[i], EM_SETMODIFY, FALSE, 0); //@D01A
  445. }
  446. }
  447. return TRUE;
  448. }
  449. void lcDelLine(
  450. HWND hwnd)
  451. {
  452. UINT iEdit,i;
  453. BOOL is_WORD;
  454. if(lWordBuff == 0)
  455. return;
  456. iEdit=lcGetEditFocus(GetFocus(), &is_WORD);
  457. if((iDisp_Top+iEdit) > lWordBuff)
  458. return;
  459. if(!lcSaveEditText(iDisp_Top, iEdit+1))
  460. return;
  461. lcFreeSeg(lpWord[iDisp_Top+iEdit].lFirst_Seg);
  462. for(i=(iDisp_Top+iEdit); i < lWordBuff; i++) {
  463. lpWord[i].wWord=lpWord[i+1].wWord;
  464. lpWord[i].lFirst_Seg=lpWord[i+1].lFirst_Seg;
  465. }
  466. lWordBuff--;
  467. SetScrollRange(subhWnd, SB_VERT, 0, lWordBuff-iPage_line, TRUE);
  468. // Check the last page
  469. if(((iDisp_Top+iPage_line) >= lWordBuff) && (iDisp_Top != 0))
  470. iDisp_Top--;
  471. lcSetEditText(iDisp_Top, FALSE);
  472. bSaveFile = TRUE; // <== @E01
  473. }
  474. void lcInsLine(
  475. HWND hwnd)
  476. {
  477. UINT iEdit,iFree,iWord;
  478. BOOL is_WORD;
  479. int i;
  480. iEdit=lcGetEditFocus(GetFocus(), &is_WORD);
  481. iWord=iDisp_Top+iEdit;
  482. if(iWord > lWordBuff)
  483. iWord=lWordBuff;
  484. if(!lcSaveEditText(iDisp_Top, 0))
  485. return;
  486. if(lWordBuff+1 == nWordBuffsize)
  487. if(!lcAllocWord())
  488. return;
  489. iFree=lcGetSeg();
  490. if(iFree == NULL_SEG)
  491. return;
  492. if(lWordBuff == 0) {
  493. lpWord[iWord].wWord=0;
  494. lpWord[iWord].lFirst_Seg=iFree;
  495. } else {
  496. for(i=(int)lWordBuff; i >= (int)iWord; i--) {
  497. lpWord[i+1].wWord=lpWord[i].wWord;
  498. lpWord[i+1].lFirst_Seg=lpWord[i].lFirst_Seg;
  499. }
  500. lpWord[iWord].wWord=0;
  501. lpWord[iWord].lFirst_Seg=iFree;
  502. }
  503. lWordBuff++;
  504. lpPhrase[iFree].szPhrase[0]=0;
  505. lpPhrase[iFree].lNext_Seg=NULL_SEG;
  506. SetScrollRange(subhWnd, SB_VERT, 0, lWordBuff-iPage_line, TRUE);
  507. if((iEdit+1) == iPage_line) {
  508. iEdit--;
  509. iDisp_Top++;
  510. }
  511. lcSetEditText(iDisp_Top, FALSE);
  512. SendMessage(hwndWord[iEdit], EM_SETMODIFY, TRUE, 0);
  513. SendMessage(hwndPhrase[iEdit], EM_SETMODIFY, TRUE, 0);
  514. }
  515. int __cdecl lcComp(
  516. const void *Pointer1,
  517. const void *Pointer2)
  518. {
  519. LPWORDBUF lpWord1=(LPWORDBUF)Pointer1;
  520. LPWORDBUF lpWord2=(LPWORDBUF)Pointer2;
  521. if(lpWord1->wWord == lpWord2->wWord) {
  522. wSameCode=lpWord1->wWord;
  523. return 0;
  524. }
  525. if(lpWord1->wWord > lpWord2->wWord)
  526. return 1;
  527. else
  528. return -1;
  529. }
  530. BOOL lcSort(
  531. HWND hwnd)
  532. {
  533. if(!lcSaveEditText(iDisp_Top, 0))
  534. return FALSE;
  535. wSameCode=0;
  536. qsort(lpWord, lWordBuff, sizeof(WORDBUF), lcComp);
  537. if(wSameCode) {
  538. TCHAR szStr[MAX_PATH];
  539. TCHAR szErrStr[MAX_PATH];
  540. LoadString(hInst, IDS_ERR_SAMECODE, szStr, sizeof(szStr));
  541. #ifdef UNICODE
  542. wsprintf(szErrStr, szStr, wSameCode, ' ');
  543. #else
  544. wsprintf(szErrStr, szStr, HIBYTE(wSameCode), LOBYTE(wSameCode));
  545. #endif
  546. MessageBox(hwndMain, szErrStr, NULL, MB_OK | MB_ICONEXCLAMATION);
  547. }
  548. lcSetEditText(0, FALSE);
  549. yPos=0;
  550. SetScrollPos(subhWnd, SB_VERT, yPos, TRUE);
  551. iDisp_Top = 0;
  552. return TRUE;
  553. }
  554. BOOL is_DBCS(
  555. WORD wWord,
  556. BOOL bMessage)
  557. {
  558. #ifdef UNICODE
  559. #else
  560. if((HIBYTE(wWord) < 0x81) || (HIBYTE(wWord) > 0xFE)) {
  561. if(bMessage)
  562. lcErrMsg(IDS_ERR_SBCS);
  563. return FALSE;
  564. }
  565. if((LOBYTE(wWord) < 0x40) || (LOBYTE(wWord) > 0xFE)) {
  566. if(bMessage)
  567. lcErrMsg(IDS_ERR_SBCS);
  568. return FALSE;
  569. }
  570. #endif
  571. return TRUE;
  572. }
  573. BOOL is_DBCS2(
  574. WORD wWord,
  575. BOOL bMessage)
  576. {
  577. #ifndef UNICODE
  578. if((LOBYTE(wWord) < 0x81) || (LOBYTE(wWord) > 0xFE)) {
  579. if(bMessage)
  580. lcErrMsg(IDS_ERR_SBCS);
  581. return FALSE;
  582. }
  583. if((HIBYTE(wWord) < 0x40) || (HIBYTE(wWord) > 0xFE)) {
  584. if(bMessage)
  585. lcErrMsg(IDS_ERR_SBCS);
  586. return FALSE;
  587. }
  588. #endif
  589. return TRUE;
  590. }
  591. void lcEditFocusOn(
  592. WORD wID)
  593. {
  594. HWND hwnd;
  595. BOOL isWord;
  596. int iAddr;
  597. TCHAR szStr[MAX_CHAR_NUM];
  598. UINT i,len;
  599. WORD wTemp;
  600. if(wOldID != wID) {
  601. if(wOldID >= IDE_PHRASE_START) {
  602. isWord=FALSE;
  603. iAddr=wOldID-IDE_PHRASE_START;
  604. hwnd=hwndPhrase[iAddr];
  605. } else {
  606. isWord=TRUE;
  607. iAddr=wOldID-IDE_WORD_START;
  608. hwnd=hwndWord[iAddr];
  609. }
  610. if(SendMessage(hwnd, EM_GETMODIFY, 0, 0)) {
  611. bSaveFile=TRUE;
  612. SendMessage(hwnd, WM_GETTEXT, MAX_CHAR_NUM-1, (LPARAM)szStr);
  613. len=lstrlen(szStr);
  614. if(len == 0) {
  615. wOldID=wID;
  616. return;
  617. }
  618. if(isWord) {
  619. #ifdef UNICODE
  620. if(!is_DBCS2(szStr[0], FALSE))
  621. return;
  622. wTemp=lpWord[iDisp_Top+iAddr].wWord=szStr[0];
  623. #else
  624. if(!is_DBCS2(*((WORD *)(szStr)), FALSE))
  625. return;
  626. wTemp=(szStr[0] << 8)+szStr[1];
  627. lpWord[iDisp_Top+iAddr].wWord=wTemp;
  628. #endif
  629. for(i=0; i<lWordBuff; i++) {
  630. if(i == iDisp_Top+iAddr)
  631. continue;
  632. if(wTemp == lpWord[i].wWord)
  633. break;
  634. }
  635. if(i != lWordBuff) {
  636. lcErrMsg(IDS_ERR_INPUTSAME);
  637. SetFocus(hwnd);
  638. return;
  639. }
  640. } else {
  641. len++;
  642. // Check DBCS
  643. for(i=0; i<len-1; i++) {
  644. if(szStr[i] ==_TEXT(' '))
  645. continue;
  646. if(!is_DBCS2(*((LPUNAWORD)(&szStr[i])), TRUE)) {
  647. SetFocus(hwndPhrase[iAddr]);
  648. return;
  649. }
  650. i++;
  651. }
  652. if(!lcDisp2Mem(iDisp_Top+iAddr, szStr))
  653. return;
  654. }
  655. SendMessage(hwnd, EM_SETMODIFY, FALSE, 0);
  656. }
  657. if(wID >= IDE_PHRASE_START) {
  658. isWord=FALSE;
  659. iAddr=wID-IDE_PHRASE_START;
  660. } else {
  661. isWord=TRUE;
  662. iAddr=wID-IDE_WORD_START;
  663. }
  664. if((iAddr >= (int)iPage_line) || (iAddr < 0))
  665. return; // Focus not in Edit Control
  666. // Check out of legal buffer
  667. if(iDisp_Top+iAddr >= lWordBuff) {
  668. MessageBeep(MB_OK);
  669. SetFocus(hwnd);
  670. return;
  671. }
  672. wOldID=wID;
  673. hwndFocus=isWord ? hwndWord[iAddr] : hwndPhrase[iAddr];
  674. }
  675. }
  676. BOOL lcRemoveDup( TCHAR *szBuf )
  677. {
  678. UINT len;
  679. UINT s;
  680. UINT i,cnt;
  681. TCHAR *szCurPos, *szStr;
  682. int unmatch;
  683. BOOL bModify=FALSE;
  684. if ( szBuf == 0 )
  685. return FALSE;
  686. len = (UINT)lstrlen(szBuf);
  687. // remove trailing blanks
  688. for ( ; len > 0 && szBuf[len-1] ==_TEXT(' '); szBuf[--len] = 0 );
  689. // remove leading blanks
  690. for ( s=0 ; s < len && szBuf[s] ==_TEXT(' '); s++ );
  691. if ( s > 0 )
  692. {
  693. #ifdef UNICODE
  694. memcpy( &szBuf[0], &szBuf[s], (len-s)<<1 );
  695. #else
  696. memcpy( &szBuf[0], &szBuf[s], len-s );
  697. #endif
  698. len -= s;
  699. szBuf[len]=0;
  700. }
  701. // return if len=0
  702. if ( len == 0 )
  703. return FALSE;
  704. // search from the end of string and remove duplicate phrase
  705. // s -> last char of target phrase
  706. for ( i=0, s=len-1 ; s > 0 ; )
  707. {
  708. // locate the range of current phrase
  709. for ( cnt=1 ; s>0 && szBuf[s-1] !=_TEXT(' ') ; s--, cnt++ );
  710. // s-> first char of target phrase
  711. // break if start from first char in buf)
  712. if (s==0)
  713. break;
  714. // check if we found another occurrence before the target string
  715. // match 1st char first, then match the rest of string
  716. // do until a match or end of buf
  717. for ( szStr=&szBuf[s], szCurPos=&szBuf[0], unmatch=1 ;
  718. szCurPos+cnt < szStr &&
  719. (*szCurPos != *szStr ||
  720. szCurPos[cnt] != _TEXT(' ') ||
  721. #ifdef UNICODE
  722. (unmatch=memcmp(szCurPos, szStr, cnt <<1))!=0) ; )
  723. #else
  724. (unmatch=memcmp(szCurPos, szStr, cnt))!=0) ; )
  725. #endif
  726. {
  727. // skip this phrase
  728. // skip non-blanks
  729. while ( *szCurPos !=0 && *szCurPos != _TEXT(' ')) szCurPos++;
  730. // skip blanks
  731. while ( *szCurPos !=0 && *szCurPos == _TEXT(' ')) szCurPos++;
  732. }
  733. // if found a string
  734. if ( unmatch == 0 )
  735. {
  736. // remove it and its trailing blanks
  737. while (szBuf[s+cnt]==_TEXT(' ')) cnt++;
  738. #ifdef UNICODE
  739. memmove(&szBuf[s], &szBuf[s+cnt], (len-s-cnt+1)<<1);
  740. #else
  741. memmove(&szBuf[s], &szBuf[s+cnt], len-s-cnt+1);
  742. #endif
  743. len -= cnt;
  744. bModify=TRUE;
  745. }
  746. // let s point to last byte of the previous string
  747. // skip blanks
  748. for ( s--; s>0 && (szBuf[s]==_TEXT(' ') || szBuf[s] ==0) ; s-- ) ;
  749. }
  750. return bModify;
  751. }
  752. BOOL lcDisp2Mem(
  753. UINT iAddr,
  754. TCHAR *szDispBuf)
  755. {
  756. LPPHRASEBUF Phrase;
  757. UINT i,j,len,iFree,iSave;
  758. // remove duplicate phrase
  759. if(lcRemoveDup(szDispBuf) && iAddr < MAX_LINE){
  760. SendMessage(hwndPhrase[iAddr],WM_SETTEXT,0,
  761. (LPARAM)(LPCTSTR)szDispBuf);
  762. };
  763. len=lstrlen(szDispBuf)+1;
  764. if((szDispBuf[len-1] == _TEXT(' ')) && (len > 1)) {
  765. szDispBuf[len-1]=0;
  766. len--;
  767. }
  768. if(len >= MAX_CHAR_NUM) { //tang must fix
  769. szDispBuf[MAX_CHAR_NUM-1]=0;
  770. #ifndef UNICODE
  771. if(is_DBCS_1st(szDispBuf, MAX_CHAR_NUM-2))
  772. szDispBuf[MAX_CHAR_NUM-2]=' ';
  773. #endif
  774. len=MAX_CHAR_NUM;
  775. }
  776. Phrase=&lpPhrase[lpWord[iAddr].lFirst_Seg];
  777. iSave=lpWord[iAddr].lFirst_Seg;
  778. for(i=0; i<((len-1)/SEGMENT_SIZE); i++) {
  779. #ifdef UNICODE
  780. CopyMemory(Phrase->szPhrase, &szDispBuf[i*SEGMENT_SIZE],SEGMENT_SIZE<< 1);
  781. #else
  782. CopyMemory(Phrase->szPhrase, &szDispBuf[i*SEGMENT_SIZE],SEGMENT_SIZE);
  783. #endif
  784. if(Phrase->lNext_Seg == NULL_SEG) {
  785. iFree=lcGetSeg();
  786. if(iFree == NULL_SEG)
  787. return FALSE;
  788. Phrase=&lpPhrase[iSave];
  789. Phrase->lNext_Seg=iFree;
  790. }
  791. iSave=Phrase->lNext_Seg;
  792. Phrase=&lpPhrase[Phrase->lNext_Seg];
  793. }
  794. for(j=0; j<SEGMENT_SIZE; j++) {
  795. Phrase->szPhrase[j]=szDispBuf[i*SEGMENT_SIZE+j];
  796. if(szDispBuf[i*SEGMENT_SIZE+j] == 0)
  797. break;
  798. }
  799. if(Phrase->lNext_Seg != NULL_SEG)
  800. lcFreeSeg(Phrase->lNext_Seg);
  801. Phrase->lNext_Seg=NULL_SEG;
  802. return TRUE;
  803. }
  804. UINT lcMem2Disp(
  805. UINT iAddr,
  806. TCHAR *szDispBuf)
  807. {
  808. LPPHRASEBUF Phrase;
  809. UINT i,len;
  810. Phrase=&lpPhrase[lpWord[iAddr].lFirst_Seg];
  811. for(i=0; Phrase->lNext_Seg != NULL_SEG; i+=SEGMENT_SIZE) {
  812. #ifdef UNICODE
  813. CopyMemory(&szDispBuf[i], Phrase->szPhrase, SEGMENT_SIZE << 1);
  814. #else
  815. CopyMemory(&szDispBuf[i], Phrase->szPhrase, SEGMENT_SIZE);
  816. #endif
  817. Phrase=&lpPhrase[Phrase->lNext_Seg];
  818. }
  819. szDispBuf[i] = 0;
  820. lstrcat(szDispBuf, Phrase->szPhrase);
  821. len=lstrlen(szDispBuf);
  822. if(szDispBuf[len] != _TEXT(' ')) {
  823. lstrcat(szDispBuf,_TEXT(" "));
  824. len+=1;
  825. }
  826. return len;
  827. }
  828. extern TCHAR szPhrasestr[MAX_CHAR_NUM];
  829. UINT nStartAddr = 0;
  830. UINT nStartPos = 0;
  831. void lcMoveEditWindowByWord(UINT nWords);
  832. LONG lcSearchMem(
  833. TCHAR *szSearchBuf)
  834. {
  835. UINT iAddr;
  836. TCHAR szDispBuf[MAX_CHAR_NUM];
  837. for (iAddr = nStartAddr; iAddr < lWordBuff; iAddr++) {
  838. lcMem2Disp(iAddr, szDispBuf);
  839. #ifdef UNICODE
  840. if (wcsstr(szDispBuf, szSearchBuf) != NULL) {
  841. #else
  842. if (strstr(szDispBuf, szSearchBuf) != NULL) {
  843. #endif
  844. return (LONG) iAddr;
  845. }
  846. }
  847. return -1;
  848. }
  849. void lcSearch(
  850. HWND hwnd, BOOL bNext)
  851. {
  852. UINT iDiff,iDisp_save;
  853. TCHAR szBuf[MAX_CHAR_NUM], *lpStr;
  854. BOOL is_WORD;
  855. int is_OK;
  856. LONG i;
  857. TCHAR szShowMsg[MAX_PATH];
  858. if(bNext && szPhrasestr[0] == 0) {
  859. MessageBeep(-1);
  860. return;
  861. }
  862. if(!lcSaveEditText(iDisp_Top, 0))
  863. return;
  864. iDisp_save=iDisp_Top;
  865. nStartAddr=lcGetEditFocus(GetFocus(), &is_WORD) + iDisp_Top;
  866. if (is_WORD) {
  867. nStartPos = 0;
  868. } else {
  869. SendMessage(hwndPhrase[nStartAddr - iDisp_Top],EM_GETSEL, 0, (LPARAM) (LPDWORD)&nStartPos);
  870. }
  871. if (!bNext) {
  872. is_OK=(int)DialogBox(hInst,
  873. _TEXT("SearchDialog"),
  874. hwndMain,
  875. (DLGPROC)SearchDialogProc);
  876. // Check cancel by user
  877. if(!is_OK) {
  878. SetFocus(hwndFocus);
  879. return;
  880. }
  881. }
  882. SendMessage(hwndPhrase[nStartAddr - iDisp_Top], WM_GETTEXT, (WPARAM)MAX_CHAR_NUM-1, (LPARAM)szBuf);
  883. #ifdef UNICODE
  884. lpStr = wcsstr(szBuf + nStartPos, szPhrasestr);
  885. #else
  886. lpStr = strstr(szBuf + nStartPos, szPhrasestr);
  887. #endif
  888. if (lpStr != NULL) {
  889. UINT nStart = (UINT)(lpStr - szBuf);
  890. UINT nEnd = nStart + lstrlen(szPhrasestr);
  891. SetFocus(hwndPhrase[nStartAddr - iDisp_Top]);
  892. SendMessage(hwndPhrase[nStartAddr - iDisp_Top], EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
  893. lcMoveEditWindowByWord(nStart);
  894. return;
  895. } else {
  896. nStartAddr++;
  897. }
  898. if((i = lcSearchMem(szPhrasestr)) == -1) {
  899. LoadString(hInst, IDS_ERR_PHRASE_NOT_FOUND,
  900. szShowMsg, sizeof(szShowMsg)/sizeof(TCHAR));
  901. MessageBox(hwnd, szShowMsg, NULL,
  902. MB_OK | MB_ICONEXCLAMATION);
  903. SetFocus(hwndFocus);
  904. return ;
  905. }
  906. iDisp_Top=(UINT)i;
  907. if(iDisp_Top > (lWordBuff-iPage_line)) {
  908. iDiff=iDisp_Top-lWordBuff+iPage_line;
  909. iDisp_Top=lWordBuff-iPage_line;
  910. SetFocus(hwndPhrase[iDiff]);
  911. } else {
  912. iDiff = 0;
  913. SetFocus(hwndPhrase[0]);
  914. }
  915. if(!lcSetEditText(iDisp_Top, FALSE))
  916. iDisp_Top=iDisp_save;
  917. yPos=iDisp_Top;
  918. SendMessage(hwndPhrase[iDiff], WM_GETTEXT, (WPARAM)MAX_CHAR_NUM-1, (LPARAM)szBuf);
  919. #ifdef UNICODE
  920. lpStr = wcsstr(szBuf, szPhrasestr);
  921. #else
  922. lpStr = strstr(szBuf, szPhrasestr);
  923. #endif
  924. if (lpStr != NULL) {
  925. UINT nStart = (UINT)(lpStr - szBuf);
  926. UINT nEnd = nStart + lstrlen(szPhrasestr);
  927. SendMessage(hwndPhrase[iDiff], EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
  928. lcMoveEditWindowByWord(nStart);
  929. }
  930. }
  931. INT_PTR FAR PASCAL SearchDialogProc(
  932. HWND hDlg,
  933. UINT message,
  934. WPARAM wParam,
  935. LPARAM lParam)
  936. {
  937. switch (message) {
  938. case WM_INITDIALOG:
  939. szPhrasestr[0]=0; //set to be null
  940. SetDlgItemText(hDlg,IDD_SEARCH_LINE,szPhrasestr);
  941. return TRUE;
  942. case WM_COMMAND:
  943. switch (wParam) {
  944. case IDOK:
  945. case IDB_OK:
  946. GetDlgItemText(hDlg,IDD_SEARCH_LINE,szPhrasestr, sizeof(szPhrasestr)/sizeof(TCHAR) );
  947. EndDialog (hDlg, TRUE) ;
  948. return TRUE;
  949. case IDB_CANCEL:
  950. case IDCANCEL:
  951. EndDialog (hDlg, FALSE) ;
  952. return TRUE;
  953. case IDD_INDEX_NAME:
  954. return TRUE;
  955. }
  956. break ;
  957. case WM_CLOSE:
  958. EndDialog(hDlg, FALSE);
  959. return TRUE;
  960. }
  961. return FALSE;
  962. }