Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9733 lines
312 KiB

  1. /*************************************************
  2. * abc95ui.c *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. #include <windows.h>
  8. #include <winerror.h>
  9. #include <winuser.h>
  10. #include <windowsx.h>
  11. #include <immdev.h>
  12. #include <stdio.h>
  13. #include <shlobj.h>
  14. #include "abc95def.h"
  15. #include "resource.h"
  16. #include "resrc1.h"
  17. #include "data.H"
  18. #define IME_CMODE_SDA 0x80000000
  19. HWND hCrtDlg = NULL;
  20. LONG lLock = 0; // this var is for Lock and unLock.
  21. void PASCAL ReInitIme2(HWND ,WORD);
  22. // Get the current user's EMB file path, and IME's MB path
  23. // fill global variable sImeG.szIMEUserPath
  24. void GetCurrentUserEMBPath( )
  25. {
  26. TCHAR szModuleName[MAX_PATH], *lpszStart, *lpszDot;
  27. int i;
  28. // Get the path for MB and EMB
  29. GetModuleFileName(hInst, szModuleName, sizeof(szModuleName)/sizeof(TCHAR) );
  30. lpszStart = szModuleName + lstrlen(szModuleName) - 1;
  31. while ( (lpszStart != szModuleName) && ( *lpszStart != TEXT('\\') ) ) {
  32. if ( *lpszStart == TEXT('.') ) {
  33. lpszDot = lpszStart;
  34. *lpszDot = TEXT('\0');
  35. }
  36. lpszStart --;
  37. }
  38. if ( *lpszStart == TEXT('\\') ) {
  39. lpszStart ++;
  40. }
  41. if ( lpszStart != szModuleName ) {
  42. for (i=0; i<lstrlen(lpszStart); i++)
  43. szModuleName[i] = lpszStart[i];
  44. szModuleName[i] = TEXT('\0');
  45. }
  46. SHGetSpecialFolderPath(NULL,sImeG.szIMEUserPath,CSIDL_APPDATA, FALSE);
  47. if ( sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath)-1] == TEXT('\\') )
  48. sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath) - 1] = TEXT('\0');
  49. // Because CreateDirectory( ) cannot create directory like \AA\BB,
  50. // if AA and BB both do not exist. It can create only one layer of
  51. // directory each time. so we must call twice CreateDirectory( ) for
  52. // \AA\BB
  53. lstrcat(sImeG.szIMEUserPath, TEXT("\\Microsoft") );
  54. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  55. CreateDirectory(sImeG.szIMEUserPath, NULL);
  56. lstrcat(sImeG.szIMEUserPath, TEXT("\\IME") );
  57. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  58. CreateDirectory(sImeG.szIMEUserPath, NULL);
  59. lstrcat(sImeG.szIMEUserPath, TEXT("\\") );
  60. lstrcat(sImeG.szIMEUserPath, szModuleName);
  61. //
  62. // Create the directory, so that CreateFile( ) can work fine later.
  63. // ortherwise, if the directory does not exist, and you try to create
  64. // a file under that dir, CreateFile will return error.
  65. //
  66. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  67. CreateDirectory(sImeG.szIMEUserPath, NULL);
  68. return;
  69. }
  70. //**************************************************************************
  71. //* Name : *
  72. //* void DrawConvexRect() *
  73. //* Description : *
  74. //* draw a convex rectangle *
  75. //* Parameters : *
  76. //* hDC - the handle of DC be drawed *
  77. //* (x1,y1) *
  78. //* +------------+ *
  79. //* |+----1----> | *
  80. //* ||2 x2-2| *
  81. //* |Vy2-2 | *
  82. //* | | *
  83. //* +------------+ *
  84. //* (x2,y2) *
  85. //* Return Value: *
  86. //* none *
  87. //**************************************************************************
  88. void DrawConvexRect(
  89. HDC hDC,
  90. int x1,
  91. int y1,
  92. int x2,
  93. int y2)
  94. {
  95. // draw the most outer color =light gray and black
  96. SelectObject(hDC,sImeG.LightGrayPen);
  97. MoveToEx(hDC, x1, y1,NULL);
  98. LineTo(hDC, x2-1, y1);
  99. MoveToEx(hDC, x1, y1,NULL);
  100. LineTo(hDC, x1, y2-1);
  101. SelectObject(hDC,sImeG.BlackPen); //GetStockObject(BLACK_PEN));
  102. MoveToEx(hDC, x1, y2,NULL);
  103. LineTo(hDC, x2+1, y2);
  104. MoveToEx(hDC, x2, y1,NULL);
  105. LineTo(hDC, x2, y2);
  106. // draw the second line color = white and grary
  107. SelectObject(hDC, sImeG.WhitePen); //GetStockObject(WHITE_PEN));
  108. MoveToEx(hDC, x1+1, y1+1,NULL);
  109. LineTo(hDC, x2-1, y1+1);
  110. MoveToEx(hDC, x1+1, y1+1,NULL);
  111. LineTo(hDC, x1+1, y2-1);
  112. SelectObject(hDC,sImeG.GrayPen);
  113. MoveToEx(hDC, x1+1, y2-1,NULL);
  114. LineTo(hDC, x2, y2-1);
  115. MoveToEx(hDC, x2-1, y1+1,NULL);
  116. LineTo(hDC, x2-1, y2-1);
  117. // draw the fourth line color = gray and white
  118. SelectObject(hDC,sImeG.GrayPen); // CreatePen(PS_SOLID, 1, 0x00808080));
  119. MoveToEx(hDC, x1+3, y1+3,NULL);
  120. LineTo(hDC, x2-3, y1+3);
  121. MoveToEx(hDC, x1+3, y1+3,NULL);
  122. LineTo(hDC, x1+3, y2-3);
  123. SelectObject(hDC, sImeG.WhitePen);
  124. MoveToEx(hDC, x1+3, y2-3,NULL);
  125. LineTo(hDC, x2-2, y2-3);
  126. MoveToEx(hDC, x2-3, y1+3,NULL);
  127. LineTo(hDC, x2-3, y2-3);
  128. }
  129. //**************************************************************************
  130. //* Name : *
  131. //* void DrawConcaveRect() *
  132. //* Description : *
  133. //* draw a concave rectangle *
  134. //* Parameters : *
  135. //* hDC - the handle of DC be drawed *
  136. //* (x1,y1) x2-1 *
  137. //* +-----1----->+ *
  138. //* | ^ y1+1 *
  139. //* 2 | *
  140. //* | 3 *
  141. //* y2-1 V | *
  142. //* <-----4------+ *
  143. //* x1 (x2,y2) *
  144. //* Return Value: *
  145. //* none *
  146. //**************************************************************************
  147. void DrawStatusRect(
  148. HDC hDC,
  149. int x1,
  150. int y1,
  151. int x2,
  152. int y2)
  153. {
  154. SelectObject(hDC,sImeG.LightGrayPen);
  155. MoveToEx(hDC, x1, y1,NULL);
  156. LineTo(hDC, x2-1, y1);
  157. MoveToEx(hDC, x1, y1,NULL);
  158. LineTo(hDC, x1, y2-1);
  159. SelectObject(hDC,sImeG.BlackPen); //GetStockObject(BLACK_PEN));
  160. MoveToEx(hDC, x1, y2,NULL);
  161. LineTo(hDC, x2+1, y2);
  162. MoveToEx(hDC, x2, y1,NULL);
  163. LineTo(hDC, x2, y2);
  164. // draw the second line color = white and grary
  165. SelectObject(hDC, sImeG.WhitePen); //GetStockObject(WHITE_PEN));
  166. MoveToEx(hDC, x1+1, y1+1,NULL);
  167. LineTo(hDC, x2-1, y1+1);
  168. MoveToEx(hDC, x1+1, y1+1,NULL);
  169. LineTo(hDC, x1+1, y2-1);
  170. SelectObject(hDC,sImeG.GrayPen);
  171. MoveToEx(hDC, x1+1, y2-1,NULL);
  172. LineTo(hDC, x2, y2-1);
  173. MoveToEx(hDC, x2-1, y1+1,NULL);
  174. LineTo(hDC, x2-1, y2-1);
  175. }
  176. /**********************************************************************/
  177. /* ShowBitmap2() */
  178. /* a subprgm for ShowBitmap */
  179. /**********************************************************************/
  180. void ShowBitmap2(
  181. HDC hDC,
  182. int x,
  183. int y,
  184. int Wi,
  185. int Hi,
  186. HBITMAP hBitmap)
  187. {
  188. HDC hMemDC ;
  189. HBITMAP hOldBmp;
  190. hMemDC = CreateCompatibleDC(hDC);
  191. if ( hMemDC == NULL )
  192. return;
  193. hOldBmp = SelectObject(hMemDC, hBitmap);
  194. BitBlt(hDC,
  195. x,
  196. y,
  197. Wi,
  198. Hi,
  199. hMemDC,
  200. 0,
  201. 0,
  202. SRCCOPY);
  203. SelectObject(hMemDC, hOldBmp);
  204. DeleteDC(hMemDC);
  205. return ;
  206. }
  207. /**********************************************************************/
  208. /* ShowBitmap() */
  209. /**********************************************************************/
  210. void ShowBitmap(
  211. HDC hDC,
  212. int x,
  213. int y,
  214. int Wi,
  215. int Hi,
  216. LPSTR BitmapName)
  217. {
  218. HBITMAP hBitmap ;
  219. hBitmap = LoadBitmap(hInst, BitmapName);
  220. if ( hBitmap )
  221. {
  222. ShowBitmap2(hDC, x,y,Wi,Hi,hBitmap);
  223. DeleteObject(hBitmap);
  224. }
  225. return ;
  226. }
  227. /**********************************************************************/
  228. /* CreateUIWindow() */
  229. /**********************************************************************/
  230. void PASCAL CreateUIWindow( // create composition window
  231. HWND hUIWnd)
  232. {
  233. HGLOBAL hUIPrivate;
  234. // create storage for UI setting
  235. hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
  236. if (!hUIPrivate) { // Oh! Oh!
  237. return;
  238. }
  239. SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);
  240. // set the default position for UI window, it is hide now
  241. SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);
  242. ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);
  243. return;
  244. }
  245. //ui.c skd #5
  246. /**********************************************************************/
  247. /* ShowSoftKbd */
  248. /**********************************************************************/
  249. void PASCAL ShowSoftKbd( // Show the soft keyboard window
  250. HWND hUIWnd,
  251. int nShowSoftKbdCmd)
  252. {
  253. HIMC hIMC;
  254. LPINPUTCONTEXT lpIMC;
  255. HGLOBAL hUIPrivate;
  256. LPUIPRIV lpUIPrivate;
  257. LPPRIVCONTEXT lpImcP;
  258. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  259. if (!hUIPrivate) { // can not darw status window
  260. return;
  261. }
  262. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  263. if (!lpUIPrivate) { // can not draw status window
  264. return;
  265. }
  266. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  267. if (!hIMC)
  268. return;
  269. lpIMC =(LPINPUTCONTEXT)ImmLockIMC(hIMC);
  270. if (!lpIMC)
  271. return;
  272. lpImcP =(LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  273. if (!lpImcP){
  274. ImmUnlockIMC(hIMC);
  275. return;
  276. }
  277. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL1, MF_UNCHECKED);
  278. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL2, MF_UNCHECKED);
  279. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL3, MF_UNCHECKED);
  280. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL4, MF_UNCHECKED);
  281. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL5, MF_UNCHECKED);
  282. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL6, MF_UNCHECKED);
  283. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL7, MF_UNCHECKED);
  284. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL8, MF_UNCHECKED);
  285. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL9, MF_UNCHECKED);
  286. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL10, MF_UNCHECKED);
  287. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL11, MF_UNCHECKED);
  288. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL12, MF_UNCHECKED);
  289. CheckMenuItem(lpImeL->hSKMenu, IDM_SKL13, MF_UNCHECKED);
  290. if (!lpUIPrivate->hSoftKbdWnd) {
  291. // not in show status window mode
  292. } else if (lpUIPrivate->nShowSoftKbdCmd != nShowSoftKbdCmd) {
  293. ImmShowSoftKeyboard(lpUIPrivate->hSoftKbdWnd, nShowSoftKbdCmd);
  294. if (nShowSoftKbdCmd != SW_HIDE){
  295. SendMessage(lpUIPrivate->hSoftKbdWnd,WM_PAINT,0,0l);
  296. ReDrawSdaKB(hIMC, lpImeL->dwSKWant, nShowSoftKbdCmd);
  297. }
  298. lpUIPrivate->nShowSoftKbdCmd = nShowSoftKbdCmd;
  299. lpImcP->nShowSoftKbdCmd = nShowSoftKbdCmd;
  300. if(!(lpImcP == NULL)) {
  301. if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
  302. if(!(lpImeL->hSKMenu)) {
  303. lpImeL->hSKMenu = LoadMenu (hInst, "SKMENU");
  304. }
  305. CheckMenuItem(lpImeL->hSKMenu,
  306. lpImeL->dwSKWant + IDM_SKL1, MF_CHECKED);
  307. }
  308. }
  309. }
  310. ImmUnlockIMCC(lpIMC->hPrivate);
  311. ImmUnlockIMC(hIMC);
  312. GlobalUnlock(hUIPrivate);
  313. return;
  314. }
  315. /**********************************************************************/
  316. /* ChangeCompositionSize() */
  317. /**********************************************************************/
  318. void PASCAL ChangeCompositionSize(
  319. HWND hUIWnd)
  320. {
  321. HWND hCompWnd, hCandWnd;
  322. RECT rcWnd;
  323. UINT nMaxKey;
  324. HIMC hIMC;
  325. LPINPUTCONTEXT lpIMC;
  326. hCompWnd = GetCompWnd(hUIWnd);
  327. if (!hCompWnd) {
  328. return;
  329. }
  330. GetWindowRect(hCompWnd, &rcWnd);
  331. if ((rcWnd.right - rcWnd.left) != lpImeL->xCompWi) {
  332. } else if ((rcWnd.bottom - rcWnd.top) != lpImeL->yCompHi) {
  333. } else {
  334. return;
  335. }
  336. SetWindowPos(hCompWnd, NULL,
  337. 0, 0, lpImeL->xCompWi, lpImeL->yCompHi,
  338. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
  339. if (lpImeL->nRevMaxKey >= lpImeL->nMaxKey) {
  340. nMaxKey = lpImeL->nRevMaxKey;
  341. } else {
  342. nMaxKey = lpImeL->nMaxKey;
  343. }
  344. SetWindowLong(hCompWnd, UI_MOVE_XY, nMaxKey);
  345. // if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  346. // return;
  347. // }
  348. hCandWnd = GetCandWnd(hUIWnd);
  349. if (!hCandWnd) {
  350. return;
  351. }
  352. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  353. if (!hIMC) {
  354. return;
  355. }
  356. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  357. if (!lpIMC) {
  358. return;
  359. }
  360. CalcCandPos((LPPOINT)&rcWnd);
  361. ImmUnlockIMC(hIMC);
  362. SetWindowPos(hCandWnd, NULL,
  363. rcWnd.left, rcWnd.top,
  364. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  365. return;
  366. }
  367. /**********************************************************************/
  368. /* ShowUI() */
  369. /**********************************************************************/
  370. void PASCAL ShowUI( // show the sub windows
  371. HWND hUIWnd,
  372. int nShowCmd)
  373. {
  374. HIMC hIMC;
  375. LPINPUTCONTEXT lpIMC;
  376. LPPRIVCONTEXT lpImcP;
  377. HGLOBAL hUIPrivate;
  378. LPUIPRIV lpUIPrivate;
  379. if (nShowCmd == SW_HIDE) {
  380. } else if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))) {
  381. nShowCmd = SW_HIDE;
  382. } else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  383. nShowCmd = SW_HIDE;
  384. } else if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
  385. ImmUnlockIMC(hIMC);
  386. nShowCmd = SW_HIDE;
  387. } else {
  388. }
  389. if (nShowCmd == SW_HIDE) {
  390. ShowStatus(
  391. hUIWnd, nShowCmd);
  392. ShowComp(
  393. hUIWnd, nShowCmd);
  394. ShowCand(
  395. hUIWnd, nShowCmd);
  396. ShowSoftKbd(hUIWnd, nShowCmd);
  397. return;
  398. }
  399. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  400. if (!hUIPrivate) { // can not darw status window
  401. goto ShowUIUnlockIMCC;
  402. }
  403. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  404. if (!lpUIPrivate) { // can not draw status window
  405. goto ShowUIUnlockIMCC;
  406. }
  407. if( /*(lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW)&& */
  408. (lpImcP->fdwImeMsg & MSG_ALREADY_START)
  409. && (step_mode &1)){
  410. if (lpUIPrivate->hCompWnd) {
  411. if ((UINT)GetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY) !=
  412. lpImeL->nRevMaxKey) {
  413. ChangeCompositionSize(hUIWnd);
  414. }
  415. if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
  416. // some time the WM_NCPAINT is eaten by the app
  417. // RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
  418. // RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  419. }
  420. SendMessage(lpUIPrivate->hCompWnd, WM_IME_NOTIFY,
  421. IMN_SETCOMPOSITIONWINDOW, 0);
  422. if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
  423. ShowComp(hUIWnd, nShowCmd);
  424. }
  425. } else {
  426. StartComp(hUIWnd);
  427. }
  428. } else if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
  429. } else {
  430. ShowComp(hUIWnd, SW_HIDE);
  431. }
  432. if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW) &&
  433. (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)&&(step_mode == 1)) {
  434. if (lpUIPrivate->hCandWnd) {
  435. if (lpUIPrivate->nShowCandCmd != SW_HIDE) {
  436. // some time the WM_NCPAINT is eaten by the app
  437. RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
  438. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  439. }
  440. SendMessage(lpUIPrivate->hCandWnd, WM_IME_NOTIFY,
  441. IMN_SETCANDIDATEPOS, 0x0001);
  442. if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
  443. ShowCand(hUIWnd, nShowCmd);
  444. }
  445. } else {
  446. OpenCand(hUIWnd);
  447. }
  448. } else if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
  449. } else {
  450. ShowCand(hUIWnd, SW_HIDE);
  451. }
  452. if (lpIMC->fdwInit & INIT_SENTENCE) {
  453. // app set the sentence mode so we should not change it
  454. // with the configure option set by end user
  455. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
  456. if ((WORD)lpIMC->fdwSentence != IME_SMODE_PHRASEPREDICT) {
  457. DWORD fdwSentence;
  458. fdwSentence = lpIMC->fdwSentence;
  459. *(LPUNAWORD)&fdwSentence = IME_SMODE_PHRASEPREDICT;
  460. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  461. }
  462. } else {
  463. if ((WORD)lpIMC->fdwSentence == IME_SMODE_PHRASEPREDICT) {
  464. DWORD fdwSentence;
  465. fdwSentence = lpIMC->fdwSentence;
  466. *(LPUNAWORD)&fdwSentence = IME_SMODE_NONE;
  467. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  468. }
  469. }
  470. if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  471. if (!lpUIPrivate->hStatusWnd) {
  472. OpenStatus(hUIWnd);
  473. }
  474. if (lpUIPrivate->nShowStatusCmd != SW_HIDE) {
  475. // some time the WM_NCPAINT is eaten by the app
  476. RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
  477. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  478. }
  479. SendMessage(lpUIPrivate->hStatusWnd, WM_IME_NOTIFY,
  480. IMN_SETSTATUSWINDOWPOS, 0);
  481. if (lpUIPrivate->nShowStatusCmd == SW_HIDE) {
  482. ShowStatus(hUIWnd, nShowCmd);
  483. }
  484. else // add for bug 34131, a-zhanw, 1996-4-15
  485. ShowStatus(hUIWnd, nShowCmd);
  486. } else if (lpUIPrivate->hStatusWnd)
  487. DestroyWindow(lpUIPrivate->hStatusWnd);
  488. if (!lpIMC->fOpen) {
  489. if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
  490. ShowSoftKbd(hUIWnd, SW_HIDE);
  491. }
  492. } else if ((lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) &&
  493. (lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
  494. if (!lpUIPrivate->hSoftKbdWnd) {
  495. UpdateSoftKbd(hUIWnd);
  496. } else if ((UINT)SendMessage(lpUIPrivate->hSoftKbdWnd,
  497. WM_IME_CONTROL, IMC_GETSOFTKBDSUBTYPE, 0) !=
  498. lpImeL->nReadLayout) {
  499. UpdateSoftKbd(hUIWnd);
  500. } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  501. ShowSoftKbd(hUIWnd, nShowCmd);
  502. } else if (lpUIPrivate->hIMC != hIMC) {
  503. UpdateSoftKbd(hUIWnd);
  504. } else {
  505. RedrawWindow(lpUIPrivate->hSoftKbdWnd, NULL, NULL,
  506. RDW_FRAME|RDW_INVALIDATE);
  507. }
  508. } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  509. } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  510. lpUIPrivate->fdwSetContext |= ISC_HIDE_SOFTKBD;
  511. ShowSoftKbd(hUIWnd, SW_HIDE);
  512. } else {
  513. ShowSoftKbd(hUIWnd, SW_HIDE);
  514. }
  515. // we switch to this hIMC
  516. lpUIPrivate->hIMC = hIMC;
  517. GlobalUnlock(hUIPrivate);
  518. ShowUIUnlockIMCC:
  519. ImmUnlockIMCC(lpIMC->hPrivate);
  520. ImmUnlockIMC(hIMC);
  521. return;
  522. }
  523. /**********************************************************************/
  524. /* MoveCompCand() */
  525. /**********************************************************************/
  526. void PASCAL MoveCompCand( // show the sub windows
  527. HWND hUIWnd)
  528. {
  529. HIMC hIMC;
  530. LPINPUTCONTEXT lpIMC;
  531. LPPRIVCONTEXT lpImcP;
  532. if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC)))
  533. return;
  534. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)))
  535. return ;
  536. if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
  537. ImmUnlockIMC(hIMC);
  538. return ;
  539. }
  540. {
  541. HGLOBAL hUIPrivate;
  542. LPUIPRIV lpUIPrivate;
  543. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  544. if (!hUIPrivate) { // Oh! Oh!
  545. return;
  546. }
  547. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  548. if (!lpUIPrivate) { // Oh! Oh!
  549. return;
  550. }
  551. // composition window need to be destroyed
  552. if (lpUIPrivate->hCandWnd) {
  553. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)
  554. MoveWindow(lpUIPrivate->hCandWnd,
  555. lpImeL->ptDefCand.x,
  556. lpImeL->ptDefCand.y,
  557. sImeG.xCandWi,
  558. sImeG.yCandHi,
  559. TRUE);
  560. }
  561. // candidate window need to be destroyed
  562. if (lpUIPrivate->hCompWnd) {
  563. if (lpImcP->fdwImeMsg & MSG_ALREADY_START)
  564. MoveWindow(
  565. lpUIPrivate->hCompWnd,
  566. lpImeL->ptDefComp.x,
  567. lpImeL->ptDefComp.y,
  568. lpImeL->xCompWi,lpImeL->yCompHi,
  569. TRUE );
  570. }
  571. GlobalUnlock(hUIPrivate);
  572. }
  573. ImmUnlockIMCC(lpIMC->hPrivate);
  574. ImmUnlockIMC(hIMC);
  575. return;
  576. }
  577. /**********************************************************************/
  578. /* CheckSoftKbdPosition() */
  579. /**********************************************************************/
  580. void PASCAL CheckSoftKbdPosition(
  581. LPUIPRIV lpUIPrivate,
  582. LPINPUTCONTEXT lpIMC)
  583. {
  584. UINT fPortionBits = 0;
  585. UINT fPortionTest;
  586. int xPortion, yPortion, nPortion;
  587. RECT rcWnd;
  588. // portion of dispaly
  589. // 0 1
  590. // 2 3
  591. if (lpUIPrivate->hCompWnd) {
  592. GetWindowRect(lpUIPrivate->hCompWnd, &rcWnd);
  593. if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
  594. xPortion = 1;
  595. } else {
  596. xPortion = 0;
  597. }
  598. if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
  599. yPortion = 1;
  600. } else {
  601. yPortion = 0;
  602. }
  603. fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
  604. }
  605. if (lpUIPrivate->hStatusWnd) {
  606. GetWindowRect(lpUIPrivate->hStatusWnd, &rcWnd);
  607. if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
  608. xPortion = 1;
  609. } else {
  610. xPortion = 0;
  611. }
  612. if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
  613. yPortion = 1;
  614. } else {
  615. yPortion = 0;
  616. }
  617. fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
  618. }
  619. GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);
  620. // start from portion 3
  621. for (nPortion = 3, fPortionTest = 0x0008; fPortionTest;
  622. nPortion--, fPortionTest >>= 1) {
  623. if (fPortionTest & fPortionBits) {
  624. // someone here!
  625. continue;
  626. }
  627. if (nPortion % 2) {
  628. lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.right -
  629. (rcWnd.right - rcWnd.left) - UI_MARGIN;
  630. } else {
  631. lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.left;
  632. }
  633. if (nPortion / 2) {
  634. lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.bottom -
  635. (rcWnd.bottom - rcWnd.top) - UI_MARGIN;
  636. } else {
  637. lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.top;
  638. }
  639. lpIMC->fdwInit |= INIT_SOFTKBDPOS;
  640. break;
  641. }
  642. return;
  643. }
  644. // sdk #6
  645. /**********************************************************************/
  646. /* SetSoftKbdData() */
  647. /**********************************************************************/
  648. void PASCAL SetSoftKbdData(
  649. HWND hSoftKbdWnd,
  650. LPINPUTCONTEXT lpIMC)
  651. {
  652. int i;
  653. LPSOFTKBDDATA lpSoftKbdData;
  654. LPPRIVCONTEXT lpImcP;
  655. HGLOBAL hsSoftKbdData;
  656. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  657. if (!lpImcP) {
  658. return;
  659. }
  660. hsSoftKbdData = GlobalAlloc(GHND, sizeof(SOFTKBDDATA) * 2);
  661. if (!hsSoftKbdData) {
  662. ImmUnlockIMCC(lpIMC->hPrivate);
  663. return;
  664. }
  665. lpSoftKbdData = (LPSOFTKBDDATA)GlobalLock(hsSoftKbdData);
  666. if (!lpSoftKbdData) { // can not draw soft keyboard window
  667. ImmUnlockIMCC(lpIMC->hPrivate);
  668. return;
  669. }
  670. lpSoftKbdData->uCount = 2;
  671. for (i = 0; i < 48; i++) {
  672. BYTE bVirtKey;
  673. bVirtKey = VirtKey48Map[i];
  674. if (!bVirtKey) {
  675. continue;
  676. }
  677. {
  678. WORD CHIByte, CLOByte;
  679. CHIByte = SKLayout[lpImeL->dwSKWant][i*2] & 0x00ff;
  680. CLOByte = SKLayout[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
  681. lpSoftKbdData->wCode[0][bVirtKey] = (CHIByte << 8) | CLOByte;
  682. CHIByte = SKLayoutS[lpImeL->dwSKWant][i*2] & 0x00ff;
  683. CLOByte = SKLayoutS[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
  684. lpSoftKbdData->wCode[1][bVirtKey] = (CHIByte << 8) | CLOByte;
  685. }
  686. }
  687. SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDDATA,
  688. (LPARAM)lpSoftKbdData);
  689. GlobalUnlock(hsSoftKbdData);
  690. // free storage for UI settings
  691. GlobalFree(hsSoftKbdData);
  692. ImmUnlockIMCC(lpIMC->hPrivate);
  693. return;
  694. }
  695. //sdk #7
  696. /**********************************************************************/
  697. /* UpdateSoftKbd() */
  698. /**********************************************************************/
  699. void PASCAL UpdateSoftKbd(
  700. HWND hUIWnd)
  701. {
  702. HIMC hIMC;
  703. LPINPUTCONTEXT lpIMC;
  704. HGLOBAL hUIPrivate;
  705. LPUIPRIV lpUIPrivate;
  706. LPPRIVCONTEXT lpImcP;
  707. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  708. if (!hIMC) {
  709. return;
  710. }
  711. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  712. if (!lpIMC) {
  713. return;
  714. }
  715. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  716. if (!lpImcP){
  717. ImmUnlockIMC(hIMC);
  718. return;
  719. }
  720. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  721. if (!hUIPrivate) { // can not darw soft keyboard window
  722. ImmUnlockIMCC(lpIMC->hPrivate);
  723. ImmUnlockIMC(hIMC);
  724. return;
  725. }
  726. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  727. if (!lpUIPrivate) { // can not draw soft keyboard window
  728. ImmUnlockIMCC(lpIMC->hPrivate);
  729. ImmUnlockIMC(hIMC);
  730. return;
  731. }
  732. if (!(lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
  733. if (lpUIPrivate->hSoftKbdWnd) {
  734. ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
  735. lpImcP->hSoftKbdWnd = NULL;
  736. lpUIPrivate->hSoftKbdWnd = NULL;
  737. }
  738. lpUIPrivate->nShowSoftKbdCmd = SW_HIDE;
  739. lpImcP->nShowSoftKbdCmd = SW_HIDE;
  740. } else if (!lpIMC->fOpen) {
  741. if (lpUIPrivate->nShowSoftKbdCmd != SW_HIDE) {
  742. ShowSoftKbd(hUIWnd, SW_HIDE/*, NULL*/);
  743. }
  744. } else {
  745. if (!lpUIPrivate->hSoftKbdWnd) {
  746. // create soft keyboard
  747. lpUIPrivate->hSoftKbdWnd =
  748. ImmCreateSoftKeyboard(SOFTKEYBOARD_TYPE_C1, hUIWnd,
  749. 0, 0);
  750. lpImcP->hSoftKbdWnd = lpUIPrivate->hSoftKbdWnd;
  751. }
  752. if (!(lpIMC->fdwInit & INIT_SOFTKBDPOS)) {
  753. CheckSoftKbdPosition(lpUIPrivate, lpIMC);
  754. }
  755. SetSoftKbdData(lpUIPrivate->hSoftKbdWnd, lpIMC);
  756. if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  757. SetWindowPos(lpUIPrivate->hSoftKbdWnd, NULL,
  758. lpIMC->ptSoftKbdPos.x, lpIMC->ptSoftKbdPos.y,
  759. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  760. // only show, if the application want to show it
  761. //if (lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) { //zst 95/9/28
  762. ShowSoftKbd(hUIWnd, SW_SHOWNOACTIVATE/*, lpImcP*/);
  763. // } zst 95/9/28
  764. }
  765. }
  766. GlobalUnlock(hUIPrivate);
  767. ImmUnlockIMCC(lpIMC->hPrivate);
  768. ImmUnlockIMC(hIMC);
  769. return;
  770. }
  771. /**********************************************************************/
  772. /* ShowGuideLine */
  773. /**********************************************************************/
  774. void PASCAL ShowGuideLine(
  775. HWND hUIWnd)
  776. {
  777. HIMC hIMC;
  778. LPINPUTCONTEXT lpIMC;
  779. LPGUIDELINE lpGuideLine;
  780. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  781. if (!hIMC) {
  782. return;
  783. }
  784. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  785. if (!lpIMC) {
  786. return;
  787. }
  788. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  789. if (!lpGuideLine) {
  790. } else if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
  791. MessageBeep((UINT)-1);
  792. MessageBeep((UINT)-1);
  793. } else if (lpGuideLine->dwLevel == GL_LEVEL_WARNING) {
  794. MessageBeep((UINT)-1);
  795. } else {
  796. }
  797. ImmUnlockIMCC(lpIMC->hGuideLine);
  798. ImmUnlockIMC(hIMC);
  799. return;
  800. }
  801. /**********************************************************************/
  802. /* StatusWndMsg() */
  803. /**********************************************************************/
  804. void PASCAL StatusWndMsg( // set the show hide state and
  805. HWND hUIWnd,
  806. BOOL fOn)
  807. {
  808. HGLOBAL hUIPrivate;
  809. HIMC hIMC;
  810. HWND hStatusWnd;
  811. register LPUIPRIV lpUIPrivate;
  812. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  813. if (!hUIPrivate) {
  814. return;
  815. }
  816. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  817. if (!lpUIPrivate) {
  818. return;
  819. }
  820. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  821. if(!hIMC){
  822. return;
  823. }
  824. if (fOn) {
  825. lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
  826. if (!lpUIPrivate->hStatusWnd) {
  827. OpenStatus(
  828. hUIWnd);
  829. }
  830. } else {
  831. lpUIPrivate->fdwSetContext &= ~(ISC_OPEN_STATUS_WINDOW);
  832. }
  833. hStatusWnd = lpUIPrivate->hStatusWnd;
  834. GlobalUnlock(hUIPrivate);
  835. if (!hStatusWnd) {
  836. return;
  837. }
  838. if (!fOn) {
  839. register DWORD fdwSetContext;
  840. /*
  841. fdwSetContext = lpUIPrivate->fdwSetContext &
  842. (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);
  843. if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
  844. ShowComp(
  845. hUIWnd, SW_HIDE);
  846. }
  847. fdwSetContext = lpUIPrivate->fdwSetContext &
  848. (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);
  849. if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
  850. ShowCand(
  851. hUIWnd, SW_HIDE);
  852. }
  853. fdwSetContext = lpUIPrivate->fdwSetContext &
  854. (ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);
  855. if (fdwSetContext == ISC_HIDE_SOFTKBD) {
  856. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
  857. ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
  858. }
  859. ShowStatus(
  860. hUIWnd, SW_HIDE);
  861. */
  862. ShowComp(hUIWnd, SW_HIDE);
  863. ShowCand(hUIWnd, SW_HIDE);
  864. // ShowSoftKbd(hUIWnd, SW_HIDE);
  865. fdwSetContext = lpUIPrivate->fdwSetContext &
  866. (ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);
  867. if (fdwSetContext == ISC_HIDE_SOFTKBD) {
  868. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
  869. ShowSoftKbd(hUIWnd, SW_HIDE);
  870. }
  871. ShowStatus(hUIWnd, SW_HIDE);
  872. } else if (hIMC) {
  873. ShowStatus(
  874. hUIWnd, SW_SHOWNOACTIVATE);
  875. } else {
  876. ShowStatus(
  877. hUIWnd, SW_HIDE);
  878. }
  879. return;
  880. }
  881. /**********************************************************************/
  882. /* NotifyUI() */
  883. /**********************************************************************/
  884. void PASCAL NotifyUI(
  885. HWND hUIWnd,
  886. WPARAM wParam,
  887. LPARAM lParam)
  888. {
  889. HWND hStatusWnd;
  890. switch (wParam) {
  891. case IMN_OPENSTATUSWINDOW:
  892. StatusWndMsg(hUIWnd, TRUE);
  893. break;
  894. case IMN_CLOSESTATUSWINDOW:
  895. StatusWndMsg(hUIWnd, FALSE);
  896. break;
  897. case IMN_OPENCANDIDATE:
  898. if (lParam & 0x00000001) {
  899. OpenCand(hUIWnd);
  900. }
  901. break;
  902. case IMN_CHANGECANDIDATE:
  903. if (lParam & 0x00000001) {
  904. HWND hCandWnd;
  905. HDC hDC;
  906. hCandWnd = GetCandWnd(hUIWnd);
  907. if (!hCandWnd) {
  908. return;
  909. }
  910. hDC = GetDC(hCandWnd);
  911. UpdateCandWindow2(hCandWnd, hDC);
  912. ReleaseDC(hCandWnd, hDC);
  913. }
  914. break;
  915. case IMN_CLOSECANDIDATE:
  916. if (lParam & 0x00000001) {
  917. CloseCand(hUIWnd);
  918. }
  919. break;
  920. case IMN_SETSENTENCEMODE:
  921. break;
  922. case IMN_SETCONVERSIONMODE:
  923. case IMN_SETOPENSTATUS:
  924. hStatusWnd = GetStatusWnd(hUIWnd);
  925. if (hStatusWnd) {
  926. InvalidateRect(hStatusWnd, &sImeG.rcStatusText, FALSE);
  927. UpdateWindow(hStatusWnd);
  928. }
  929. break;
  930. case IMN_SETCOMPOSITIONFONT:
  931. // we are not going to change font, but an IME can do this if it want
  932. break;
  933. case IMN_SETCOMPOSITIONWINDOW:
  934. SetCompWindow(hUIWnd);
  935. break;
  936. case IMN_SETSTATUSWINDOWPOS:
  937. // SetStatusWindowPos(hUIWnd);
  938. SetStatusWindowPos(GetStatusWnd(hUIWnd));
  939. break;
  940. case IMN_GUIDELINE:
  941. ShowGuideLine(hUIWnd);
  942. break;
  943. case IMN_PRIVATE:
  944. switch (lParam) {
  945. case IMN_PRIVATE_UPDATE_SOFTKBD:
  946. UpdateSoftKbd(hUIWnd);
  947. break;
  948. default:
  949. break;
  950. }
  951. break;
  952. default:
  953. break;
  954. }
  955. return;
  956. }
  957. /**********************************************************************/
  958. /* SetContext() */
  959. /**********************************************************************/
  960. void PASCAL SetContext( // the context activated/deactivated
  961. HWND hUIWnd,
  962. BOOL fOn,
  963. LPARAM lShowUI)
  964. {
  965. HGLOBAL hUIPrivate;
  966. register LPUIPRIV lpUIPrivate;
  967. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  968. if (!hUIPrivate) {
  969. return;
  970. }
  971. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  972. if (!lpUIPrivate) {
  973. return;
  974. }
  975. if (fOn) {
  976. HIMC hIMC;
  977. LPINPUTCONTEXT lpIMC;
  978. if(!sImeG.Prop)
  979. InitUserSetting();
  980. ReInitIme2(lpUIPrivate->hStatusWnd, lpImeL->wImeStyle);
  981. lpUIPrivate->fdwSetContext = (lpUIPrivate->fdwSetContext &
  982. ~ISC_SHOWUIALL) | ((DWORD)lShowUI & ISC_SHOWUIALL) | ISC_SHOW_SOFTKBD;
  983. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  984. if (!hIMC) {
  985. goto SetCxtUnlockUIPriv;
  986. }
  987. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  988. if (!lpIMC) {
  989. goto SetCxtUnlockUIPriv;
  990. }
  991. if (lpIMC->cfCandForm[0].dwIndex != 0) {
  992. lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
  993. }
  994. ImmUnlockIMC(hIMC);
  995. } else {
  996. lpUIPrivate->fdwSetContext &= ~ISC_SETCONTEXT_UI;
  997. }
  998. if(fOn){
  999. BOOL x;
  1000. HIMC hIMC;
  1001. LPINPUTCONTEXT lpIMC;
  1002. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1003. if (!hIMC) {
  1004. goto SetCxtUnlockUIPriv;
  1005. }
  1006. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1007. if (!lpIMC)
  1008. goto SetCxtUnlockUIPriv;
  1009. x = GetKeyState(VK_CAPITAL)&1;
  1010. if(!x && (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION)){
  1011. lpIMC->fdwConversion = lpIMC->fdwConversion & (~IME_CMODE_NOCONVERSION)|IME_CMODE_NATIVE;
  1012. }
  1013. if(x && (lpIMC->fdwConversion & IME_CMODE_NATIVE)){
  1014. lpIMC->fdwConversion = lpIMC->fdwConversion & (~IME_CMODE_NATIVE) |(IME_CMODE_NOCONVERSION);
  1015. InitCvtPara();
  1016. }
  1017. //lpIMC->fdwConversion = IME_CMODE_NOCONVERSION;
  1018. ImmUnlockIMC(hIMC);
  1019. }
  1020. SetCxtUnlockUIPriv:
  1021. GlobalUnlock(hUIPrivate);
  1022. UIPaint(hUIWnd);
  1023. // PostMessage(hUIWnd, WM_PAINT, 0, 0); //zl3
  1024. return;
  1025. }
  1026. /**********************************************************************/
  1027. /* GetConversionMode() */
  1028. /* Return Value : */
  1029. /* the conversion mode */
  1030. /**********************************************************************/
  1031. LRESULT PASCAL GetConversionMode(
  1032. HWND hUIWnd)
  1033. {
  1034. HIMC hIMC;
  1035. LPINPUTCONTEXT lpIMC;
  1036. DWORD fdwConversion;
  1037. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1038. if (!hIMC) {
  1039. return (LRESULT)NULL;
  1040. }
  1041. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1042. if (!lpIMC) {
  1043. return (LRESULT)NULL;
  1044. }
  1045. fdwConversion = lpIMC->fdwConversion;
  1046. ImmUnlockIMC(hIMC);
  1047. return (LRESULT)fdwConversion;
  1048. }
  1049. /**********************************************************************/
  1050. /* SetConversionMode() */
  1051. /* Return Value : */
  1052. /* NULL - successful, else - failure */
  1053. /**********************************************************************/
  1054. LRESULT PASCAL SetConversionMode( // set conversion mode
  1055. HWND hUIWnd,
  1056. DWORD dwNewConvMode)
  1057. {
  1058. HIMC hIMC;
  1059. DWORD dwOldConvMode, fdwOldSentence;
  1060. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1061. if (!hIMC) {
  1062. return (1L);
  1063. }
  1064. if (!ImmGetConversionStatus(hIMC, &dwOldConvMode, &fdwOldSentence))
  1065. return (LRESULT)(1L);
  1066. return (LRESULT)!ImmSetConversionStatus(hIMC, dwNewConvMode,
  1067. fdwOldSentence);
  1068. }
  1069. /**********************************************************************/
  1070. /* GetSentenceMode() */
  1071. /* Return Value : */
  1072. /* the sentence mode */
  1073. /**********************************************************************/
  1074. LRESULT PASCAL GetSentenceMode(
  1075. HWND hUIWnd)
  1076. {
  1077. HIMC hIMC;
  1078. LPINPUTCONTEXT lpIMC;
  1079. DWORD fdwSentence;
  1080. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1081. if (!hIMC) {
  1082. return (LRESULT)NULL;
  1083. }
  1084. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1085. if (!lpIMC) {
  1086. return (LRESULT)NULL;
  1087. }
  1088. fdwSentence = lpIMC->fdwSentence;
  1089. ImmUnlockIMC(hIMC);
  1090. return (LRESULT)fdwSentence;
  1091. }
  1092. /**********************************************************************/
  1093. /* SetSentenceMode() */
  1094. /* Return Value : */
  1095. /* NULL - successful, else - failure */
  1096. /**********************************************************************/
  1097. LRESULT PASCAL SetSentenceMode( // set the sentence mode
  1098. HWND hUIWnd,
  1099. DWORD dwNewSentence)
  1100. {
  1101. HIMC hIMC;
  1102. DWORD dwOldConvMode, fdwOldSentence;
  1103. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1104. if (!hIMC) {
  1105. return (1L);
  1106. }
  1107. if (!ImmGetConversionStatus(hIMC, &dwOldConvMode, &fdwOldSentence)) {
  1108. return (LRESULT)(1L);
  1109. }
  1110. return (LRESULT)!ImmSetConversionStatus(hIMC, dwOldConvMode,
  1111. dwNewSentence);
  1112. }
  1113. /**********************************************************************/
  1114. /* GetOpenStatus() */
  1115. /* Return Value : */
  1116. /* the open status */
  1117. /**********************************************************************/
  1118. LRESULT PASCAL GetOpenStatus(
  1119. HWND hUIWnd)
  1120. {
  1121. HIMC hIMC;
  1122. LPINPUTCONTEXT lpIMC;
  1123. BOOL fOpen;
  1124. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1125. if (!hIMC) {
  1126. return (LRESULT)NULL;
  1127. }
  1128. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1129. if (!lpIMC) {
  1130. return (LRESULT)NULL;
  1131. }
  1132. fOpen = (BOOL)lpIMC->fOpen;
  1133. ImmUnlockIMC(hIMC);
  1134. return (LRESULT)fOpen;
  1135. }
  1136. /**********************************************************************/
  1137. /* SetOpenStatus() */
  1138. /* Return Value : */
  1139. /* NULL - successful, else - failure */
  1140. /**********************************************************************/
  1141. LRESULT PASCAL SetOpenStatus( // set open/close status
  1142. HWND hUIWnd,
  1143. BOOL fNewOpenStatus)
  1144. {
  1145. HIMC hIMC;
  1146. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1147. if (!hIMC) {
  1148. return (1L);
  1149. }
  1150. return (LRESULT)!ImmSetOpenStatus(hIMC, fNewOpenStatus);
  1151. }
  1152. /**********************************************************************/
  1153. /* SetCompFont() */
  1154. /**********************************************************************/
  1155. LRESULT PASCAL SetCompFont(
  1156. HWND hUIWnd,
  1157. LPLOGFONT lplfFont)
  1158. {
  1159. HIMC hIMC;
  1160. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1161. if (!hIMC) {
  1162. return (1L);
  1163. }
  1164. return (LRESULT)!ImmSetCompositionFont(hIMC, lplfFont);
  1165. }
  1166. /**********************************************************************/
  1167. /* GetCompWindow() */
  1168. /**********************************************************************/
  1169. LRESULT PASCAL GetCompWindow(
  1170. HWND hUIWnd,
  1171. LPCOMPOSITIONFORM lpCompForm)
  1172. {
  1173. HWND hCompWnd;
  1174. RECT rcCompWnd;
  1175. hCompWnd = GetCompWnd(hUIWnd);
  1176. if (!hCompWnd) {
  1177. return (1L);
  1178. }
  1179. if (!GetWindowRect(hCompWnd, &rcCompWnd)) {
  1180. return (1L);
  1181. }
  1182. lpCompForm->dwStyle = CFS_POINT|CFS_RECT;
  1183. lpCompForm->ptCurrentPos = *(LPPOINT)&rcCompWnd;
  1184. lpCompForm->rcArea = rcCompWnd;
  1185. return (0L);
  1186. }
  1187. /**********************************************************************/
  1188. /* SelectIME() */
  1189. /**********************************************************************/
  1190. void PASCAL SelectIME( // switch IMEs
  1191. HWND hUIWnd,
  1192. BOOL fSelect)
  1193. {
  1194. if (!fSelect) {
  1195. ShowUI(hUIWnd, SW_HIDE);
  1196. } else {
  1197. HIMC hIMC;
  1198. LPINPUTCONTEXT lpIMC;
  1199. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1200. if (!hIMC) {
  1201. MessageBeep((UINT)-1);
  1202. return;
  1203. }
  1204. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  1205. MessageBeep((UINT)-1);
  1206. return;
  1207. }
  1208. if(GetKeyState(VK_CAPITAL)&1){
  1209. lpIMC->fdwConversion |= IME_CMODE_NOCONVERSION;
  1210. lpIMC->fdwConversion &= ~IME_CMODE_NATIVE;
  1211. cap_mode = 1;
  1212. }else{
  1213. lpIMC->fdwConversion |= IME_CMODE_NATIVE;
  1214. lpIMC->fdwConversion &= ~IME_CMODE_NOCONVERSION;
  1215. cap_mode = 0;
  1216. }
  1217. ImmUnlockIMC(hIMC);
  1218. UpdateSoftKbd(hUIWnd);
  1219. ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
  1220. }
  1221. return;
  1222. }
  1223. /**********************************************************************/
  1224. /* ToggleUI() */
  1225. /**********************************************************************/
  1226. /*
  1227. void PASCAL ToggleUI(
  1228. HWND hUIWnd)
  1229. {
  1230. HGLOBAL hUIPrivate;
  1231. LPUIPRIV lpUIPrivate;
  1232. DWORD fdwFlag;
  1233. HIMC hIMC;
  1234. LPINPUTCONTEXT lpIMC;
  1235. LPPRIVCONTEXT lpImcP;
  1236. HWND hDestroyWnd;
  1237. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  1238. if (!hUIPrivate) {
  1239. return;
  1240. }
  1241. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  1242. if (!lpUIPrivate) {
  1243. return;
  1244. }
  1245. //if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
  1246. // if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1247. // goto ToggleUIOvr;
  1248. // } else {
  1249. // fdwFlag = 0;
  1250. // }
  1251. //} else {
  1252. // if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1253. // fdwFlag = ISC_OFF_CARET_UI;
  1254. // } else {
  1255. // goto ToggleUIOvr;
  1256. // }
  1257. //}
  1258. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1259. if (!hIMC) {
  1260. goto ToggleUIOvr;
  1261. }
  1262. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1263. if (!lpIMC) {
  1264. goto ToggleUIOvr;
  1265. }
  1266. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  1267. if (!lpImcP) {
  1268. goto CreateUIOvr;
  1269. }
  1270. if (fdwFlag & ISC_OFF_CARET_UI) {
  1271. lpUIPrivate->fdwSetContext |= (ISC_OFF_CARET_UI);
  1272. } else {
  1273. lpUIPrivate->fdwSetContext &= ~(ISC_OFF_CARET_UI);
  1274. }
  1275. hDestroyWnd = NULL;
  1276. // we need to dsetroy status first because lpUIPrivate->hStatusWnd
  1277. // may be NULL out in OffCreat UI destroy time
  1278. if (lpUIPrivate->hStatusWnd) {
  1279. if (lpUIPrivate->hStatusWnd != hDestroyWnd) {
  1280. hDestroyWnd = lpUIPrivate->hStatusWnd;
  1281. DestroyWindow(lpUIPrivate->hStatusWnd);
  1282. }
  1283. lpUIPrivate->hStatusWnd = NULL;
  1284. }
  1285. // destroy all off caret UI
  1286. if (lpUIPrivate->hCompWnd) {
  1287. if (lpUIPrivate->hCompWnd != hDestroyWnd) {
  1288. hDestroyWnd = lpUIPrivate->hCompWnd;
  1289. DestroyWindow(lpUIPrivate->hCompWnd);
  1290. }
  1291. lpUIPrivate->hCompWnd = NULL;
  1292. lpUIPrivate->nShowCompCmd = SW_HIDE;
  1293. }
  1294. if (lpUIPrivate->hCandWnd) {
  1295. if (lpUIPrivate->hCandWnd != hDestroyWnd) {
  1296. hDestroyWnd = lpUIPrivate->hCandWnd;
  1297. DestroyWindow(lpUIPrivate->hCandWnd);
  1298. }
  1299. lpUIPrivate->hCandWnd = NULL;
  1300. lpUIPrivate->nShowCandCmd = SW_HIDE;
  1301. }
  1302. if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  1303. OpenStatus(hUIWnd);
  1304. }
  1305. if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW)) {
  1306. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  1307. StartComp(hUIWnd);
  1308. } else {
  1309. }
  1310. if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW)) {
  1311. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  1312. if (!(fdwFlag & ISC_OFF_CARET_UI)) {
  1313. NotifyIME(hIMC, NI_SETCANDIDATE_PAGESIZE, 0, CANDPERPAGE);
  1314. }
  1315. OpenCand(hUIWnd);
  1316. } else {
  1317. }
  1318. ImmUnlockIMCC(lpIMC->hPrivate);
  1319. CreateUIOvr:
  1320. ImmUnlockIMC(hIMC);
  1321. ToggleUIOvr:
  1322. GlobalUnlock(hUIPrivate);
  1323. return;
  1324. }
  1325. */
  1326. /**********************************************************************/
  1327. /* UIPaint() */
  1328. /**********************************************************************/
  1329. LRESULT PASCAL UIPaint(
  1330. HWND hUIWnd)
  1331. {
  1332. PAINTSTRUCT ps;
  1333. MSG sMsg;
  1334. HGLOBAL hUIPrivate;
  1335. LPUIPRIV lpUIPrivate;
  1336. // for safety
  1337. BeginPaint(hUIWnd, &ps);
  1338. EndPaint(hUIWnd, &ps);
  1339. // some application will not remove the WM_PAINT messages
  1340. PeekMessage(&sMsg, hUIWnd, WM_PAINT, WM_PAINT, PM_REMOVE|PM_NOYIELD);
  1341. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  1342. if (!hUIPrivate) {
  1343. return (0L);
  1344. }
  1345. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  1346. if (!lpUIPrivate) {
  1347. return (0L);
  1348. }
  1349. if (lpUIPrivate->fdwSetContext & ISC_SHOW_UI_ALL) { //ZL1
  1350. //if (lpUIPrivate->fdwSetContext & ISC_SETCONTEXT_UI) {
  1351. /*
  1352. if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
  1353. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)){
  1354. ToggleUI(hUIWnd);
  1355. }
  1356. } else {
  1357. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1358. ToggleUI(hUIWnd);
  1359. }
  1360. }
  1361. */
  1362. ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
  1363. } else {
  1364. ShowUI(hUIWnd, SW_HIDE);
  1365. }
  1366. GlobalUnlock(hUIPrivate);
  1367. return (0L);
  1368. }
  1369. /**********************************************************************/
  1370. /* UIWndProc() */
  1371. /**********************************************************************/
  1372. LRESULT CALLBACK UIWndProc( // maybe not good but this UI
  1373. // window also is composition window
  1374. HWND hUIWnd,
  1375. UINT uMsg,
  1376. WPARAM wParam,
  1377. LPARAM lParam)
  1378. {
  1379. lpImeL->TempUIWnd = hUIWnd ;
  1380. switch (uMsg) {
  1381. case WM_NEW_WORD:
  1382. // DefNewNow = 0;
  1383. UpdateUser();
  1384. break;
  1385. case WM_CREATE:
  1386. CreateUIWindow(hUIWnd);
  1387. break;
  1388. case WM_DESTROY:
  1389. DestroyUIWindow(hUIWnd);
  1390. break;
  1391. case WM_IME_STARTCOMPOSITION:
  1392. // you can create a window as the composition window here
  1393. StartComp(hUIWnd);
  1394. if (lParam==0x6699)
  1395. show_char(NULL,0);
  1396. break;
  1397. case WM_IME_COMPOSITION:
  1398. if (lParam & GCS_RESULTSTR) {
  1399. MoveDefaultCompPosition(hUIWnd);
  1400. }
  1401. UpdateCompWindow(hUIWnd);
  1402. break;
  1403. case WM_IME_ENDCOMPOSITION:
  1404. // you can destroy the composition window here
  1405. EndComp(hUIWnd);
  1406. break;
  1407. case WM_IME_NOTIFY:
  1408. NotifyUI(hUIWnd, wParam, lParam);
  1409. break;
  1410. case WM_IME_SETCONTEXT:
  1411. SetContext(hUIWnd, (BOOL)wParam, lParam);
  1412. break;
  1413. case WM_IME_CONTROL:
  1414. switch (wParam) {
  1415. case IMC_SETCONVERSIONMODE:
  1416. return SetConversionMode(hUIWnd, (DWORD)lParam);
  1417. case IMC_SETSENTENCEMODE:
  1418. return SetSentenceMode(hUIWnd, (DWORD)lParam);
  1419. case IMC_SETOPENSTATUS:
  1420. return SetOpenStatus(hUIWnd, (BOOL)lParam);
  1421. case IMC_GETCANDIDATEPOS:
  1422. return GetCandPos(hUIWnd,(LPCANDIDATEFORM)lParam);
  1423. return (1L); // not implemented yet
  1424. case IMC_SETCANDIDATEPOS:
  1425. return SetCandPosition(hUIWnd, (LPCANDIDATEFORM)lParam);
  1426. case IMC_GETCOMPOSITIONFONT:
  1427. return (1L); // not implemented yet
  1428. case IMC_SETCOMPOSITIONFONT:
  1429. return SetCompFont(hUIWnd, (LPLOGFONT)lParam);
  1430. case IMC_GETCOMPOSITIONWINDOW:
  1431. return GetCompWindow(hUIWnd, (LPCOMPOSITIONFORM)lParam);
  1432. case IMC_SETCOMPOSITIONWINDOW:
  1433. {
  1434. HIMC hIMC;
  1435. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1436. if (!hIMC) {
  1437. return (1L);
  1438. }
  1439. return (LRESULT)!ImmSetCompositionWindow(hIMC,
  1440. (LPCOMPOSITIONFORM)lParam);
  1441. }
  1442. return (1L);
  1443. case IMC_GETSTATUSWINDOWPOS:
  1444. {
  1445. HWND hStatusWnd;
  1446. RECT rcStatusWnd;
  1447. LPARAM lParam;
  1448. hStatusWnd = GetStatusWnd(hUIWnd);
  1449. if (!hStatusWnd) {
  1450. return (0L); // fail, return (0, 0)?
  1451. }
  1452. if (!GetWindowRect(hStatusWnd, &rcStatusWnd)) {
  1453. return (0L); // fail, return (0, 0)?
  1454. }
  1455. lParam = MAKELRESULT(rcStatusWnd.left, rcStatusWnd.right);
  1456. return (lParam);
  1457. }
  1458. return (0L);
  1459. case IMC_SETSTATUSWINDOWPOS:
  1460. {
  1461. HIMC hIMC;
  1462. POINT ptPos;
  1463. ptPos.x = ((LPPOINTS)&lParam)->x;
  1464. ptPos.y = ((LPPOINTS)&lParam)->y;
  1465. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1466. if (!hIMC) {
  1467. return (1L);
  1468. }
  1469. return ImmSetStatusWindowPos(hIMC, &ptPos);
  1470. }
  1471. return (1L);
  1472. default:
  1473. return (1L);
  1474. }
  1475. break;
  1476. case WM_IME_COMPOSITIONFULL:
  1477. return (0L);
  1478. case WM_IME_SELECT:
  1479. SelectIME(hUIWnd, (BOOL)wParam);
  1480. return (0L);
  1481. case WM_MOUSEACTIVATE:
  1482. return (MA_NOACTIVATE);
  1483. case WM_PAINT:
  1484. UIPaint(hUIWnd);
  1485. return 0L; //ZL2
  1486. default:
  1487. return DefWindowProc(hUIWnd, uMsg, wParam, lParam);
  1488. }
  1489. return (0L);
  1490. }
  1491. /**********************************************************************/
  1492. /* DrawFrameBorder() */
  1493. /**********************************************************************/
  1494. void PASCAL DrawFrameBorder( // border of IME
  1495. HDC hDC,
  1496. HWND hWnd) // window of IME
  1497. {
  1498. RECT rcWnd;
  1499. int xWi, yHi;
  1500. GetWindowRect(hWnd, &rcWnd);
  1501. xWi = rcWnd.right - rcWnd.left;
  1502. yHi = rcWnd.bottom - rcWnd.top;
  1503. // 1, ->
  1504. PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
  1505. // 1, v
  1506. PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
  1507. // 1, _>
  1508. PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
  1509. // 1, v
  1510. PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
  1511. xWi -= 2;
  1512. yHi -= 2;
  1513. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  1514. // 2, ->
  1515. PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
  1516. // 2, v
  1517. PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
  1518. // 2, v
  1519. PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
  1520. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  1521. // 2, _>
  1522. PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
  1523. xWi -= 2;
  1524. yHi -= 2;
  1525. // 3, ->
  1526. PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
  1527. // 3, v
  1528. PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
  1529. // 3, v
  1530. PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
  1531. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  1532. // 3, _>
  1533. PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
  1534. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  1535. xWi -= 2;
  1536. yHi -= 2;
  1537. // 4, ->
  1538. PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
  1539. // 4, v
  1540. PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
  1541. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  1542. // 4, v
  1543. PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
  1544. // 4, _>
  1545. PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
  1546. return;
  1547. }
  1548. /**********************************************************************/
  1549. /* GetCompWnd */
  1550. /* Return Value : */
  1551. /* window handle of composition */
  1552. /**********************************************************************/
  1553. HWND PASCAL GetCompWnd(
  1554. HWND hUIWnd) // UI window
  1555. {
  1556. HGLOBAL hUIPrivate;
  1557. LPUIPRIV lpUIPrivate;
  1558. HWND hCompWnd;
  1559. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  1560. if (!hUIPrivate) { // can not darw candidate window
  1561. return (HWND)NULL;
  1562. }
  1563. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  1564. if (!lpUIPrivate) { // can not draw candidate window
  1565. return (HWND)NULL;
  1566. }
  1567. hCompWnd = lpUIPrivate->hCompWnd;
  1568. GlobalUnlock(hUIPrivate);
  1569. return (hCompWnd);
  1570. }
  1571. /**********************************************************************/
  1572. /* GetNearCaretPosition() */
  1573. /**********************************************************************/
  1574. void PASCAL GetNearCaretPosition( // decide a near caret position according
  1575. // to the caret position
  1576. LPPOINT lpptFont,
  1577. UINT uEsc,
  1578. UINT uRot,
  1579. LPPOINT lpptCaret,
  1580. LPPOINT lpptNearCaret,
  1581. BOOL fFlags)
  1582. {
  1583. LONG lFontSize;
  1584. LONG xWidthUI, yHeightUI, xBorder, yBorder;
  1585. if ((uEsc + uRot) & 0x0001) {
  1586. lFontSize = lpptFont->x;
  1587. } else {
  1588. lFontSize = lpptFont->y;
  1589. }
  1590. if (fFlags & NEAR_CARET_CANDIDATE) {
  1591. xWidthUI = sImeG.xCandWi;
  1592. yHeightUI = sImeG.yCandHi;
  1593. xBorder = sImeG.cxCandBorder;
  1594. yBorder = sImeG.cyCandBorder;
  1595. } else {
  1596. xWidthUI = lpImeL->xCompWi;
  1597. yHeightUI = lpImeL->yCompHi;
  1598. xBorder = lpImeL->cxCompBorder;
  1599. yBorder = lpImeL->cyCompBorder;
  1600. }
  1601. if (fFlags & NEAR_CARET_FIRST_TIME) {
  1602. lpptNearCaret->x = lpptCaret->x +
  1603. lFontSize * ncUIEsc[uEsc].iLogFontFacX +
  1604. sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
  1605. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX;
  1606. if (ptInputEsc[uEsc].x >= 0) {
  1607. lpptNearCaret->x += xBorder * 2;
  1608. } else {
  1609. lpptNearCaret->x -= xWidthUI - xBorder * 2;
  1610. }
  1611. lpptNearCaret->y = lpptCaret->y +
  1612. lFontSize * ncUIEsc[uEsc].iLogFontFacY +
  1613. sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
  1614. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY;
  1615. if (ptInputEsc[uEsc].y >= 0) {
  1616. lpptNearCaret->y += yBorder * 2;
  1617. } else {
  1618. lpptNearCaret->y -= yHeightUI - yBorder * 2;
  1619. }
  1620. } else {
  1621. lpptNearCaret->x = lpptCaret->x +
  1622. lFontSize * ncAltUIEsc[uEsc].iLogFontFacX +
  1623. sImeG.iPara * ncAltUIEsc[uEsc].iParaFacX +
  1624. sImeG.iPerp * ncAltUIEsc[uEsc].iPerpFacX;
  1625. if (ptAltInputEsc[uEsc].x >= 0) {
  1626. lpptNearCaret->x += xBorder * 2;
  1627. } else {
  1628. lpptNearCaret->x -= xWidthUI - xBorder * 2;
  1629. }
  1630. lpptNearCaret->y = lpptCaret->y +
  1631. lFontSize * ncAltUIEsc[uEsc].iLogFontFacY +
  1632. sImeG.iPara * ncAltUIEsc[uEsc].iParaFacY +
  1633. sImeG.iPerp * ncAltUIEsc[uEsc].iPerpFacY;
  1634. if (ptAltInputEsc[uEsc].y >= 0) {
  1635. lpptNearCaret->y += yBorder * 2;
  1636. } else {
  1637. lpptNearCaret->y -= yHeightUI - yBorder * 2;
  1638. }
  1639. }
  1640. if (lpptNearCaret->x < sImeG.rcWorkArea.left) {
  1641. lpptNearCaret->x = sImeG.rcWorkArea.left;
  1642. } else if (lpptNearCaret->x + xWidthUI > sImeG.rcWorkArea.right) {
  1643. lpptNearCaret->x = sImeG.rcWorkArea.right - xWidthUI;
  1644. } else {
  1645. }
  1646. if (lpptNearCaret->y < sImeG.rcWorkArea.top) {
  1647. lpptNearCaret->y = sImeG.rcWorkArea.top;
  1648. } else if (lpptNearCaret->y + yHeightUI > sImeG.rcWorkArea.bottom) {
  1649. lpptNearCaret->y = sImeG.rcWorkArea.bottom - yHeightUI;
  1650. } else {
  1651. }
  1652. return;
  1653. }
  1654. /**********************************************************************/
  1655. /* FitInLazyOperation() */
  1656. /* Return Value : */
  1657. /* TRUE or FALSE */
  1658. /**********************************************************************/
  1659. BOOL PASCAL FitInLazyOperation( // fit in lazy operation or not
  1660. LPPOINT lpptOrg,
  1661. LPPOINT lpptNearCaret, // the suggested near caret position
  1662. LPRECT lprcInputRect,
  1663. UINT uEsc)
  1664. {
  1665. POINT ptDelta, ptTol;
  1666. RECT rcUIRect, rcInterRect;
  1667. ptDelta.x = lpptOrg->x - lpptNearCaret->x;
  1668. ptDelta.x = (ptDelta.x >= 0) ? ptDelta.x : -ptDelta.x;
  1669. ptTol.x = sImeG.iParaTol * ncUIEsc[uEsc].iParaFacX +
  1670. sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacX;
  1671. ptTol.x = (ptTol.x >= 0) ? ptTol.x : -ptTol.x;
  1672. if (ptDelta.x > ptTol.x) {
  1673. return (FALSE);
  1674. }
  1675. ptDelta.y = lpptOrg->y - lpptNearCaret->y;
  1676. ptDelta.y = (ptDelta.y >= 0) ? ptDelta.y : -ptDelta.y;
  1677. ptTol.y = sImeG.iParaTol * ncUIEsc[uEsc].iParaFacY +
  1678. sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacY;
  1679. ptTol.y = (ptTol.y >= 0) ? ptTol.y : -ptTol.y;
  1680. if (ptDelta.y > ptTol.y) {
  1681. return (FALSE);
  1682. }
  1683. // build up the UI rectangle (composition window)
  1684. rcUIRect.left = lpptOrg->x;
  1685. rcUIRect.top = lpptOrg->y;
  1686. rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
  1687. rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
  1688. if (IntersectRect(&rcInterRect, &rcUIRect, lprcInputRect)) {
  1689. return (FALSE);
  1690. }
  1691. return (TRUE);
  1692. }
  1693. /**********************************************************************/
  1694. /* AdjustCompPosition() */
  1695. /* Return Value : */
  1696. /* the position of composition window is changed or not */
  1697. /**********************************************************************/
  1698. BOOL PASCAL AdjustCompPosition( // IME adjust position according to
  1699. // composition form
  1700. LPINPUTCONTEXT lpIMC,
  1701. LPPOINT lpptOrg, // original composition window
  1702. // and final position
  1703. LPPOINT lpptNew) // new expect position
  1704. {
  1705. POINT ptNearCaret, ptOldNearCaret, ptCompWnd;
  1706. UINT uEsc, uRot;
  1707. RECT rcUIRect, rcInputRect, rcInterRect;
  1708. POINT ptFont;
  1709. // we need to adjust according to font attribute
  1710. if (lpIMC->lfFont.A.lfWidth > 0) {
  1711. ptFont.x = lpIMC->lfFont.A.lfWidth * 2;
  1712. } else if (lpIMC->lfFont.A.lfWidth < 0) {
  1713. ptFont.x = -lpIMC->lfFont.A.lfWidth * 2;
  1714. } else if (lpIMC->lfFont.A.lfHeight > 0) {
  1715. ptFont.x = lpIMC->lfFont.A.lfHeight;
  1716. } else if (lpIMC->lfFont.A.lfHeight < 0) {
  1717. ptFont.x = -lpIMC->lfFont.A.lfHeight;
  1718. } else {
  1719. ptFont.x = lpImeL->yCompHi;
  1720. }
  1721. if (lpIMC->lfFont.A.lfHeight > 0) {
  1722. ptFont.y = lpIMC->lfFont.A.lfHeight;
  1723. } else if (lpIMC->lfFont.A.lfHeight < 0) {
  1724. ptFont.y = -lpIMC->lfFont.A.lfHeight;
  1725. } else {
  1726. ptFont.y = ptFont.x;
  1727. }
  1728. // if the input char is too big, we don't need to consider so much
  1729. if (ptFont.x > lpImeL->yCompHi * 8) {
  1730. ptFont.x = lpImeL->yCompHi * 8;
  1731. }
  1732. if (ptFont.y > lpImeL->yCompHi * 8) {
  1733. ptFont.y = lpImeL->yCompHi * 8;
  1734. }
  1735. if (ptFont.x < sImeG.xChiCharWi) {
  1736. ptFont.x = sImeG.xChiCharWi;
  1737. }
  1738. if (ptFont.y < sImeG.yChiCharHi) {
  1739. ptFont.y = sImeG.yChiCharHi;
  1740. }
  1741. // -450 to 450 index 0
  1742. // 450 to 1350 index 1
  1743. // 1350 to 2250 index 2
  1744. // 2250 to 3150 index 3
  1745. uEsc = (UINT)((lpIMC->lfFont.A.lfEscapement + 450) / 900 % 4);
  1746. uRot = (UINT)((lpIMC->lfFont.A.lfOrientation + 450) / 900 % 4);
  1747. // decide the input rectangle
  1748. rcInputRect.left = lpptNew->x;
  1749. rcInputRect.top = lpptNew->y;
  1750. // build up an input rectangle from escapemment
  1751. rcInputRect.right = rcInputRect.left + ptFont.x * ptInputEsc[uEsc].x;
  1752. rcInputRect.bottom = rcInputRect.top + ptFont.y * ptInputEsc[uEsc].y;
  1753. // be a normal rectangle, not a negative rectangle
  1754. if (rcInputRect.left > rcInputRect.right) {
  1755. LONG tmp;
  1756. tmp = rcInputRect.left;
  1757. rcInputRect.left = rcInputRect.right;
  1758. rcInputRect.right = tmp;
  1759. }
  1760. if (rcInputRect.top > rcInputRect.bottom) {
  1761. LONG tmp;
  1762. tmp = rcInputRect.top;
  1763. rcInputRect.top = rcInputRect.bottom;
  1764. rcInputRect.bottom = tmp;
  1765. }
  1766. GetNearCaretPosition(
  1767. &ptFont, uEsc, uRot, lpptNew, &ptNearCaret, NEAR_CARET_FIRST_TIME);
  1768. // 1st, use the adjust point
  1769. // build up the new suggest UI rectangle (composition window)
  1770. rcUIRect.left = ptNearCaret.x;
  1771. rcUIRect.top = ptNearCaret.y;
  1772. rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
  1773. rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
  1774. ptCompWnd = ptOldNearCaret = ptNearCaret;
  1775. // OK, no intersect between the near caret position and input char
  1776. if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
  1777. } else if (CalcCandPos(
  1778. /*lpIMC,*/ &ptCompWnd)) {
  1779. // can not fit the candidate window
  1780. } else if (FitInLazyOperation(
  1781. lpptOrg, &ptNearCaret, &rcInputRect, uEsc)) {
  1782. // happy ending!!!, don't chaqge position
  1783. return (FALSE);
  1784. } else {
  1785. *lpptOrg = ptNearCaret;
  1786. // happy ending!!
  1787. return (TRUE);
  1788. }
  1789. // unhappy case
  1790. GetNearCaretPosition(&ptFont, uEsc, uRot, lpptNew, &ptNearCaret, 0);
  1791. // build up the new suggest UI rectangle (composition window)
  1792. rcUIRect.left = ptNearCaret.x;
  1793. rcUIRect.top = ptNearCaret.y;
  1794. rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
  1795. rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
  1796. ptCompWnd = ptNearCaret;
  1797. // OK, no intersect between the adjust position and input char
  1798. if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
  1799. } else if (CalcCandPos(
  1800. /*lpIMC,*/ &ptCompWnd)) {
  1801. // can not fit the candidate window
  1802. } else if (FitInLazyOperation(
  1803. lpptOrg, &ptNearCaret, &rcInputRect, uEsc)) {
  1804. // happy ending!!!, don't chaqge position
  1805. return (FALSE);
  1806. } else {
  1807. *lpptOrg = ptNearCaret;
  1808. // happy ending!!
  1809. return (TRUE);
  1810. }
  1811. // unhappy ending! :-(
  1812. *lpptOrg = ptOldNearCaret;
  1813. return (TRUE);
  1814. }
  1815. /**********************************************************************/
  1816. /* AdjustCompPosition() */
  1817. /* Return Value : */
  1818. /* the position of composition window is changed or not */
  1819. /**********************************************************************/
  1820. /*BOOL PASCAL AdjustCompPosition( // IME adjust position according to
  1821. // composition form
  1822. LPINPUTCONTEXT lpIMC,
  1823. LPPOINT lpptOrg, // original composition window
  1824. // and final position
  1825. LPPOINT lpptNew) // new expect position
  1826. {
  1827. POINT ptAdjust, ptDelta;
  1828. UINT uEsc;
  1829. RECT rcUIRect, rcInputRect, rcInterRect;
  1830. POINT ptFont;
  1831. ptAdjust.x = lpptNew->x;
  1832. ptAdjust.y = lpptNew->y;
  1833. // we need to adjust according to font attribute
  1834. if (lpIMC->lfFont.A.lfWidth > 0) {
  1835. ptFont.x = lpIMC->lfFont.A.lfWidth;
  1836. } else if (lpIMC->lfFont.A.lfWidth == 0) {
  1837. ptFont.x = lpImeL->yCompHi;
  1838. } else {
  1839. ptFont.x = -lpIMC->lfFont.A.lfWidth;
  1840. }
  1841. if (lpIMC->lfFont.A.lfHeight > 0) {
  1842. ptFont.y = lpIMC->lfFont.A.lfHeight;
  1843. } else if (lpIMC->lfFont.A.lfWidth == 0) {
  1844. ptFont.y = lpImeL->yCompHi;
  1845. } else {
  1846. ptFont.y = -lpIMC->lfFont.A.lfHeight;
  1847. }
  1848. // if the input char is too big, we don't need to consider so much
  1849. if (ptFont.x > lpImeL->yCompHi * 8) {
  1850. ptFont.x = lpImeL->yCompHi * 8;
  1851. }
  1852. if (ptFont.y > lpImeL->yCompHi * 8) {
  1853. ptFont.y = lpImeL->yCompHi * 8;
  1854. }
  1855. if (ptFont.x < sImeG.xChiCharWi) {
  1856. ptFont.x = sImeG.xChiCharWi;
  1857. }
  1858. if (ptFont.y < sImeG.yChiCharHi) {
  1859. ptFont.y = sImeG.yChiCharHi;
  1860. }
  1861. // -450 to 450 index 0
  1862. // 450 to 1350 index 1
  1863. // 1350 to 2250 index 2
  1864. // 2250 to 3150 index 3
  1865. uEsc = (UINT)((lpIMC->lfFont.A.lfEscapement + 450) / 900 % 4);
  1866. // find the location after IME do an adjustment
  1867. ptAdjust.x = ptAdjust.x + sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
  1868. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX;
  1869. ptAdjust.y = ptAdjust.y + ptFont.y * ncUIEsc[uEsc].iLogFontFac +
  1870. sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
  1871. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY - lpImeL->cyCompBorder;
  1872. // Is the current location within tolerance?
  1873. ptDelta.x = lpptOrg->x - ptAdjust.x;
  1874. ptDelta.y = lpptOrg->y - ptAdjust.y;
  1875. ptDelta.x = (ptDelta.x > 0) ? ptDelta.x : -ptDelta.x;
  1876. ptDelta.y = (ptDelta.y > 0) ? ptDelta.y : -ptDelta.y;
  1877. // decide the input rectangle
  1878. rcInputRect.left = lpptNew->x;
  1879. rcInputRect.top = lpptNew->y;
  1880. // build up an input rectangle from escapemment
  1881. rcInputRect.right = rcInputRect.left + ptFont.x * ptInputEsc[uEsc].x;
  1882. rcInputRect.bottom = rcInputRect.top + ptFont.y * ptInputEsc[uEsc].y;
  1883. // be a normal rectangle, not a negative rectangle
  1884. if (rcInputRect.left > rcInputRect.right) {
  1885. int tmp;
  1886. tmp = rcInputRect.left;
  1887. rcInputRect.left = rcInputRect.right;
  1888. rcInputRect.right = tmp;
  1889. }
  1890. if (rcInputRect.top > rcInputRect.bottom) {
  1891. int tmp;
  1892. tmp = rcInputRect.top;
  1893. rcInputRect.top = rcInputRect.bottom;
  1894. rcInputRect.bottom = tmp;
  1895. }
  1896. // build up the UI rectangle (composition window)
  1897. rcUIRect.left = lpptOrg->x;
  1898. rcUIRect.top = lpptOrg->y;
  1899. rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
  1900. rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
  1901. // will it within lazy operation range (tolerance)
  1902. if (ptDelta.x > sImeG.iParaTol * ncUIEsc[uEsc].iParaFacX +
  1903. sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacX) {
  1904. } else if (ptDelta.y > sImeG.iParaTol * ncUIEsc[uEsc].iParaFacY +
  1905. sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacY) {
  1906. } else if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
  1907. // If there are intersection, we need to fix that
  1908. } else {
  1909. // happy ending!!!, don't chaqge position
  1910. return (FALSE);
  1911. }
  1912. ptAdjust.x -= lpImeL->cxCompBorder;
  1913. ptAdjust.y -= lpImeL->cyCompBorder;
  1914. // lazy guy, move!
  1915. // 1st, use the adjust point
  1916. if (ptAdjust.x < sImeG.rcWorkArea.left) {
  1917. ptAdjust.x = sImeG.rcWorkArea.left;
  1918. } else if (ptAdjust.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
  1919. ptAdjust.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
  1920. }
  1921. if (ptAdjust.y < sImeG.rcWorkArea.top) {
  1922. ptAdjust.y = sImeG.rcWorkArea.top;
  1923. } else if (ptAdjust.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
  1924. ptAdjust.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
  1925. }
  1926. // build up the new suggest UI rectangle (composition window)
  1927. rcUIRect.left = ptAdjust.x;
  1928. rcUIRect.top = ptAdjust.y;
  1929. rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
  1930. rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
  1931. // OK, no intersect between the adjust position and input char
  1932. if (!IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
  1933. // happy ending!!
  1934. lpptOrg->x = ptAdjust.x;
  1935. lpptOrg->y = ptAdjust.y;
  1936. return (TRUE);
  1937. }
  1938. // unhappy case
  1939. ptAdjust.x = lpptNew->x;
  1940. ptAdjust.y = lpptNew->y;
  1941. ClientToScreen((HWND)lpIMC->hWnd, &ptAdjust);
  1942. // IME do another adjustment
  1943. ptAdjust.x = ptAdjust.x + ptFont.x * ncUIEsc[uEsc].iParaFacX -
  1944. sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
  1945. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX - lpImeL->cxCompBorder;
  1946. ptAdjust.y = ptAdjust.y + ptFont.y * ncUIEsc[uEsc].iLogFontFac -
  1947. sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
  1948. sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY - lpImeL->cyCompBorder;
  1949. if (ptAdjust.x < sImeG.rcWorkArea.left) {
  1950. ptAdjust.x = sImeG.rcWorkArea.left;
  1951. } else if (ptAdjust.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
  1952. ptAdjust.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
  1953. }
  1954. if (ptAdjust.y < sImeG.rcWorkArea.top) {
  1955. ptAdjust.y = sImeG.rcWorkArea.top;
  1956. } else if (ptAdjust.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
  1957. ptAdjust.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
  1958. }
  1959. // unhappy ending! :-(
  1960. lpptOrg->x = ptAdjust.x;
  1961. lpptOrg->y = ptAdjust.y;
  1962. return (TRUE);
  1963. } */
  1964. /**********************************************************************/
  1965. /* SetCompPosFix() */
  1966. /**********************************************************************/
  1967. void PASCAL SetCompPosFix( // set the composition window position
  1968. HWND hCompWnd,
  1969. LPINPUTCONTEXT lpIMC)
  1970. {
  1971. POINT ptWnd;
  1972. BOOL fChange = FALSE;
  1973. HGLOBAL hUIPrivate;
  1974. LPUIPRIV lpUIPrivate;
  1975. // the client coordinate position (0, 0) of composition window
  1976. ptWnd.x = 0;
  1977. ptWnd.y = 0;
  1978. // convert to screen coordinates
  1979. ClientToScreen(hCompWnd, &ptWnd);
  1980. ptWnd.x -= lpImeL->cxCompBorder;
  1981. ptWnd.y -= lpImeL->cyCompBorder;
  1982. if (ptWnd.x != lpImeL->ptDefComp.x) {
  1983. ptWnd.x = lpImeL->ptDefComp.x;
  1984. fChange = TRUE;
  1985. }
  1986. if (ptWnd.y != lpImeL->ptDefComp.y) {
  1987. ptWnd.y = lpImeL->ptDefComp.y;
  1988. fChange = TRUE;
  1989. }
  1990. if (!fChange ) return;
  1991. //## 8
  1992. SetWindowPos(hCompWnd, NULL,
  1993. ptWnd.x, ptWnd.y,
  1994. lpImeL->xCompWi, lpImeL->yCompHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
  1995. hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
  1996. IMMGWLP_PRIVATE);
  1997. if (!hUIPrivate) {
  1998. return;
  1999. }
  2000. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2001. if (!lpUIPrivate) {
  2002. return;
  2003. }
  2004. if (!lpUIPrivate->hCandWnd) {
  2005. GlobalUnlock(hUIPrivate);
  2006. return;
  2007. }
  2008. // decide the position of candidate window by UI's position
  2009. // ##1
  2010. SetWindowPos(lpUIPrivate->hCandWnd, NULL,
  2011. lpImeL->ptDefCand.x, lpImeL->ptDefCand.y ,
  2012. sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
  2013. GlobalUnlock(hUIPrivate);
  2014. return;
  2015. }
  2016. /**********************************************************************/
  2017. /* SetCompPosition() */
  2018. /**********************************************************************/
  2019. void PASCAL SetCompPosition( // set the composition window position
  2020. HWND hCompWnd,
  2021. LPINPUTCONTEXT lpIMC)
  2022. {
  2023. POINT ptWnd, ptCaret;
  2024. BOOL fChange = FALSE;
  2025. HGLOBAL hUIPrivate;
  2026. LPUIPRIV lpUIPrivate;
  2027. HWND hCandWnd;
  2028. if (lpImeL->wImeStyle == IME_APRS_FIX){
  2029. SetCompPosFix(hCompWnd, lpIMC);
  2030. return;
  2031. }
  2032. // the client coordinate position (0, 0) of composition window
  2033. ptWnd.x = 0;
  2034. ptWnd.y = 0;
  2035. // convert to screen coordinates
  2036. ClientToScreen(hCompWnd, &ptWnd);
  2037. ptWnd.x -= lpImeL->cxCompBorder;
  2038. ptWnd.y -= lpImeL->cyCompBorder;
  2039. if (lpIMC->cfCompForm.dwStyle & CFS_FORCE_POSITION) {
  2040. POINT ptNew; // new position of UI
  2041. ptNew.x = lpIMC->cfCompForm.ptCurrentPos.x;
  2042. ptNew.y = lpIMC->cfCompForm.ptCurrentPos.y;
  2043. ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
  2044. if (ptWnd.x != ptNew.x) {
  2045. ptWnd.x = ptNew.x;
  2046. fChange = TRUE;
  2047. }
  2048. if (ptWnd.y != ptNew.y) {
  2049. ptWnd.y = ptNew.y;
  2050. fChange = TRUE;
  2051. }
  2052. if (fChange) {
  2053. ptWnd.x -= lpImeL->cxCompBorder;
  2054. ptWnd.y -= lpImeL->cyCompBorder;
  2055. }
  2056. } else if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
  2057. // aplication tell us the position, we need to adjust
  2058. POINT ptNew; // new position of UI
  2059. ptNew.x = lpIMC->cfCompForm.ptCurrentPos.x;
  2060. ptNew.y = lpIMC->cfCompForm.ptCurrentPos.y;
  2061. ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
  2062. fChange = AdjustCompPosition(lpIMC, &ptWnd, &ptNew);
  2063. } else {
  2064. POINT ptNew; // new position of UI
  2065. /*ptNew.x = lpIMC->ptStatusWndPos.x + sImeG.xStatusWi + UI_MARGIN;
  2066. if (ptNew.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
  2067. ptNew.x = lpIMC->ptStatusWndPos.x -
  2068. lpImeL->xCompWi - lpImeL->cxCompBorder * 2 -
  2069. UI_MARGIN;
  2070. }
  2071. ptNew.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;// - 2 * UI_MARGIN ;*/
  2072. ptNew.x = lpImeL->ptZLComp.x;
  2073. ptNew.y = lpImeL->ptZLComp.y;
  2074. if (ptWnd.x != ptNew.x) {
  2075. ptWnd.x = ptNew.x;
  2076. fChange = TRUE;
  2077. }
  2078. if (ptWnd.y != ptNew.y) {
  2079. ptWnd.y = ptNew.y;
  2080. fChange = TRUE;
  2081. }
  2082. if (fChange) {
  2083. lpIMC->cfCompForm.ptCurrentPos = ptNew;
  2084. ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
  2085. }
  2086. }
  2087. /*if (GetCaretPos(&ptCaret)) {
  2088. // application don't set position, OK we need to near caret
  2089. ClientToScreen(lpIMC->hWnd, &ptCaret);
  2090. fChange = AdjustCompPosition(lpIMC, &ptWnd, &ptCaret);
  2091. } else {
  2092. // no caret information!
  2093. if (ptWnd.x != lpImeL->ptDefComp.x) {
  2094. ptWnd.x = lpImeL->ptDefComp.y;
  2095. fChange = TRUE;
  2096. }
  2097. if (ptWnd.y != lpImeL->ptDefComp.x) {
  2098. ptWnd.y = lpImeL->ptDefComp.y;
  2099. fChange = TRUE;
  2100. }
  2101. if (ptWnd.x != lpImeL->ptDefComp.x) {
  2102. ptWnd.x =lpIMC->ptStatusWndPos.x + sImeG.TextLen+8;//lpImeL->ptDefComp.y;
  2103. fChange = TRUE;
  2104. }
  2105. if (ptWnd.y != lpImeL->ptDefComp.x) {
  2106. ptWnd.y =lpIMC->ptStatusWndPos.
  2107. } y ;//lpImeL->ptDefComp.y;
  2108. fChange = TRUE;
  2109. } */
  2110. if (!(fChange|CandWndChange)) {
  2111. return;
  2112. }
  2113. CandWndChange = 0;
  2114. // ##2
  2115. if(TypeOfOutMsg & COMP_NEEDS_END){
  2116. CloseCand(GetWindow(hCompWnd, GW_OWNER));
  2117. EndComp(GetWindow(hCompWnd, GW_OWNER));
  2118. //CloseCand(GetWindow(hCandWnd, GW_OWNER));
  2119. TypeOfOutMsg = TypeOfOutMsg & ~(COMP_NEEDS_END);
  2120. }
  2121. SetWindowPos(hCompWnd, NULL,
  2122. ptWnd.x, ptWnd.y,
  2123. lpImeL->xCompWi,lpImeL->yCompHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
  2124. hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
  2125. IMMGWLP_PRIVATE);
  2126. if (!hUIPrivate) {
  2127. return;
  2128. }
  2129. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2130. if (!lpUIPrivate) {
  2131. return;
  2132. }
  2133. if (!lpUIPrivate->hCandWnd) {
  2134. GlobalUnlock(hUIPrivate);
  2135. return;
  2136. }
  2137. // decide the position of candidate window by UI's position
  2138. CalcCandPos(&ptWnd);
  2139. //##3
  2140. SetWindowPos(lpUIPrivate->hCandWnd, NULL,
  2141. ptWnd.x, ptWnd.y,
  2142. sImeG.xCandWi,sImeG.yCandHi , SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
  2143. GlobalUnlock(hUIPrivate);
  2144. return;
  2145. }
  2146. /**********************************************************************/
  2147. /* SetCompWindow() */
  2148. /**********************************************************************/
  2149. void PASCAL SetCompWindow( // set the position of composition window
  2150. HWND hUIWnd)
  2151. {
  2152. HIMC hIMC;
  2153. LPINPUTCONTEXT lpIMC;
  2154. HWND hCompWnd;
  2155. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2156. if (!hIMC) {
  2157. return;
  2158. }
  2159. hCompWnd = GetCompWnd(hUIWnd);
  2160. if (!hCompWnd) {
  2161. return;
  2162. }
  2163. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2164. if (!lpIMC) {
  2165. return;
  2166. }
  2167. SetCompPosition(hCompWnd, lpIMC);
  2168. ImmUnlockIMC(hIMC);
  2169. return;
  2170. }
  2171. /**********************************************************************/
  2172. /* MoveDefaultCompPosition() */
  2173. /**********************************************************************/
  2174. void PASCAL MoveDefaultCompPosition( // the default comp position
  2175. // need to near the caret
  2176. HWND hUIWnd)
  2177. {
  2178. HIMC hIMC;
  2179. LPINPUTCONTEXT lpIMC;
  2180. HWND hCompWnd;
  2181. if (lpImeL->wImeStyle == IME_APRS_FIX ) return ;
  2182. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2183. if (!hIMC) {
  2184. return;
  2185. }
  2186. hCompWnd = GetCompWnd(hUIWnd);
  2187. if (!hCompWnd) {
  2188. return;
  2189. }
  2190. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2191. if (!lpIMC) {
  2192. return;
  2193. }
  2194. if (lpIMC->cfCompForm.dwStyle & CFS_FORCE_POSITION) {
  2195. } else if (!lpIMC->hPrivate) {
  2196. } else {
  2197. LPPRIVCONTEXT lpImcP;
  2198. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  2199. if (!lpImcP) {
  2200. } else if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONPOS) {
  2201. } else {
  2202. lpImcP->fdwImeMsg |= MSG_IMN_COMPOSITIONPOS;
  2203. // lpImcP->fdwGcsFlag =lpImcP->fdwGcsFlag &~( GCS_RESULTREAD|GCS_RESULTSTR);
  2204. // if(sImeG.InbxProc){
  2205. /* sImeG.InbxProc = 0;*///}
  2206. // else{
  2207. // GenerateMessage(hIMC, lpIMC, lpImcP);//} //CHG4
  2208. }
  2209. ImmUnlockIMCC(lpIMC->hPrivate);
  2210. }
  2211. ImmUnlockIMC(hIMC);
  2212. return;
  2213. }
  2214. /**********************************************************************/
  2215. /* ShowComp() */
  2216. /**********************************************************************/
  2217. void PASCAL ShowComp( // Show the composition window
  2218. HWND hUIWnd,
  2219. int nShowCompCmd)
  2220. {
  2221. HGLOBAL hUIPrivate;
  2222. LPUIPRIV lpUIPrivate;
  2223. // show or hid the UI window
  2224. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2225. if (!hUIPrivate) {
  2226. return;
  2227. }
  2228. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2229. if (!lpUIPrivate) {
  2230. return;
  2231. }
  2232. if (!lpUIPrivate->hCompWnd) {
  2233. // not in show candidate window mode
  2234. } else if (lpUIPrivate->nShowCompCmd != nShowCompCmd) {
  2235. ShowWindow(lpUIPrivate->hCompWnd, nShowCompCmd);
  2236. lpUIPrivate->nShowCompCmd = nShowCompCmd;
  2237. } else {
  2238. }
  2239. GlobalUnlock(hUIPrivate);
  2240. return;
  2241. }
  2242. /**********************************************************************/
  2243. /* StartComp() */
  2244. /**********************************************************************/
  2245. void PASCAL StartComp(
  2246. HWND hUIWnd)
  2247. {
  2248. HIMC hIMC;
  2249. HGLOBAL hUIPrivate;
  2250. LPINPUTCONTEXT lpIMC;
  2251. LPUIPRIV lpUIPrivate;
  2252. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2253. if (!hIMC) { // Oh! Oh!
  2254. return;
  2255. }
  2256. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2257. if (!hUIPrivate) { // Oh! Oh!
  2258. return;
  2259. }
  2260. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2261. if (!lpIMC) { // Oh! Oh!
  2262. return;
  2263. }
  2264. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2265. if (!lpUIPrivate) { // can not draw composition window
  2266. ImmUnlockIMC(hIMC);
  2267. return;
  2268. }
  2269. lpUIPrivate->fdwSetContext |= ISC_SHOWUICOMPOSITIONWINDOW;//zl 95.9.14
  2270. if (!lpUIPrivate->hCompWnd) {
  2271. lpUIPrivate->hCompWnd = CreateWindowEx(
  2272. /* WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME|WS_EX_TOPMOST,*/
  2273. 0,
  2274. szCompClassName, NULL, WS_POPUP|WS_DISABLED,//|WS_BORDER,
  2275. 0, 0, lpImeL->xCompWi, lpImeL->yCompHi,
  2276. hUIWnd, (HMENU)NULL, hInst, NULL);
  2277. if ( lpUIPrivate->hCompWnd != NULL )
  2278. {
  2279. SetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_OFFSET,
  2280. WINDOW_NOT_DRAG);
  2281. SetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY, 0L);
  2282. }
  2283. }
  2284. // try to set the position of composition UI window near the caret
  2285. SetCompPosition(lpUIPrivate->hCompWnd, lpIMC);
  2286. ImmUnlockIMC(hIMC);
  2287. ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
  2288. GlobalUnlock(hUIPrivate);
  2289. return;
  2290. }
  2291. /**********************************************************************/
  2292. /* EndComp() */
  2293. /**********************************************************************/
  2294. void PASCAL EndComp(
  2295. HWND hUIWnd)
  2296. {
  2297. HGLOBAL hUIPrivate;
  2298. LPUIPRIV lpUIPrivate;
  2299. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2300. if (!hUIPrivate) { // Oh! Oh!
  2301. return;
  2302. }
  2303. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2304. if (!lpUIPrivate) { // Oh! Oh!
  2305. return;
  2306. }
  2307. // hide the composition window
  2308. ShowWindow(lpUIPrivate->hCompWnd, SW_HIDE);
  2309. lpUIPrivate->nShowCompCmd = SW_HIDE;
  2310. GlobalUnlock(hUIPrivate);
  2311. return;
  2312. }
  2313. /**********************************************************************/
  2314. /* DestroyCompWindow() */
  2315. /**********************************************************************/
  2316. void PASCAL DestroyCompWindow( // destroy composition window
  2317. HWND hCompWnd)
  2318. {
  2319. HGLOBAL hUIPrivate;
  2320. LPUIPRIV lpUIPrivate;
  2321. hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
  2322. IMMGWLP_PRIVATE);
  2323. if (!hUIPrivate) { // Oh! Oh!
  2324. return;
  2325. }
  2326. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2327. if (!lpUIPrivate) { // Oh! Oh!
  2328. return;
  2329. }
  2330. lpUIPrivate->nShowCompCmd = SW_HIDE;
  2331. lpUIPrivate->hCompWnd = (HWND)NULL;
  2332. GlobalUnlock(hUIPrivate);
  2333. return;
  2334. }
  2335. /**********************************************************************/
  2336. /* CompSetCursor() */
  2337. /**********************************************************************/
  2338. void PASCAL CompSetCursor(
  2339. HWND hCompWnd,
  2340. LPARAM lParam)
  2341. {
  2342. POINT ptCursor;
  2343. RECT rcWnd;
  2344. if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  2345. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  2346. return;
  2347. }
  2348. GetCursorPos(&ptCursor);
  2349. ScreenToClient(hCompWnd, &ptCursor);
  2350. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  2351. if (HIWORD(lParam) == WM_RBUTTONDOWN) {
  2352. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  2353. return;
  2354. } else if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  2355. // start dragging
  2356. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  2357. } else {
  2358. return;
  2359. }
  2360. SetCapture(hCompWnd);
  2361. GetCursorPos(&ptCursor);
  2362. SetWindowLong(hCompWnd, UI_MOVE_XY,
  2363. MAKELONG(ptCursor.x, ptCursor.y));
  2364. GetWindowRect(hCompWnd, &rcWnd);
  2365. SetWindowLong(hCompWnd, UI_MOVE_OFFSET,
  2366. MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top));
  2367. DrawDragBorder(hCompWnd, MAKELONG(ptCursor.x, ptCursor.y),
  2368. GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
  2369. return;
  2370. }
  2371. /**********************************************************************/
  2372. /* CompButtonUp() */
  2373. /**********************************************************************/
  2374. BOOL PASCAL CompButtonUp( // finish drag, set comp window to this
  2375. // position
  2376. HWND hCompWnd)
  2377. {
  2378. LONG lTmpCursor, lTmpOffset;
  2379. POINT pt;
  2380. HWND hUIWnd;
  2381. HIMC hIMC;
  2382. LPINPUTCONTEXT lpIMC;
  2383. HWND hFocusWnd;
  2384. COMPOSITIONFORM cfCompForm;
  2385. if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
  2386. return (FALSE);
  2387. }
  2388. lTmpCursor = GetWindowLong(hCompWnd, UI_MOVE_XY);
  2389. pt.x = (*(LPPOINTS)&lTmpCursor).x;
  2390. pt.y = (*(LPPOINTS)&lTmpCursor).y;
  2391. // calculate the org by the offset
  2392. lTmpOffset = GetWindowLong(hCompWnd, UI_MOVE_OFFSET);
  2393. pt.x -= (*(LPPOINTS)&lTmpOffset).x;
  2394. pt.y -= (*(LPPOINTS)&lTmpOffset).y;
  2395. DrawDragBorder(hCompWnd, lTmpCursor, lTmpOffset);
  2396. SetWindowLong(hCompWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  2397. ReleaseCapture();
  2398. hUIWnd = GetWindow(hCompWnd, GW_OWNER);
  2399. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2400. if (!hIMC) {
  2401. return (FALSE);
  2402. }
  2403. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2404. if (!lpIMC) {
  2405. return (FALSE);
  2406. }
  2407. hFocusWnd = (HWND)lpIMC->hWnd;
  2408. ImmUnlockIMC(hIMC);
  2409. if (pt.x < sImeG.rcWorkArea.left) {
  2410. pt.x = sImeG.rcWorkArea.left;
  2411. } else if (pt.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
  2412. pt.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
  2413. }
  2414. if (pt.y < sImeG.rcWorkArea.top) {
  2415. pt.y = sImeG.rcWorkArea.top;
  2416. } else if (pt.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
  2417. pt.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
  2418. }
  2419. ScreenToClient(hFocusWnd, &pt);
  2420. cfCompForm.dwStyle = CFS_POINT|CFS_FORCE_POSITION;
  2421. cfCompForm.ptCurrentPos.x = pt.x + lpImeL->cxCompBorder;
  2422. cfCompForm.ptCurrentPos.y = pt.y + lpImeL->cyCompBorder;
  2423. // set composition window to the new poosition
  2424. SendMessage(hUIWnd, WM_IME_CONTROL, IMC_SETCOMPOSITIONWINDOW,
  2425. (LPARAM)&cfCompForm);
  2426. return (TRUE);
  2427. }
  2428. #define SHENHUI RGB(0x80,0x80,0x80)
  2429. #define QIANHUI RGB(0xe0,0xe0,0x80)
  2430. /**********************************************************************/
  2431. /* CurMovePaint() */
  2432. /* Function: While the string is longer than the Comp Window.... */
  2433. /* keep the cursor inside the Comp Window */
  2434. /* Called: By UpdateCompWindow2 */
  2435. /**********************************************************************/
  2436. void WINAPI CurMovePaint(
  2437. HDC hDC,
  2438. LPSTR srBuffer, // the source sting that to be showed...
  2439. int StrLen) // the length of that...
  2440. {
  2441. int i,xx,yy;
  2442. //SetBkColor(hDC, QIANHUI);
  2443. if(!StrLen)
  2444. return;
  2445. for (i=0; i<StrLen; i++)
  2446. InputBuffer[i] = srBuffer[i];
  2447. xx= 0;
  2448. if (InputBuffer[0]>0xa0){
  2449. for (i =0; i<StrLen; i++){
  2450. if(InputBuffer[i]<0xa0) break;
  2451. }
  2452. yy = i;
  2453. for (i=yy; i>0; i=i-2) {
  2454. //xx =sImeG.xChiCharWi*i/2;
  2455. xx=GetText32(hDC,&InputBuffer[0],i);
  2456. if ( xx <= lpImeL->rcCompText.right-4)
  2457. break;
  2458. }
  2459. i=0;
  2460. cur_start_ps=0;
  2461. cur_start_count=0;
  2462. }else {
  2463. for (i =now_cs; i>0; i--){
  2464. yy=GetText32(hDC, &InputBuffer[i-1], 1);
  2465. if ( (xx+yy) >= (lpImeL->rcCompText.right-4))
  2466. break;
  2467. else
  2468. xx+=yy;
  2469. }
  2470. cur_start_count=(WORD)i;
  2471. cur_start_ps=(WORD)GetText32(hDC, &InputBuffer[0], i);
  2472. // true_len = StrLen-cur_start_count ;
  2473. }
  2474. for(i=StrLen-cur_start_count; i>0; i--){
  2475. yy=GetText32(hDC,&InputBuffer[cur_start_count],i);
  2476. if (yy <= lpImeL->rcCompText.right-4)
  2477. break;
  2478. }
  2479. {
  2480. LOGFONT lfFont;
  2481. HGDIOBJ hOldFont;
  2482. int Top = 2;
  2483. if (sImeG.yChiCharHi > 0x10)
  2484. Top = 0;
  2485. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  2486. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  2487. lfFont.lfWeight = FW_DONTCARE;
  2488. SelectObject(hDC, CreateFontIndirect(&lfFont));
  2489. ExtTextOut(hDC,
  2490. lpImeL->rcCompText.left, lpImeL->rcCompText.top + Top,
  2491. ETO_OPAQUE, &lpImeL->rcCompText,
  2492. &InputBuffer[cur_start_count],
  2493. i, NULL);
  2494. DeleteObject(SelectObject(hDC, hOldFont));
  2495. }
  2496. // TextOut(hDC,0,0,&InputBuffer[cur_start_count],
  2497. // (sizeof InputBuffer)-cur_start_count);
  2498. now_cs_dot = xx;
  2499. cur_hibit=0,cur_flag=0;
  2500. return;
  2501. }
  2502. /**********************************************************************/
  2503. /* UpdateCompWindow2() */
  2504. /**********************************************************************/
  2505. void PASCAL UpdateCompWindow2(
  2506. HWND hUIWnd,
  2507. HDC hDC)
  2508. {
  2509. HIMC hIMC;
  2510. LPINPUTCONTEXT lpIMC;
  2511. LPCOMPOSITIONSTRING lpCompStr;
  2512. LPGUIDELINE lpGuideLine;
  2513. BOOL fShowString;
  2514. LOGFONT lfFont;
  2515. HGDIOBJ hOldFont;
  2516. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2517. if (!hIMC) {
  2518. return;
  2519. }
  2520. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2521. if (!lpIMC) {
  2522. return;
  2523. }
  2524. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  2525. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  2526. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  2527. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  2528. lfFont.lfWeight = FW_DONTCARE;
  2529. SelectObject(hDC, CreateFontIndirect(&lfFont));
  2530. SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
  2531. fShowString = (BOOL)0;
  2532. if (lpImeL->wImeStyle == IME_APRS_FIX){
  2533. RECT rcSunken;
  2534. DrawConvexRect(hDC,
  2535. 0,
  2536. 0,
  2537. lpImeL->xCompWi-1,
  2538. lpImeL->yCompHi-1);
  2539. rcSunken.left =0;
  2540. rcSunken.top =0;
  2541. rcSunken.right =lpImeL->xCompWi-1;
  2542. rcSunken.bottom = lpImeL->yCompHi-1;
  2543. // DrawEdge(hDC, &rcSunken, EDGE_RAISED,/*EDGE_SUNKEN,*/ BF_RECT);
  2544. }else
  2545. DrawConvexRect(hDC,
  2546. 0,
  2547. 0,
  2548. lpImeL->xCompWi-1,
  2549. lpImeL->yCompHi-1);
  2550. /* DrawConvexRect(hDC,
  2551. lpImeL->rcCompText.left-4,
  2552. lpImeL->rcCompText.top-4,
  2553. lpImeL->rcCompText.right+4,
  2554. lpImeL->rcCompText.bottom+4); */
  2555. /* DrawConcaveRect(hDC,
  2556. lpImeL->rcCompText.left-1,
  2557. lpImeL->rcCompText.top-1,
  2558. lpImeL->rcCompText.right+1,
  2559. lpImeL->rcCompText.bottom+1); */
  2560. if (!lpGuideLine) {
  2561. } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
  2562. } else if (!lpGuideLine->dwStrLen) {
  2563. if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
  2564. fShowString |= IME_STR_ERROR;
  2565. }
  2566. } else {
  2567. // if there is information string, we will show the information
  2568. // string
  2569. if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
  2570. // red text for error
  2571. SetTextColor(hDC, RGB(0xFF, 0, 0));
  2572. // light gray background for error
  2573. SetBkColor(hDC, QIANHUI);
  2574. }
  2575. ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
  2576. ETO_OPAQUE, &lpImeL->rcCompText,
  2577. (LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
  2578. (UINT)lpGuideLine->dwStrLen, NULL);
  2579. fShowString |= IME_STR_SHOWED;
  2580. }
  2581. if (fShowString & IME_STR_SHOWED) {
  2582. // already show it, don't need to show
  2583. } else if (lpCompStr) {
  2584. // ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
  2585. // ETO_OPAQUE, &lpImeL->rcCompText,
  2586. // (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset,
  2587. // (UINT)lpCompStr->dwCompStrLen, NULL);
  2588. CurMovePaint(hDC,
  2589. (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset,
  2590. (UINT)lpCompStr->dwCompStrLen);
  2591. if (fShowString & IME_STR_ERROR) {
  2592. // red text for error
  2593. SetTextColor(hDC, RGB(0xFF, 0, 0));
  2594. // light gray background for error
  2595. SetBkColor(hDC, QIANHUI);
  2596. ExtTextOut(hDC, lpImeL->rcCompText.left +
  2597. lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
  2598. lpImeL->rcCompText.top,
  2599. ETO_CLIPPED, &lpImeL->rcCompText,
  2600. (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset +
  2601. lpCompStr->dwCursorPos,
  2602. (UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL);
  2603. } else if (lpCompStr->dwCursorPos < lpCompStr->dwCompStrLen) {
  2604. // light gray background for cursor start
  2605. SetBkColor(hDC, QIANHUI);
  2606. ExtTextOut(hDC, lpImeL->rcCompText.left +
  2607. lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
  2608. lpImeL->rcCompText.top,
  2609. ETO_CLIPPED, &lpImeL->rcCompText,
  2610. (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset +
  2611. lpCompStr->dwCursorPos,
  2612. (UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL);
  2613. } else {
  2614. }
  2615. } else {
  2616. ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
  2617. ETO_OPAQUE, &lpImeL->rcCompText,
  2618. (LPSTR)NULL, 0, NULL);
  2619. }
  2620. DeleteObject(SelectObject(hDC, hOldFont));
  2621. ImmUnlockIMCC(lpIMC->hGuideLine);
  2622. ImmUnlockIMCC(lpIMC->hCompStr);
  2623. ImmUnlockIMC(hIMC);
  2624. return;
  2625. }
  2626. /**********************************************************************/
  2627. /* UpdateCompWindow() */
  2628. /**********************************************************************/
  2629. void PASCAL UpdateCompWindow(
  2630. HWND hUIWnd)
  2631. {
  2632. HWND hCompWnd;
  2633. HDC hDC;
  2634. hCompWnd = GetCompWnd(hUIWnd);
  2635. if (!hCompWnd) return ; //Modify 95/7.1
  2636. hDC = GetDC(hCompWnd);
  2637. UpdateCompWindow2(hUIWnd, hDC);
  2638. ReleaseDC(hCompWnd, hDC);
  2639. }
  2640. /**********************************************************************/
  2641. /* UpdateCompCur() */
  2642. /**********************************************************************/
  2643. void PASCAL UpdateCompCur(
  2644. HWND hCompWnd)
  2645. {
  2646. HDC hDC;
  2647. int yy,i;
  2648. HGDIOBJ hOldFont;
  2649. LOGFONT lfFont;
  2650. cur_hibit=1;
  2651. if (!hCompWnd) return ; //Modify 95/7.1
  2652. hDC = GetDC(hCompWnd);
  2653. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  2654. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  2655. lfFont.lfWeight = FW_DONTCARE;
  2656. SelectObject(hDC, CreateFontIndirect(&lfFont));
  2657. SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
  2658. for (i =43-cur_start_count; i>0; i--){
  2659. yy=GetText32(hDC, &InputBuffer[cur_start_count], i);
  2660. if ( yy < lpImeL->rcCompText.right-4)
  2661. break;
  2662. }
  2663. ExtTextOut(hDC,
  2664. lpImeL->rcCompText.left, lpImeL->rcCompText.top,
  2665. ETO_OPAQUE, &lpImeL->rcCompText,
  2666. &InputBuffer[cur_start_count],
  2667. i,
  2668. NULL);
  2669. DeleteObject(SelectObject(hDC, hOldFont));
  2670. ReleaseDC(hCompWnd, hDC);
  2671. cur_hibit=0,cur_flag=0;
  2672. return ;
  2673. }
  2674. /**********************************************************************/
  2675. /* PaintCompWindow() */
  2676. /**********************************************************************/
  2677. void PASCAL PaintCompWindow( // get WM_PAINT message
  2678. HWND hCompWnd)
  2679. {
  2680. HDC hDC;
  2681. PAINTSTRUCT ps;
  2682. RECT pt;
  2683. if(CompWndChange){
  2684. CompWndChange = 0;
  2685. SetCompWindow(GetWindow(hCompWnd,GW_OWNER));
  2686. };
  2687. cur_hibit=1;
  2688. hDC = BeginPaint(hCompWnd, &ps);
  2689. UpdateCompWindow2(GetWindow(hCompWnd, GW_OWNER), hDC);
  2690. EndPaint(hCompWnd, &ps);
  2691. cur_hibit=0,cur_flag=0;
  2692. return;
  2693. }
  2694. /**********************************************************************/
  2695. /* CompWndProc() */
  2696. /**********************************************************************/
  2697. LRESULT CALLBACK CompWndProc( // composition window proc
  2698. HWND hCompWnd,
  2699. UINT uMsg,
  2700. WPARAM wParam,
  2701. LPARAM lParam)
  2702. {
  2703. HDC hDC;
  2704. switch (uMsg) {
  2705. case WM_CREATE:
  2706. hDC=GetDC(hCompWnd);
  2707. hMemoryDC=CreateCompatibleDC(hDC);
  2708. cur_h=LoadBitmap(hInst,CUR_HB);
  2709. ReleaseDC(hCompWnd,hDC);
  2710. SetTimer(hCompWnd ,1,400,(TIMERPROC)NULL);
  2711. ShowCandTimerCount=0;
  2712. break;
  2713. case WM_TIMER:
  2714. hInputWnd = hCompWnd;
  2715. TimerCounter++;
  2716. ShowCandTimerCount++;
  2717. if (TimerCounter==3){
  2718. TimerCounter=0;
  2719. }
  2720. if (!kb_flag) return(0);
  2721. if (cur_hibit||(cap_mode&&(!cur_flag))) return(0);
  2722. DrawInputCur();
  2723. break;
  2724. case WM_DESTROY:
  2725. KillTimer(hCompWnd,1);
  2726. DeleteObject(cur_h);
  2727. DeleteObject(hMemoryDC);
  2728. DestroyCompWindow(hCompWnd);
  2729. break;
  2730. case WM_SETCURSOR:
  2731. CompSetCursor(hCompWnd, lParam);
  2732. break;
  2733. case WM_MOUSEMOVE:
  2734. if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  2735. if(lpImeL->wImeStyle == IME_APRS_AUTO){
  2736. POINT ptCursor;
  2737. DrawDragBorder(hCompWnd,
  2738. GetWindowLong(hCompWnd, UI_MOVE_XY),
  2739. GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
  2740. GetCursorPos(&ptCursor);
  2741. SetWindowLong(hCompWnd, UI_MOVE_XY,
  2742. MAKELONG(ptCursor.x, ptCursor.y));
  2743. DrawDragBorder(hCompWnd, MAKELONG(ptCursor.x, ptCursor.y),
  2744. GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
  2745. }else MessageBeep(0);
  2746. } else {
  2747. return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
  2748. }
  2749. break;
  2750. case WM_LBUTTONUP:
  2751. if (!CompButtonUp(hCompWnd)) {
  2752. return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
  2753. }
  2754. break;
  2755. case WM_SHOWWINDOW:
  2756. if (wParam) cur_hibit = 0;
  2757. else cur_hibit = 1;
  2758. break;
  2759. case WM_PAINT:
  2760. if (wParam == 0xa )
  2761. UpdateCompCur(hCompWnd);
  2762. else
  2763. PaintCompWindow(hCompWnd);
  2764. break;
  2765. case WM_MOUSEACTIVATE:
  2766. return (MA_NOACTIVATE);
  2767. default:
  2768. return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
  2769. }
  2770. return (0L);
  2771. }
  2772. /**********************************************************************/
  2773. /* GetCandWnd */
  2774. /* Return Value : */
  2775. /* window handle of candidatte */
  2776. /**********************************************************************/
  2777. HWND PASCAL GetCandWnd(
  2778. HWND hUIWnd) // UI window
  2779. {
  2780. HGLOBAL hUIPrivate;
  2781. LPUIPRIV lpUIPrivate;
  2782. HWND hCandWnd;
  2783. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2784. if (!hUIPrivate) { // can not darw candidate window
  2785. return (HWND)NULL;
  2786. }
  2787. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2788. if (!lpUIPrivate) { // can not draw candidate window
  2789. return (HWND)NULL;
  2790. }
  2791. hCandWnd = lpUIPrivate->hCandWnd;
  2792. GlobalUnlock(hUIPrivate);
  2793. return (hCandWnd);
  2794. }
  2795. /**********************************************************************/
  2796. /* CalcCandPos */
  2797. /**********************************************************************/
  2798. void PASCAL CalcCandPos2(
  2799. LPPOINT lpptWnd) // the composition window position
  2800. {
  2801. POINT ptNew;
  2802. ptNew.x = lpptWnd->x + UI_MARGIN * 2;
  2803. if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
  2804. // exceed screen width
  2805. ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2;
  2806. }
  2807. ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder;
  2808. if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
  2809. // exceed screen high
  2810. ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
  2811. }
  2812. lpptWnd->x = ptNew.x;
  2813. lpptWnd->y = ptNew.y;
  2814. return;
  2815. }
  2816. /**********************************************************************/
  2817. /* CalcCandPos */
  2818. /**********************************************************************/
  2819. BOOL PASCAL CalcCandPos(
  2820. LPPOINT lpptWnd) // the composition window position
  2821. {
  2822. POINT ptNew;
  2823. ptNew.x = lpptWnd->x + lpImeL->xCompWi + UI_MARGIN * 2;
  2824. if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
  2825. // exceed screen width
  2826. ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2;
  2827. }
  2828. ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder;
  2829. if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
  2830. // exceed screen high
  2831. ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
  2832. }
  2833. lpptWnd->x = ptNew.x;
  2834. lpptWnd->y = ptNew.y;
  2835. return 0;
  2836. }
  2837. /**********************************************************************/
  2838. /* AdjustCandBoundry */
  2839. /**********************************************************************/
  2840. void PASCAL AdjustCandBoundry(
  2841. LPPOINT lpptCandWnd) // the position
  2842. {
  2843. if (lpptCandWnd->x < sImeG.rcWorkArea.left) {
  2844. lpptCandWnd->x = sImeG.rcWorkArea.left;
  2845. } else if (lpptCandWnd->x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
  2846. lpptCandWnd->x = sImeG.rcWorkArea.right - sImeG.xCandWi;
  2847. }
  2848. if (lpptCandWnd->y < sImeG.rcWorkArea.top) {
  2849. lpptCandWnd->y = sImeG.rcWorkArea.top;
  2850. } else if (lpptCandWnd->y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
  2851. lpptCandWnd->y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
  2852. }
  2853. return;
  2854. }
  2855. /**********************************************************************/
  2856. /* GetCandPos() */
  2857. /**********************************************************************/
  2858. LRESULT PASCAL GetCandPos(
  2859. HWND hUIWnd,
  2860. LPCANDIDATEFORM lpCandForm)
  2861. {
  2862. HWND hCandWnd;
  2863. HIMC hIMC;
  2864. LPINPUTCONTEXT lpIMC;
  2865. POINT ptNew;
  2866. //DebugShow("GetCand...%x",hUIWnd);
  2867. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2868. if (!hIMC) {
  2869. return (1L);
  2870. }
  2871. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2872. if (!lpIMC) {
  2873. return (1L);
  2874. }
  2875. if (!(hCandWnd = GetCandWnd(hUIWnd))) {
  2876. return (1L);
  2877. }
  2878. if (lpCandForm->dwStyle & CFS_FORCE_POSITION) {
  2879. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2880. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2881. } else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) {
  2882. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2883. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2884. } else if (lpCandForm->dwStyle & CFS_EXCLUDE) {
  2885. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2886. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2887. }
  2888. ImmUnlockIMC(hIMC);
  2889. return (0L);
  2890. }
  2891. /**********************************************************************/
  2892. /* SetCandPosition() */
  2893. /**********************************************************************/
  2894. LRESULT PASCAL SetCandPosition(
  2895. HWND hUIWnd,
  2896. LPCANDIDATEFORM lpCandForm)
  2897. {
  2898. HWND hCandWnd;
  2899. HIMC hIMC;
  2900. LPINPUTCONTEXT lpIMC;
  2901. POINT ptNew;
  2902. // DebugShow("SetCand...%x",hUIWnd);
  2903. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  2904. if (!hIMC) {
  2905. return (1L);
  2906. }
  2907. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  2908. if (!lpIMC) {
  2909. return (1L);
  2910. }
  2911. if (!(hCandWnd = GetCandWnd(hUIWnd))) {
  2912. return (1L);
  2913. }
  2914. if (lpCandForm->dwStyle & CFS_FORCE_POSITION) {
  2915. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2916. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2917. ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
  2918. //##4
  2919. SetWindowPos(hCandWnd, NULL,
  2920. ptNew.x, ptNew.y,
  2921. sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
  2922. } else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) {
  2923. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2924. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2925. ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
  2926. AdjustCandBoundry(&ptNew);
  2927. // ##5
  2928. SetWindowPos(hCandWnd, NULL,
  2929. ptNew.x, ptNew.y,
  2930. sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
  2931. } else if (lpCandForm->dwStyle & CFS_EXCLUDE) {
  2932. ptNew.x = (int)lpCandForm->ptCurrentPos.x;
  2933. ptNew.y = (int)lpCandForm->ptCurrentPos.y;
  2934. ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
  2935. AdjustCandBoundry(&ptNew);
  2936. // ##6
  2937. SetWindowPos(hCandWnd, NULL,
  2938. ptNew.x, ptNew.y,
  2939. sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
  2940. } else if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) {
  2941. HWND hCompWnd;
  2942. if (hCompWnd = GetCompWnd(hUIWnd)) {
  2943. ptNew.x = 0;
  2944. ptNew.y = 0;
  2945. ClientToScreen(hCompWnd, &ptNew);
  2946. CalcCandPos(&ptNew);
  2947. } else {
  2948. AdjustCandBoundry(&ptNew);
  2949. }
  2950. SetWindowPos(hCandWnd, NULL,
  2951. ptNew.x, ptNew.y,
  2952. sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
  2953. }
  2954. ImmUnlockIMC(hIMC);
  2955. return (0L);
  2956. }
  2957. /**********************************************************************/
  2958. /* ShowCand() */
  2959. /**********************************************************************/
  2960. void PASCAL ShowCand( // Show the candidate window
  2961. HWND hUIWnd,
  2962. int nShowCandCmd)
  2963. {
  2964. HGLOBAL hUIPrivate;
  2965. LPUIPRIV lpUIPrivate;
  2966. // if (ShowCandTimerCount<5) {ShowCandTimerCount = 0; return 0;}
  2967. // ShowCandTimerCount = 0 ;
  2968. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2969. if (!hUIPrivate) { // can not darw candidate window
  2970. return;
  2971. }
  2972. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  2973. if (!lpUIPrivate) { // can not draw candidate window
  2974. return;
  2975. }
  2976. if (!lpUIPrivate->hCandWnd) {
  2977. // not in show candidate window mode
  2978. } else if (lpUIPrivate->nShowCandCmd != nShowCandCmd) {
  2979. ShowWindow(lpUIPrivate->hCandWnd, nShowCandCmd);
  2980. lpUIPrivate->nShowCandCmd = nShowCandCmd;
  2981. } else {
  2982. }
  2983. GlobalUnlock(hUIPrivate);
  2984. return;
  2985. }
  2986. /**********************************************************************/
  2987. /* OpenCand */
  2988. /**********************************************************************/
  2989. void PASCAL OpenCand(
  2990. HWND hUIWnd)
  2991. {
  2992. HGLOBAL hUIPrivate;
  2993. LPUIPRIV lpUIPrivate;
  2994. POINT ptWnd;
  2995. int value;
  2996. // DebugShow("In Open Cand",0);
  2997. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  2998. if (!hUIPrivate) { // can not darw candidate window
  2999. return;
  3000. }
  3001. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  3002. if (!lpUIPrivate) { // can not draw candidate window
  3003. return;
  3004. }
  3005. lpUIPrivate->fdwSetContext |= ISC_SHOWUICANDIDATEWINDOW;
  3006. ptWnd.x = 0;
  3007. ptWnd.y = 0;
  3008. // DebugShow("OpenCand ..->hCompWnd=%X",lpUIPrivate);
  3009. value = ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd);
  3010. // DebugShow("OpenCand ..value", value);
  3011. if (!value){ // if there no Comp wndows
  3012. GetCaretPos(&ptWnd);
  3013. ClientToScreen(GetFocus(),&ptWnd);
  3014. CalcCandPos2(&ptWnd);
  3015. } else {
  3016. ptWnd.x -= lpImeL->cxCompBorder;
  3017. // ptWnd.y -= lpImeL->cyCompBorder;
  3018. CalcCandPos(&ptWnd);
  3019. }
  3020. if (lpImeL->wImeStyle == IME_APRS_FIX) {
  3021. ptWnd.x = lpImeL->ptDefCand.x;
  3022. ptWnd.y = lpImeL->ptDefCand.y;
  3023. }
  3024. // ##7
  3025. if (lpUIPrivate->hCandWnd) {
  3026. SetWindowPos(lpUIPrivate->hCandWnd, NULL,
  3027. ptWnd.x, ptWnd.y,
  3028. sImeG.xCandWi, sImeG.yCandHi,
  3029. SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
  3030. } else {
  3031. lpUIPrivate->hCandWnd = CreateWindowEx(
  3032. /* WS_EX_TOPMOST*/ /*|*/ /* WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE/*|WS_EX_DLGMODALFRAME*/
  3033. 0,
  3034. szCandClassName, NULL, WS_POPUP|WS_DISABLED, //|WS_BORDER,
  3035. ptWnd.x,
  3036. ptWnd.y,
  3037. sImeG.xCandWi, sImeG.yCandHi,
  3038. hUIWnd, (HMENU)NULL, hInst, NULL);
  3039. if ( lpUIPrivate->hCandWnd )
  3040. {
  3041. SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_OFFSET,
  3042. WINDOW_NOT_DRAG);
  3043. SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_XY, 0L);
  3044. }
  3045. }
  3046. ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
  3047. GlobalUnlock(hUIPrivate);
  3048. return;
  3049. }
  3050. /**********************************************************************/
  3051. /* CloseCand */
  3052. /**********************************************************************/
  3053. void PASCAL CloseCand(
  3054. HWND hUIWnd)
  3055. {
  3056. HGLOBAL hUIPrivate;
  3057. LPUIPRIV lpUIPrivate;
  3058. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  3059. if (!hUIPrivate) { // can not darw candidate window
  3060. return;
  3061. }
  3062. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  3063. if (!lpUIPrivate) { // can not draw candidate window
  3064. return;
  3065. }
  3066. ShowWindow(lpUIPrivate->hCandWnd, SW_HIDE);
  3067. lpUIPrivate->nShowCandCmd = SW_HIDE;
  3068. GlobalUnlock(hUIPrivate);
  3069. return;
  3070. }
  3071. /**********************************************************************/
  3072. /* DestroyCandWindow */
  3073. /**********************************************************************/
  3074. void PASCAL DestroyCandWindow(
  3075. HWND hCandWnd)
  3076. {
  3077. HGLOBAL hUIPrivate;
  3078. LPUIPRIV lpUIPrivate;
  3079. hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER),
  3080. IMMGWLP_PRIVATE);
  3081. if (!hUIPrivate) { // can not darw candidate window
  3082. return;
  3083. }
  3084. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  3085. if (!lpUIPrivate) { // can not draw candidate window
  3086. return;
  3087. }
  3088. lpUIPrivate->nShowCandCmd = SW_HIDE;
  3089. lpUIPrivate->hCandWnd = (HWND)NULL;
  3090. GlobalUnlock(hUIPrivate);
  3091. return;
  3092. }
  3093. /**********************************************************************/
  3094. /* MouseSelectCandStr() */
  3095. /**********************************************************************/
  3096. void PASCAL MouseSelectCandStr(
  3097. HWND hCandWnd,
  3098. LPPOINT lpCursor)
  3099. {
  3100. HIMC hIMC;
  3101. LPINPUTCONTEXT lpIMC;
  3102. LPCANDIDATEINFO lpCandInfo;
  3103. LPCANDIDATELIST lpCandList;
  3104. DWORD dwValue, value = 0 ;
  3105. hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
  3106. if (!hIMC) {
  3107. return;
  3108. }
  3109. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  3110. if (!lpIMC) {
  3111. return;
  3112. }
  3113. if (!lpIMC->hCandInfo) {
  3114. ImmUnlockIMC(hIMC);
  3115. return;
  3116. }
  3117. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  3118. if (!lpCandInfo) {
  3119. ImmUnlockIMC(hIMC);
  3120. return;
  3121. }
  3122. if (PtInRect(&sImeG.rcHome, *lpCursor))
  3123. value = VK_HOME*0x100;
  3124. if (PtInRect(&sImeG.rcEnd, *lpCursor))
  3125. value = VK_END*0x100;
  3126. if (PtInRect(&sImeG.rcPageUp, *lpCursor))
  3127. value = VK_PRIOR*0x100;
  3128. if (PtInRect(&sImeG.rcPageDown, *lpCursor))
  3129. value = VK_NEXT*0x100;
  3130. if (PtInRect(&sImeG.rcCandText, *lpCursor)){
  3131. if (lpImeL->wImeStyle == IME_APRS_AUTO )
  3132. value = 0x8030 + 1 + (lpCursor->y - sImeG.rcCandText.top) / sImeG.yChiCharHi;
  3133. else
  3134. value = 0x8030+1+ (lpCursor->x - sImeG.rcCandText.left)/
  3135. (sImeG.xChiCharWi*unit_length/2+ sImeG.Ajust);
  3136. }
  3137. if(value) {
  3138. LPPRIVCONTEXT lpImcP;
  3139. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  3140. lpImcP->fdwImeMsg =lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  3141. ImmUnlockIMCC(lpIMC->hPrivate);
  3142. NotifyIME(hIMC, NI_SELECTCANDIDATESTR, 0, value);
  3143. }
  3144. ImmUnlockIMCC(lpIMC->hCandInfo);
  3145. ImmUnlockIMC(hIMC);
  3146. return;
  3147. }
  3148. /**********************************************************************/
  3149. /* CandSetCursor() */
  3150. /**********************************************************************/
  3151. void PASCAL CandSetCursor(
  3152. HWND hCandWnd,
  3153. LPARAM lParam)
  3154. {
  3155. POINT ptCursor;
  3156. RECT rcWnd;
  3157. if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  3158. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  3159. return;
  3160. }
  3161. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  3162. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  3163. GetCursorPos(&ptCursor);
  3164. ScreenToClient(hCandWnd, &ptCursor);
  3165. if (PtInRect(&sImeG.rcCandText, ptCursor)||
  3166. PtInRect(&sImeG.rcHome, ptCursor)||
  3167. PtInRect(&sImeG.rcEnd, ptCursor)||
  3168. PtInRect(&sImeG.rcPageUp, ptCursor)||
  3169. PtInRect(&sImeG.rcPageDown, ptCursor)) {
  3170. SetCursor(LoadCursor(hInst, szHandCursor));
  3171. MouseSelectCandStr(hCandWnd, &ptCursor);
  3172. return;
  3173. } else {
  3174. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  3175. }
  3176. } else {
  3177. GetCursorPos(&ptCursor);
  3178. ScreenToClient(hCandWnd, &ptCursor);
  3179. if (PtInRect(&sImeG.rcCandText, ptCursor)||
  3180. PtInRect(&sImeG.rcHome, ptCursor)||
  3181. PtInRect(&sImeG.rcEnd, ptCursor)||
  3182. PtInRect(&sImeG.rcPageUp, ptCursor)||
  3183. PtInRect(&sImeG.rcPageDown, ptCursor)) {
  3184. SetCursor(LoadCursor(hInst, szHandCursor));
  3185. } else {
  3186. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  3187. }
  3188. return;
  3189. }
  3190. SetCapture(hCandWnd);
  3191. GetCursorPos(&ptCursor);
  3192. SetWindowLong(hCandWnd, UI_MOVE_XY,
  3193. MAKELONG(ptCursor.x, ptCursor.y));
  3194. GetWindowRect(hCandWnd, &rcWnd);
  3195. SetWindowLong(hCandWnd, UI_MOVE_OFFSET,
  3196. MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top));
  3197. DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
  3198. GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
  3199. return;
  3200. }
  3201. /**********************************************************************/
  3202. /* CandButtonUp() */
  3203. /**********************************************************************/
  3204. BOOL PASCAL CandButtonUp(
  3205. HWND hCandWnd)
  3206. {
  3207. LONG lTmpCursor, lTmpOffset;
  3208. POINT pt;
  3209. HWND hUIWnd;
  3210. HIMC hIMC;
  3211. LPINPUTCONTEXT lpIMC;
  3212. HWND hFocusWnd;
  3213. CANDIDATEFORM cfCandForm;
  3214. if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
  3215. return (FALSE);
  3216. }
  3217. lTmpCursor = GetWindowLong(hCandWnd, UI_MOVE_XY);
  3218. pt.x = (*(LPPOINTS)&lTmpCursor).x;
  3219. pt.y = (*(LPPOINTS)&lTmpCursor).y;
  3220. // calculate the org by the offset
  3221. lTmpOffset = GetWindowLong(hCandWnd, UI_MOVE_OFFSET);
  3222. pt.x -= (*(LPPOINTS)&lTmpOffset).x;
  3223. pt.y -= (*(LPPOINTS)&lTmpOffset).y;
  3224. DrawDragBorder(hCandWnd, lTmpCursor, lTmpOffset);
  3225. SetWindowLong(hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  3226. ReleaseCapture();
  3227. hUIWnd = GetWindow(hCandWnd, GW_OWNER);
  3228. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  3229. if (!hIMC) {
  3230. return (FALSE);
  3231. }
  3232. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  3233. if (!lpIMC) {
  3234. return (FALSE);
  3235. }
  3236. hFocusWnd = lpIMC->hWnd;
  3237. ImmUnlockIMC(hIMC);
  3238. AdjustCandBoundry(&pt);
  3239. ScreenToClient(hFocusWnd, &pt);
  3240. cfCandForm.dwStyle = CFS_CANDIDATEPOS;
  3241. cfCandForm.ptCurrentPos.x = pt.x;
  3242. cfCandForm.ptCurrentPos.y = pt.y;
  3243. SendMessage(hUIWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS,
  3244. (LPARAM)&cfCandForm);
  3245. return (TRUE);
  3246. }
  3247. /**********************************************************************/
  3248. /* PaintOP() */
  3249. /**********************************************************************/
  3250. void PASCAL PaintOP(
  3251. HDC hDC,
  3252. HWND hWnd)
  3253. {
  3254. RECT rcSunken;
  3255. int x1,y1,x2,y2;
  3256. rcSunken = sImeG.rcCandText;
  3257. x1=rcSunken.left-2;
  3258. y1=rcSunken.top-1;//2;
  3259. x2=rcSunken.right+7;
  3260. y2=rcSunken.bottom+5;
  3261. rcSunken.left =x1;
  3262. rcSunken.top =y1;
  3263. rcSunken.right =x2;
  3264. rcSunken.bottom = y2;
  3265. // ShowBitmap(hDC,x2-50,y2,49,20, szUpDown);
  3266. if(lpImeL->wImeStyle == IME_APRS_AUTO ){
  3267. DrawConvexRect(hDC,0,0,sImeG.xCandWi-1, sImeG.yCandHi-1);
  3268. // DrawConcaveRect(hDC ,x1,y1,x2,y2);
  3269. if(bx_inpt_on){
  3270. ShowBitmap2(hDC,
  3271. sImeG.xCandWi/2-25,
  3272. sImeG.rcHome.top,
  3273. 50,
  3274. 15,
  3275. sImeG.SnumbBmp);
  3276. }else {
  3277. ShowBitmap2(hDC,
  3278. sImeG.xCandWi/2-25,
  3279. sImeG.rcHome.top,
  3280. 50,
  3281. 15,
  3282. sImeG.NumbBmp);
  3283. }
  3284. ShowBitmap2(hDC,
  3285. sImeG.rcHome.left,
  3286. sImeG.rcHome.top,
  3287. 14,
  3288. 14,
  3289. sImeG.HomeBmp);
  3290. ShowBitmap2(hDC,
  3291. sImeG.rcEnd.left,
  3292. sImeG.rcEnd.top,
  3293. 14,
  3294. 14,
  3295. sImeG.EndBmp);
  3296. ShowBitmap2(hDC,
  3297. sImeG.rcPageUp.left,
  3298. sImeG.rcPageUp.top,
  3299. 14,
  3300. 14,
  3301. sImeG.PageUpBmp);
  3302. ShowBitmap2(hDC,
  3303. sImeG.rcPageDown.left,
  3304. sImeG.rcPageDown.top,
  3305. 14,
  3306. 14,
  3307. sImeG.PageDownBmp);
  3308. }else{
  3309. ShowBitmap2(hDC,
  3310. sImeG.rcHome.left,
  3311. sImeG.rcHome.top,
  3312. 14,
  3313. 14,
  3314. sImeG.Home2Bmp);
  3315. ShowBitmap2(hDC,
  3316. sImeG.rcEnd.left,
  3317. sImeG.rcEnd.top,
  3318. 14,
  3319. 14,
  3320. sImeG.End2Bmp);
  3321. ShowBitmap2(hDC,
  3322. sImeG.rcPageUp.left,
  3323. sImeG.rcPageUp.top,
  3324. 14,
  3325. 14,
  3326. sImeG.PageUp2Bmp);
  3327. ShowBitmap2(hDC,
  3328. sImeG.rcPageDown.left,
  3329. sImeG.rcPageDown.top,
  3330. 14,
  3331. 14,
  3332. sImeG.PgDown2Bmp);
  3333. }
  3334. return ;
  3335. }
  3336. int keep =9;
  3337. /**********************************************************************/
  3338. /* UpdateCandWindow() */
  3339. /**********************************************************************/
  3340. void PASCAL UpdateCandWindow2(
  3341. HWND hCandWnd,
  3342. HDC hDC)
  3343. {
  3344. HIMC hIMC;
  3345. LPINPUTCONTEXT lpIMC;
  3346. LPCANDIDATEINFO lpCandInfo;
  3347. LPCANDIDATELIST lpCandList;
  3348. LPPRIVCONTEXT lpImcP;
  3349. DWORD dwStart, dwEnd;
  3350. TCHAR szStrBuf[30* sizeof(WCHAR) / sizeof(TCHAR)];
  3351. int i , LenOfAll;
  3352. HGDIOBJ hOldFont;
  3353. LOGFONT lfFont;
  3354. hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
  3355. if (!hIMC) {
  3356. return;
  3357. }
  3358. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  3359. if (!lpIMC) {
  3360. return;
  3361. }
  3362. if (!lpIMC->hCandInfo) {
  3363. ImmUnlockIMC(hIMC);
  3364. return ;
  3365. }
  3366. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  3367. if (!lpCandInfo) {
  3368. ImmUnlockIMC(hIMC);
  3369. return ;
  3370. }
  3371. if (!lpIMC->hPrivate) {
  3372. ImmUnlockIMCC(lpIMC->hCandInfo);
  3373. ImmUnlockIMC(hIMC);
  3374. return;
  3375. }
  3376. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  3377. if (!lpImcP) {
  3378. ImmUnlockIMCC(lpIMC->hCandInfo);
  3379. ImmUnlockIMC(hIMC);
  3380. return;
  3381. }
  3382. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  3383. lpCandInfo->dwOffset[0]);
  3384. if(lpImeL->wImeStyle == IME_APRS_FIX)
  3385. lpCandList->dwPageSize = now.fmt_group;
  3386. else
  3387. lpCandList->dwPageSize = CANDPERPAGE ;
  3388. if (!lpCandList->dwPageSize)
  3389. lpCandList->dwPageSize = keep;
  3390. keep = lpCandList->dwPageSize;
  3391. dwStart = lpCandList->dwSelection /
  3392. lpCandList->dwPageSize * lpCandList->dwPageSize;
  3393. dwEnd = dwStart + lpCandList->dwPageSize;
  3394. if (dwEnd > lpCandList->dwCount) {
  3395. dwEnd = lpCandList->dwCount;
  3396. }
  3397. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  3398. GetObject(hOldFont, sizeof(lfFont), &lfFont);
  3399. lfFont.lfWeight = FW_DONTCARE;
  3400. SelectObject(hDC, CreateFontIndirect(&lfFont));
  3401. if(lpImeL->wImeStyle != IME_APRS_FIX){
  3402. PaintOP(hDC,hCandWnd);
  3403. if (lpImcP->iImeState == CST_INIT) {
  3404. // phrase prediction
  3405. SetTextColor(hDC, RGB(0x00, 0x80, 0x00));
  3406. } else if (lpImcP->iImeState != CST_CHOOSE) {
  3407. // quick key
  3408. SetTextColor(hDC, RGB(0x80, 0x00, 0x80));
  3409. } else {
  3410. }
  3411. SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));
  3412. sImeG.rcCandText.bottom+=3;
  3413. ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top,
  3414. ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
  3415. sImeG.rcCandText.bottom-=3;
  3416. szStrBuf[0] = '1';
  3417. szStrBuf[1] = ':';
  3418. for (i = 0; dwStart < dwEnd; dwStart++, i++) {
  3419. int iLen;
  3420. szStrBuf[0] = szDigit[i + CAND_START];
  3421. iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
  3422. lpCandList->dwOffset[dwStart]));
  3423. // according to init.c, 7 DBCS char
  3424. if (iLen > 6 * sizeof(WCHAR) / sizeof(TCHAR)) {
  3425. iLen = 6 * sizeof(WCHAR) / sizeof(TCHAR);
  3426. CopyMemory(&szStrBuf[2],
  3427. ((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]),
  3428. iLen * sizeof(TCHAR) - sizeof(TCHAR) * 2);
  3429. // maybe not good for UNICODE
  3430. szStrBuf[iLen] = '.';
  3431. szStrBuf[iLen + 1] = '.';
  3432. } else {
  3433. CopyMemory(&szStrBuf[2],
  3434. ((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]),
  3435. iLen);
  3436. }
  3437. ExtTextOut(hDC, sImeG.rcCandText.left,
  3438. sImeG.rcCandText.top + i * sImeG.yChiCharHi,
  3439. (UINT)0, NULL,
  3440. szStrBuf,
  3441. iLen + 2, NULL);
  3442. }
  3443. } else {
  3444. PaintOP(hDC,hCandWnd);
  3445. SetTextColor(hDC, RGB(0xa0, 0x00, 0x80));
  3446. SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));
  3447. ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top,
  3448. ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
  3449. szStrBuf[0] = '1';
  3450. szStrBuf[1] = ':';
  3451. LenOfAll = 0;
  3452. for (i = 0; dwStart < dwEnd; dwStart++, i++) {
  3453. int iLen;
  3454. szStrBuf[LenOfAll++] = szDigit[i + CAND_START];
  3455. szStrBuf[LenOfAll++] = '.' ;
  3456. iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
  3457. lpCandList->dwOffset[dwStart]));
  3458. CopyMemory(&szStrBuf[LenOfAll],
  3459. ((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
  3460. iLen);
  3461. LenOfAll += iLen;
  3462. szStrBuf[LenOfAll] = '.';
  3463. szStrBuf[LenOfAll] = '.';
  3464. }
  3465. DrawConvexRect(hDC,0,0,sImeG.xCandWi-1,sImeG.yCandHi-1); //zl
  3466. PaintOP(hDC,hCandWnd);
  3467. {
  3468. int TopOfText = 2;
  3469. if (sImeG.yChiCharHi >0x10)
  3470. TopOfText = 0;
  3471. ExtTextOut(hDC, sImeG.rcCandText.left,
  3472. sImeG.rcCandText.top + TopOfText,
  3473. (UINT)0, NULL,
  3474. szStrBuf,
  3475. LenOfAll, NULL);
  3476. }
  3477. }
  3478. DeleteObject(SelectObject(hDC, hOldFont));
  3479. ImmUnlockIMCC(lpIMC->hPrivate);
  3480. ImmUnlockIMCC(lpIMC->hCandInfo);
  3481. ImmUnlockIMC(hIMC);
  3482. return;
  3483. }
  3484. /**********************************************************************/
  3485. /* PaintCandWindow() */
  3486. /**********************************************************************/
  3487. void PASCAL PaintCandWindow( // handle WM_PAINT message
  3488. HWND hCandWnd)
  3489. {
  3490. HDC hDC;
  3491. PAINTSTRUCT ps;
  3492. hDC = BeginPaint(hCandWnd, &ps);
  3493. UpdateCandWindow2(hCandWnd, hDC);
  3494. EndPaint(hCandWnd, &ps);
  3495. return;
  3496. }
  3497. /**********************************************************************/
  3498. /* CandWndProc() */
  3499. /**********************************************************************/
  3500. LRESULT CALLBACK CandWndProc(
  3501. HWND hCandWnd,
  3502. UINT uMsg,
  3503. WPARAM wParam,
  3504. LPARAM lParam)
  3505. {
  3506. switch (uMsg) {
  3507. case WM_CREATE:
  3508. sImeG.HomeBmp = LoadBitmap(hInst, szHome); //zl
  3509. sImeG.EndBmp = LoadBitmap(hInst, szEnd);
  3510. sImeG.PageUpBmp = LoadBitmap(hInst, szPageUp);
  3511. sImeG.PageDownBmp = LoadBitmap(hInst, szPageDown);
  3512. sImeG.NumbBmp = LoadBitmap(hInst, szNumb);
  3513. sImeG.SnumbBmp = LoadBitmap(hInst, szSnumb);
  3514. sImeG.Home2Bmp = LoadBitmap(hInst, szHome2);
  3515. sImeG.End2Bmp = LoadBitmap(hInst, szEnd2);
  3516. sImeG.PageUp2Bmp = LoadBitmap(hInst, szPageUp2);
  3517. sImeG.PgDown2Bmp = LoadBitmap(hInst, szPgDown2);
  3518. break;
  3519. case WM_DESTROY:
  3520. DeleteObject(sImeG.HomeBmp);
  3521. DeleteObject(sImeG.EndBmp);
  3522. DeleteObject(sImeG.PageUpBmp);
  3523. DeleteObject(sImeG.PageDownBmp);
  3524. DeleteObject(sImeG.NumbBmp );
  3525. DeleteObject(sImeG.SnumbBmp );
  3526. DeleteObject(sImeG.Home2Bmp);
  3527. DeleteObject(sImeG.End2Bmp);
  3528. DeleteObject(sImeG.PageUp2Bmp);
  3529. DeleteObject(sImeG.PgDown2Bmp);
  3530. DestroyCandWindow(hCandWnd);
  3531. break;
  3532. case WM_SETCURSOR:
  3533. CandSetCursor(hCandWnd, lParam);
  3534. break;
  3535. case WM_MOUSEMOVE:
  3536. if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  3537. POINT ptCursor;
  3538. if (lpImeL->wImeStyle == IME_APRS_AUTO){
  3539. DrawDragBorder(hCandWnd,
  3540. GetWindowLong(hCandWnd, UI_MOVE_XY),
  3541. GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
  3542. GetCursorPos(&ptCursor);
  3543. SetWindowLong(hCandWnd, UI_MOVE_XY,
  3544. MAKELONG(ptCursor.x, ptCursor.y));
  3545. DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
  3546. GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
  3547. }else MessageBeep(0);
  3548. } else {
  3549. return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
  3550. }
  3551. break;
  3552. case WM_LBUTTONUP:
  3553. if (!CandButtonUp(hCandWnd)) {
  3554. return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
  3555. }
  3556. break;
  3557. case WM_PAINT:
  3558. InvalidateRect(hCandWnd,0,1);
  3559. PaintCandWindow(hCandWnd);
  3560. break;
  3561. case WM_MOUSEACTIVATE:
  3562. return (MA_NOACTIVATE);
  3563. /* case WM_IME_NOTIFY:
  3564. if (wParam != IMN_SETCANDIDATEPOS) {
  3565. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  3566. } else if (lParam & 0x0001) {
  3567. return SetCandPosition(hCandWnd);
  3568. } else {
  3569. }
  3570. break;*/
  3571. default:
  3572. return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
  3573. }
  3574. return (0L);
  3575. }
  3576. /**********************************************************************/
  3577. /* ImeInquire() */
  3578. /* Return Value: */
  3579. /* TRUE - successful, FALSE - failure */
  3580. /**********************************************************************/
  3581. BOOL WINAPI ImeInquire( // initialized data structure of IME
  3582. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  3583. LPTSTR lpszWndCls, // the class name of UI
  3584. DWORD dwSystemInfoFlags)
  3585. {
  3586. if (!lpImeInfo) {
  3587. return (FALSE);
  3588. }
  3589. lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
  3590. lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|IME_PROP_IGNORE_UPKEYS|IME_PROP_CANDLIST_START_FROM_1;
  3591. lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|
  3592. /* IME_CMODE_CHARCODE|*/IME_CMODE_SOFTKBD|IME_CMODE_NOCONVERSION/*|
  3593. IME_CMODE_EUDC*/;
  3594. lpImeInfo->fdwSentenceCaps = TRUE;
  3595. // IME will have different distance base multiple of 900 escapement
  3596. lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD;
  3597. // composition string is the reading string for simple IME
  3598. lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD;
  3599. // IME want to decide conversion mode on ImeSelect
  3600. lpImeInfo->fdwSelectCaps = (DWORD)0;
  3601. lstrcpy(lpszWndCls, (LPSTR)szUIClassName);
  3602. if ( lpImeL )
  3603. {
  3604. if ( dwSystemInfoFlags & IME_SYSINFO_WINLOGON )
  3605. {
  3606. // the client app is running in logon mode.
  3607. lpImeL->fWinLogon = TRUE;
  3608. }
  3609. else
  3610. lpImeL->fWinLogon = FALSE;
  3611. }
  3612. return (TRUE);
  3613. }
  3614. INT_PTR CALLBACK ConfigDlgProc( // dialog procedure of configuration
  3615. HWND hDlg,
  3616. UINT uMessage,
  3617. WORD wParam,
  3618. LONG lParam)
  3619. {
  3620. return (TRUE);
  3621. }
  3622. /**********************************************************************/
  3623. /* ImeConfigure() */
  3624. /* Return Value: */
  3625. /* TRUE - successful, FALSE - failure */
  3626. /**********************************************************************/
  3627. BOOL WINAPI ImeConfigure( // configurate the IME setting
  3628. HKL hKL, // hKL of this IME
  3629. HWND hAppWnd, // the owner window
  3630. DWORD dwMode,
  3631. LPVOID lpData) // mode of dialog
  3632. {
  3633. switch (dwMode) {
  3634. case IME_CONFIG_GENERAL:
  3635. DoPropertySheet(hAppWnd,NULL);
  3636. ReInitIme(hAppWnd,lpImeL->wImeStyle); //#@1
  3637. break;
  3638. default:
  3639. return (FALSE);
  3640. break;
  3641. }
  3642. return (TRUE);
  3643. }
  3644. /**********************************************************************/
  3645. /* ImeConversionList() */
  3646. /**********************************************************************/
  3647. DWORD WINAPI ImeConversionList(
  3648. HIMC hIMC,
  3649. LPCTSTR lpszSrc,
  3650. LPCANDIDATELIST lpCandList,
  3651. DWORD uBufLen,
  3652. UINT uFlag)
  3653. {
  3654. return (UINT)0;
  3655. }
  3656. /**********************************************************************/
  3657. /* ImeDestroy() */
  3658. /* Return Value: */
  3659. /* TRUE - successful, FALSE - failure */
  3660. /**********************************************************************/
  3661. BOOL WINAPI ImeDestroy( // this dll is unloaded
  3662. UINT uReserved)
  3663. {
  3664. if (uReserved) {
  3665. return (FALSE);
  3666. }
  3667. // free the IME table or data base
  3668. // FreeTable();
  3669. return (TRUE);
  3670. }
  3671. /**********************************************************************/
  3672. /* SetPrivateSetting() */
  3673. /**********************************************************************/
  3674. void PASCAL SetPrivateFileSetting(
  3675. LPBYTE szBuf,
  3676. int cbBuf,
  3677. DWORD dwOffset,
  3678. LPCTSTR szSettingFile) // file for IME private related settings
  3679. {
  3680. TCHAR szSettingPath[MAX_PATH];
  3681. UINT uLen;
  3682. HANDLE hSettingFile;
  3683. DWORD dwWriteByte;
  3684. return;
  3685. }
  3686. /**********************************************************************/
  3687. /* Input2Sequence */
  3688. /* Return Value: */
  3689. /* LOWORD - Internal Code, HIWORD - sequence code */
  3690. /**********************************************************************/
  3691. LRESULT PASCAL Input2Sequence(
  3692. DWORD uVirtKey,
  3693. LPBYTE lpSeqCode)
  3694. {
  3695. return 0;
  3696. }
  3697. /**********************************************************************/
  3698. /* ImeEscape() */
  3699. /* Return Value: */
  3700. /* TRUE - successful, FALSE - failure */
  3701. /**********************************************************************/
  3702. #define IME_INPUTKEYTOSEQUENCE 0x22
  3703. LRESULT WINAPI ImeEscape( // escape function of IMEs
  3704. HIMC hIMC,
  3705. UINT uSubFunc,
  3706. LPVOID lpData)
  3707. {
  3708. LRESULT lRet;
  3709. switch (uSubFunc) {
  3710. case IME_ESC_QUERY_SUPPORT:
  3711. if ( lpData == NULL )
  3712. return FALSE;
  3713. switch (*(LPUINT)lpData) {
  3714. case IME_ESC_QUERY_SUPPORT:
  3715. case IME_ESC_SEQUENCE_TO_INTERNAL:
  3716. case IME_ESC_GET_EUDC_DICTIONARY:
  3717. case IME_ESC_SET_EUDC_DICTIONARY:
  3718. case IME_INPUTKEYTOSEQUENCE:
  3719. // will not supported in next version
  3720. // and not support 32 bit applications case IME_ESC_MAX_KEY:
  3721. case IME_ESC_IME_NAME:
  3722. case IME_ESC_GETHELPFILENAME:
  3723. return (TRUE);
  3724. default:
  3725. return (FALSE);
  3726. }
  3727. break;
  3728. case IME_ESC_SEQUENCE_TO_INTERNAL:
  3729. lRet = 0;
  3730. return (lRet);
  3731. case IME_ESC_GET_EUDC_DICTIONARY:
  3732. return (FALSE);
  3733. case IME_ESC_SET_EUDC_DICTIONARY:
  3734. return (FALSE);
  3735. case IME_INPUTKEYTOSEQUENCE:
  3736. return 0;
  3737. case IME_ESC_MAX_KEY:
  3738. return (lpImeL->nMaxKey);
  3739. case IME_ESC_IME_NAME:
  3740. {
  3741. TCHAR szIMEName[MAX_PATH];
  3742. if ( lpData == NULL )
  3743. return FALSE;
  3744. LoadString(hInst, IDS_IMENAME, szIMEName, sizeof(szIMEName) );
  3745. lstrcpy(lpData, szIMEName);
  3746. return (TRUE);
  3747. }
  3748. case IME_ESC_GETHELPFILENAME:
  3749. if ( lpData == NULL )
  3750. return FALSE;
  3751. lstrcpy(lpData, TEXT("winabc.hlp") );
  3752. return TRUE;
  3753. default:
  3754. return (FALSE);
  3755. }
  3756. return (lRet);
  3757. }
  3758. /**********************************************************************/
  3759. /* InitCompStr() */
  3760. /**********************************************************************/
  3761. void PASCAL InitCompStr( // init setting for composing string
  3762. LPCOMPOSITIONSTRING lpCompStr)
  3763. {
  3764. if (!lpCompStr) {
  3765. return;
  3766. }
  3767. lpCompStr->dwCompReadAttrLen = 0;
  3768. lpCompStr->dwCompReadClauseLen = 0;
  3769. lpCompStr->dwCompReadStrLen = 0;
  3770. lpCompStr->dwCompAttrLen = 0;
  3771. lpCompStr->dwCompClauseLen = 0;
  3772. lpCompStr->dwCompStrLen = 0;
  3773. lpCompStr->dwCursorPos = 0;
  3774. lpCompStr->dwDeltaStart = 0;
  3775. lpCompStr->dwResultReadClauseLen = 0;
  3776. lpCompStr->dwResultReadStrLen = 0;
  3777. lpCompStr->dwResultClauseLen = 0;
  3778. lpCompStr->dwResultStrLen = 0;
  3779. return;
  3780. }
  3781. /**********************************************************************/
  3782. /* ClearCompStr() */
  3783. /* Return Value: */
  3784. /* TRUE - successful, FALSE - failure */
  3785. /**********************************************************************/
  3786. BOOL PASCAL ClearCompStr(
  3787. LPINPUTCONTEXT lpIMC)
  3788. {
  3789. HIMCC hMem;
  3790. LPCOMPOSITIONSTRING lpCompStr;
  3791. DWORD dwSize =
  3792. // header length
  3793. sizeof(COMPOSITIONSTRING) +
  3794. // composition reading attribute plus NULL terminator
  3795. lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE) +
  3796. // composition reading clause
  3797. sizeof(DWORD) + sizeof(DWORD) +
  3798. // composition reading string plus NULL terminator
  3799. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  3800. // result reading clause
  3801. sizeof(DWORD) + sizeof(DWORD) +
  3802. // result reading string plus NULL terminateor
  3803. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  3804. // result clause
  3805. sizeof(DWORD) + sizeof(DWORD) +
  3806. // result string plus NULL terminateor
  3807. MAXSTRLEN * sizeof(WORD) + sizeof(WORD);
  3808. if (!lpIMC) {
  3809. return (FALSE);
  3810. }
  3811. if (!lpIMC->hCompStr) {
  3812. // it maybe free by other IME, init it
  3813. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  3814. } else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) {
  3815. lpIMC->hCompStr = hMem;
  3816. } else {
  3817. ImmDestroyIMCC(lpIMC->hCompStr);
  3818. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  3819. return (FALSE);
  3820. }
  3821. if (!lpIMC->hCompStr) {
  3822. return (FALSE);
  3823. }
  3824. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  3825. if (!lpCompStr) {
  3826. ImmDestroyIMCC(lpIMC->hCompStr);
  3827. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  3828. return (FALSE);
  3829. }
  3830. lpCompStr->dwSize = dwSize;
  3831. // 1. composition (reading) string - simple IME
  3832. // 2. result reading string
  3833. // 3. result string
  3834. lpCompStr->dwCompReadAttrLen = 0;
  3835. lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING);
  3836. lpCompStr->dwCompReadClauseLen = 0;
  3837. lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset +
  3838. lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE);
  3839. lpCompStr->dwCompReadStrLen = 0;
  3840. lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset +
  3841. sizeof(DWORD) + sizeof(DWORD);
  3842. // composition string is the same with composition reading string
  3843. // for simple IMEs
  3844. lpCompStr->dwCompAttrLen = 0;
  3845. lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset;
  3846. lpCompStr->dwCompClauseLen = 0;
  3847. lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset;
  3848. lpCompStr->dwCompStrLen = 0;
  3849. lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset;
  3850. lpCompStr->dwCursorPos = 0;
  3851. lpCompStr->dwDeltaStart = 0;
  3852. lpCompStr->dwResultReadClauseLen = 0;
  3853. lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset +
  3854. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  3855. lpCompStr->dwResultReadStrLen = 0;
  3856. lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset +
  3857. sizeof(DWORD) + sizeof(DWORD);
  3858. lpCompStr->dwResultClauseLen = 0;
  3859. lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset +
  3860. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  3861. lpCompStr->dwResultStrOffset = 0;
  3862. lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset +
  3863. sizeof(DWORD) + sizeof(DWORD);
  3864. GlobalUnlock((HGLOBAL)lpIMC->hCompStr);
  3865. return (TRUE);
  3866. }
  3867. /**********************************************************************/
  3868. /* ClearCand() */
  3869. /* Return Value: */
  3870. /* TRUE - successful, FALSE - failure */
  3871. /**********************************************************************/
  3872. BOOL PASCAL ClearCand(
  3873. LPINPUTCONTEXT lpIMC)
  3874. {
  3875. HIMCC hMem;
  3876. LPCANDIDATEINFO lpCandInfo;
  3877. LPCANDIDATELIST lpCandList;
  3878. DWORD dwSize =
  3879. // header length
  3880. sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) +
  3881. // candidate string pointers
  3882. sizeof(DWORD) * (MAXCAND) +
  3883. // string plus NULL terminator
  3884. (sizeof(WORD) + sizeof(WORD)) * MAXCAND;
  3885. if (!lpIMC) {
  3886. return (FALSE);
  3887. }
  3888. if (!lpIMC->hCandInfo) {
  3889. // it maybe free by other IME, init it
  3890. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  3891. } else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) {
  3892. lpIMC->hCandInfo = hMem;
  3893. } else {
  3894. ImmDestroyIMCC(lpIMC->hCandInfo);
  3895. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  3896. return (FALSE);
  3897. }
  3898. if (!lpIMC->hCandInfo) {
  3899. return (FALSE);
  3900. }
  3901. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  3902. if (!lpCandInfo) {
  3903. ImmDestroyIMCC(lpIMC->hCandInfo);
  3904. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  3905. return (FALSE);
  3906. }
  3907. // ordering of strings are
  3908. // buffer size
  3909. lpCandInfo->dwSize = dwSize;
  3910. lpCandInfo->dwCount = 0;
  3911. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  3912. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  3913. lpCandInfo->dwOffset[0]);
  3914. // whole candidate info size - header
  3915. lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO);
  3916. lpCandList->dwStyle = IME_CAND_READ;
  3917. lpCandList->dwCount = 0;
  3918. lpCandList->dwSelection = 0;
  3919. lpCandList->dwPageSize = CANDPERPAGE;
  3920. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) +
  3921. sizeof(DWORD) * (MAXCAND - 1);
  3922. ImmUnlockIMCC(lpIMC->hCandInfo);
  3923. return (TRUE);
  3924. }
  3925. /**********************************************************************/
  3926. /* ClearGuideLine() */
  3927. /* Return Value: */
  3928. /* TRUE - successful, FALSE - failure */
  3929. /**********************************************************************/
  3930. BOOL PASCAL ClearGuideLine(
  3931. LPINPUTCONTEXT lpIMC)
  3932. {
  3933. HIMCC hMem;
  3934. LPGUIDELINE lpGuideLine;
  3935. DWORD dwSize = sizeof(GUIDELINE) + sImeG.cbStatusErr;
  3936. if (!lpIMC->hGuideLine) {
  3937. // it maybe free by IME
  3938. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  3939. } else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) {
  3940. lpIMC->hGuideLine = hMem;
  3941. } else {
  3942. ImmDestroyIMCC(lpIMC->hGuideLine);
  3943. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  3944. }
  3945. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  3946. if (!lpGuideLine) {
  3947. return (FALSE);
  3948. }
  3949. lpGuideLine->dwSize = dwSize;
  3950. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  3951. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  3952. lpGuideLine->dwStrLen = 0;
  3953. lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
  3954. CopyMemory((LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
  3955. sImeG.szStatusErr, sImeG.cbStatusErr);
  3956. ImmUnlockIMCC(lpIMC->hGuideLine);
  3957. return (TRUE);
  3958. }
  3959. /**********************************************************************/
  3960. /* InitContext() */
  3961. /**********************************************************************/
  3962. void PASCAL InitContext(
  3963. LPINPUTCONTEXT lpIMC,
  3964. LPPRIVCONTEXT lpImcP)
  3965. {
  3966. //if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
  3967. //} else if (!lpIMC->hWnd) {
  3968. //} else if (lpImcP->fdwInit & INIT_STATUSWNDPOS) {
  3969. //} else {
  3970. if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
  3971. } else if (!lpIMC->hWnd) {
  3972. } else {
  3973. POINT ptWnd;
  3974. ptWnd.x = 0;
  3975. ptWnd.y = 0;
  3976. ClientToScreen(lpIMC->hWnd, &ptWnd);
  3977. if (ptWnd.x < sImeG.rcWorkArea.left) {
  3978. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
  3979. } else if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
  3980. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
  3981. sImeG.xStatusWi;
  3982. } else {
  3983. lpIMC->ptStatusWndPos.x = ptWnd.x;
  3984. }
  3985. // DebugShow2 ("ptst.y,", lpIMC->ptStatusWndPos.y, "bottom" , sImeG.rcWorkArea.bottom);
  3986. if(!lpIMC->ptStatusWndPos.y) // == sImeG.rcWorkArea.bottom)
  3987. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  3988. sImeG.yStatusHi;// - 2 * UI_MARGIN;// - 20;
  3989. else
  3990. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  3991. sImeG.yStatusHi;// - 2 * UI_MARGIN;
  3992. //lpImcP->fdwInit |= INIT_STATUSWNDPOS;
  3993. lpIMC->fdwInit |= INIT_STATUSWNDPOS;
  3994. }
  3995. if (!(lpIMC->fdwInit & INIT_COMPFORM)) {
  3996. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  3997. }
  3998. if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
  3999. } else if (!lpIMC->hWnd) {
  4000. } else if (lpImcP->fdwInit & INIT_COMPFORM) {
  4001. } else {
  4002. if (0/*lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI*/) {
  4003. // lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
  4004. // lpImeL->rcStatusText.right + lpImeL->cxCompBorder * 2 +
  4005. // UI_MARGIN;
  4006. // if (lpIMC->cfCompForm.ptCurrentPos.x + (lpImeL->nRevMaxKey *
  4007. // sImeG.xChiCharWi) > sImeG.rcWorkArea.right) {
  4008. // lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
  4009. // lpImeL->nRevMaxKey * sImeG.xChiCharWi -
  4010. // lpImeL->cxCompBorder * 3;
  4011. // }
  4012. } else {
  4013. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
  4014. sImeG.xStatusWi + UI_MARGIN;
  4015. if (lpIMC->cfCompForm.ptCurrentPos.x + lpImeL->xCompWi >
  4016. sImeG.rcWorkArea.right) {
  4017. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
  4018. lpImeL->xCompWi - lpImeL->cxCompBorder * 2 -
  4019. UI_MARGIN;
  4020. }
  4021. }
  4022. lpIMC->cfCompForm.ptCurrentPos.y = sImeG.rcWorkArea.bottom -
  4023. lpImeL->yCompHi;// - 2 * UI_MARGIN;
  4024. ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
  4025. lpImcP->fdwInit |= INIT_COMPFORM;
  4026. }
  4027. return;
  4028. }
  4029. /**********************************************************************/
  4030. /* Select() */
  4031. /* Return Value: */
  4032. /* TRUE - successful, FALSE - failure */
  4033. /**********************************************************************/
  4034. BOOL PASCAL Select(
  4035. HIMC hIMC,
  4036. LPINPUTCONTEXT lpIMC,
  4037. BOOL fSelect)
  4038. {
  4039. LPPRIVCONTEXT lpImcP;
  4040. sImeG.First = 0;
  4041. if (fSelect) { // init "every" fields of hPrivate, please!!!
  4042. if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT) {
  4043. } else {
  4044. }
  4045. if (!ClearCompStr(lpIMC)) {
  4046. return (FALSE);
  4047. }
  4048. if (!ClearCand(lpIMC)) {
  4049. return (FALSE);
  4050. }
  4051. ClearGuideLine(lpIMC);
  4052. }
  4053. if (!lpIMC->hPrivate) {
  4054. return (FALSE);
  4055. }
  4056. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  4057. if (!lpImcP) {
  4058. return (FALSE);
  4059. }
  4060. if (fSelect) { // init "every" fields of hPrivate, please!!!
  4061. static bFirstTimeCallHere = TRUE;
  4062. InterlockedIncrement( &lLock );
  4063. if ( bFirstTimeCallHere == TRUE ) {
  4064. // we move the following code here from the DLL_ATTACH_PROCESS to
  4065. // avoid application hang.
  4066. // With static variable bFirstTimeCallHere, we ensure the following
  4067. // code will be called only when the ImeSelect( ) is first called.
  4068. GetCurrentUserEMBPath( );
  4069. data_init( );
  4070. bFirstTimeCallHere = FALSE;
  4071. }
  4072. InterlockedDecrement( &lLock );
  4073. lpImcP->iImeState = CST_INIT; // init the IME state machine
  4074. lpImcP->fdwImeMsg = (DWORD)0; // no UI windpws show
  4075. lpImcP->dwCompChar = (DWORD)0;
  4076. lpImcP->fdwGcsFlag = (DWORD)0;
  4077. lpImcP->hSoftKbdWnd = NULL; // soft keyboard window
  4078. lpImcP->nShowSoftKbdCmd = 0;
  4079. lpIMC->fOpen = TRUE;
  4080. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  4081. if(GetKeyState(VK_CAPITAL)&1)
  4082. lpIMC->fdwConversion = IME_CMODE_NOCONVERSION;
  4083. else
  4084. lpIMC->fdwConversion = IME_CMODE_NATIVE;
  4085. kb_mode = CIN_STD;
  4086. DispMode(hIMC);
  4087. lpIMC->fdwConversion |= IME_CMODE_SYMBOL;
  4088. lpIMC->fdwInit |= INIT_CONVERSION;
  4089. }else {
  4090. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD)
  4091. {
  4092. sImeG.First = 1;
  4093. }
  4094. }
  4095. if (lpIMC->fdwInit & INIT_SENTENCE) {
  4096. } else if (lpImeL->fModeConfig & MODE_CONFIG_PREDICT) {
  4097. lpIMC->fdwSentence = IME_SMODE_PHRASEPREDICT;
  4098. lpIMC->fdwInit |= INIT_SENTENCE;
  4099. } else {
  4100. }
  4101. if (!(lpIMC->fdwInit & INIT_LOGFONT)) {
  4102. HDC hDC;
  4103. HGDIOBJ hSysFont;
  4104. hDC = GetDC(NULL);
  4105. hSysFont = GetStockObject(SYSTEM_FONT);
  4106. GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A);
  4107. ReleaseDC(NULL, hDC);
  4108. lpIMC->fdwInit |= INIT_LOGFONT;
  4109. }
  4110. // Get Current User's specific phrase table path
  4111. InitContext(lpIMC,lpImcP);
  4112. }
  4113. else
  4114. {
  4115. if(hCrtDlg) {
  4116. SendMessage(hCrtDlg, WM_CLOSE, (WPARAM)NULL, (LPARAM)NULL);
  4117. hCrtDlg = NULL;
  4118. }
  4119. }
  4120. ImmUnlockIMCC(lpIMC->hPrivate);
  4121. return (TRUE);
  4122. }
  4123. /**********************************************************************/
  4124. /* ImeSelect() */
  4125. /* Return Value: */
  4126. /* TRUE - successful, FALSE - failure */
  4127. /**********************************************************************/
  4128. BOOL WINAPI ImeSelect(
  4129. HIMC hIMC,
  4130. BOOL fSelect)
  4131. {
  4132. LPINPUTCONTEXT lpIMC;
  4133. BOOL fRet;
  4134. // to load/free IME table
  4135. if (fSelect) {
  4136. InitCvtPara();
  4137. if (!lpImeL->cRefCount++) {
  4138. /* zst LoadTable() */ ;
  4139. }
  4140. } else {
  4141. if (!lpImeL->cRefCount) {
  4142. /* zst FreeTable() */ ;
  4143. }
  4144. }
  4145. if (!hIMC) {
  4146. return (FALSE);
  4147. }
  4148. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  4149. if (!lpIMC) {
  4150. return (FALSE);
  4151. }
  4152. fRet = Select(hIMC, lpIMC, fSelect);
  4153. ImmUnlockIMC(hIMC);
  4154. return (fRet);
  4155. }
  4156. /**********************************************************************/
  4157. /* ImeSetActiveContext() */
  4158. /* Return Value: */
  4159. /* TRUE - successful, FALSE - failure */
  4160. /**********************************************************************/
  4161. BOOL WINAPI ImeSetActiveContext(
  4162. HIMC hIMC,
  4163. BOOL fOn)
  4164. {
  4165. if (!fOn) {
  4166. } else if (!hIMC) {
  4167. } else {
  4168. LPINPUTCONTEXT lpIMC;
  4169. LPPRIVCONTEXT lpImcP; //zl
  4170. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  4171. if (!lpIMC) {
  4172. return (FALSE);
  4173. }
  4174. if(lpIMC->hPrivate){
  4175. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); //zl
  4176. if (!lpImcP){ //zl
  4177. return (FALSE); //zl
  4178. } //zl
  4179. }else return(FALSE);
  4180. InitContext(lpIMC,lpImcP); //zl
  4181. // DispModeEx(0);
  4182. ImmUnlockIMCC(lpIMC->hPrivate); //zl
  4183. ImmUnlockIMC(hIMC);
  4184. }
  4185. return (TRUE);
  4186. }
  4187. /**********************************************************************/
  4188. /* ReInitIme() */
  4189. /**********************************************************************/
  4190. void PASCAL ReInitIme(
  4191. HWND hWnd ,
  4192. WORD WhatStyle)
  4193. {
  4194. HWND hStatusWnd,MainWnd;
  4195. POINT ptPos;
  4196. RECT rcStatusWnd,TempRect;
  4197. int cxBorder, cyBorder;
  4198. if (sImeG.unchanged)
  4199. return ;
  4200. // border + raising edge + sunken edge
  4201. cxBorder = GetSystemMetrics(SM_CXBORDER) +
  4202. GetSystemMetrics(SM_CXEDGE) * 2;
  4203. cyBorder = GetSystemMetrics(SM_CYBORDER) +
  4204. GetSystemMetrics(SM_CYEDGE) * 2;
  4205. //if (!WhatStyle){
  4206. if (WhatStyle==IME_APRS_AUTO){
  4207. lpImeL->rcCompText.left = 4;
  4208. lpImeL->rcCompText.top =4;
  4209. lpImeL->rcCompText.right = sImeG.TextLen+5;
  4210. lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;
  4211. lpImeL->cxCompBorder = cxBorder;
  4212. lpImeL->cyCompBorder = cyBorder;
  4213. // set the width & height for composition window
  4214. lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
  4215. //lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
  4216. lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
  4217. } else {
  4218. // text position relative to the composition window
  4219. lpImeL->rcCompText.left = 4;
  4220. lpImeL->rcCompText.top = 4;
  4221. lpImeL->rcCompText.right = sImeG.TextLen+5;
  4222. lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/
  4223. lpImeL->cxCompBorder = cxBorder;
  4224. lpImeL->cyCompBorder = cyBorder;
  4225. // set the width & height for composition window
  4226. lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
  4227. lpImeL->yCompHi = sImeG.yStatusHi; //zl
  4228. }
  4229. // border + raising edge + sunken edge
  4230. cxBorder = GetSystemMetrics(SM_CXBORDER) +
  4231. GetSystemMetrics(SM_CXEDGE) /* 2*/;
  4232. cyBorder = GetSystemMetrics(SM_CYBORDER) +
  4233. GetSystemMetrics(SM_CYEDGE) /* 2*/;
  4234. //if (!WhatStyle){
  4235. if (WhatStyle==IME_APRS_AUTO){
  4236. sImeG.rcCandText.left = 4;
  4237. sImeG.rcCandText.top = 4;
  4238. sImeG.rcCandText.right = sImeG.xChiCharWi * 7;
  4239. sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl
  4240. sImeG.cxCandBorder = cxBorder+3;
  4241. sImeG.cyCandBorder = cyBorder+3;
  4242. sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl
  4243. sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12;
  4244. sImeG.rcHome.left = 4 ;
  4245. sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ;
  4246. sImeG.rcHome.right = sImeG.rcHome.left + 14 ;
  4247. sImeG.rcHome.bottom = sImeG.rcHome.top +14 ;
  4248. sImeG.rcEnd.left = sImeG.rcHome.right ;
  4249. sImeG.rcEnd.top = sImeG.rcHome.top ;
  4250. sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ;
  4251. sImeG.rcEnd.bottom = sImeG.rcHome.bottom ;
  4252. sImeG.rcPageDown.top = sImeG.rcHome.top ;
  4253. sImeG.rcPageDown.right = sImeG.xCandWi-4;
  4254. sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
  4255. sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ;
  4256. sImeG.rcPageUp.top = sImeG.rcHome.top ;
  4257. sImeG.rcPageUp.right = sImeG.rcPageDown.left ;
  4258. sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ;
  4259. sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
  4260. }else{
  4261. sImeG.cxCandBorder = cxBorder;
  4262. sImeG.cyCandBorder = cyBorder;
  4263. sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1;
  4264. sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2;
  4265. sImeG.rcHome.left = 3; //2;
  4266. sImeG.rcHome.top = 4;//7;
  4267. sImeG.rcHome.right = sImeG.rcHome.left + 10; //14;
  4268. sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ;
  4269. sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ;
  4270. sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ;
  4271. sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ;
  4272. sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ;
  4273. sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ;
  4274. sImeG.rcPageDown.right = sImeG.xCandWi-1;//2;
  4275. sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
  4276. sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ;
  4277. sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl
  4278. sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ;
  4279. sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ;
  4280. sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
  4281. sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right;
  4282. sImeG.rcCandText.top = 4;
  4283. sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2;
  4284. sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3;
  4285. }
  4286. /* ptPos.x = 0 ;
  4287. ptPos.y = 0 ;
  4288. ClientToScreen(hWnd, &ptPos);
  4289. lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2;
  4290. lpImeL->ptDefComp.y = ptPos.y - cyBorder;
  4291. lpImeL->ptDefCand.x = ptPos.x - cxBorder;
  4292. lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2;
  4293. if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10)
  4294. {lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
  4295. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;}
  4296. if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
  4297. lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi; //sImeG.yCandHi+2;
  4298. */
  4299. if (hWnd){
  4300. ptPos.x = 0 ;
  4301. ptPos.y = 0 ;
  4302. ClientToScreen(hWnd, &ptPos);
  4303. CountDefaultComp(ptPos.x,ptPos.y,sImeG.rcWorkArea);
  4304. lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl
  4305. lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl
  4306. lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl
  4307. lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl
  4308. if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){
  4309. lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
  4310. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;
  4311. }
  4312. if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
  4313. lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2;
  4314. }else{
  4315. ptPos.x = lpImeL->Ox ;
  4316. ptPos.y = lpImeL->Oy ;
  4317. lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2;
  4318. lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
  4319. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi;
  4320. lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ;
  4321. /*
  4322. if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10)
  4323. {lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
  4324. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;}
  4325. if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
  4326. lpImeL->ptDefCand.y = ptPos.y + sImeG.yCandHi+2;
  4327. */
  4328. }
  4329. fmt_transfer();
  4330. CandWndChange = 1;
  4331. CompWndChange = 1;
  4332. return ;
  4333. }
  4334. void PASCAL ReInitIme2(
  4335. HWND hWnd ,
  4336. WORD WhatStyle)
  4337. {
  4338. HWND hStatusWnd,MainWnd;
  4339. POINT ptPos;
  4340. RECT rcStatusWnd,TempRect;
  4341. int cxBorder, cyBorder;
  4342. if (sImeG.unchanged)
  4343. return ;
  4344. // border + raising edge + sunken edge
  4345. cxBorder = GetSystemMetrics(SM_CXBORDER) +
  4346. GetSystemMetrics(SM_CXEDGE) * 2;
  4347. cyBorder = GetSystemMetrics(SM_CYBORDER) +
  4348. GetSystemMetrics(SM_CYEDGE) * 2;
  4349. if (!WhatStyle){
  4350. lpImeL->rcCompText.left = 4;
  4351. lpImeL->rcCompText.top =4;
  4352. lpImeL->rcCompText.right = sImeG.TextLen+5;
  4353. lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;
  4354. lpImeL->cxCompBorder = cxBorder;
  4355. lpImeL->cyCompBorder = cyBorder;
  4356. // set the width & height for composition window
  4357. lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
  4358. //lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
  4359. lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
  4360. } else {
  4361. // text position relative to the composition window
  4362. lpImeL->rcCompText.left = 4;
  4363. lpImeL->rcCompText.top = 4;
  4364. lpImeL->rcCompText.right = sImeG.TextLen+5;
  4365. lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/
  4366. lpImeL->cxCompBorder = cxBorder;
  4367. lpImeL->cyCompBorder = cyBorder;
  4368. // set the width & height for composition window
  4369. lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
  4370. lpImeL->yCompHi = sImeG.yStatusHi; //zl
  4371. }
  4372. // border + raising edge + sunken edge
  4373. cxBorder = GetSystemMetrics(SM_CXBORDER) +
  4374. GetSystemMetrics(SM_CXEDGE) /* 2*/;
  4375. cyBorder = GetSystemMetrics(SM_CYBORDER) +
  4376. GetSystemMetrics(SM_CYEDGE) /* 2*/;
  4377. if (!WhatStyle){
  4378. sImeG.rcCandText.left = 4;
  4379. sImeG.rcCandText.top = 4;
  4380. sImeG.rcCandText.right = sImeG.xChiCharWi * 7;
  4381. sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl
  4382. sImeG.cxCandBorder = cxBorder+3;
  4383. sImeG.cyCandBorder = cyBorder+3;
  4384. sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl
  4385. sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12;
  4386. sImeG.rcHome.left = 4 ;
  4387. sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ;
  4388. sImeG.rcHome.right = sImeG.rcHome.left + 14 ;
  4389. sImeG.rcHome.bottom = sImeG.rcHome.top +14 ;
  4390. sImeG.rcEnd.left = sImeG.rcHome.right ;
  4391. sImeG.rcEnd.top = sImeG.rcHome.top ;
  4392. sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ;
  4393. sImeG.rcEnd.bottom = sImeG.rcHome.bottom ;
  4394. sImeG.rcPageDown.top = sImeG.rcHome.top ;
  4395. sImeG.rcPageDown.right = sImeG.xCandWi-4;
  4396. sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
  4397. sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ;
  4398. sImeG.rcPageUp.top = sImeG.rcHome.top ;
  4399. sImeG.rcPageUp.right = sImeG.rcPageDown.left ;
  4400. sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ;
  4401. sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
  4402. }else{
  4403. sImeG.cxCandBorder = cxBorder;
  4404. sImeG.cyCandBorder = cyBorder;
  4405. sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1;
  4406. sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2;
  4407. sImeG.rcHome.left = 3; //2;
  4408. sImeG.rcHome.top = 4;//7;
  4409. sImeG.rcHome.right = sImeG.rcHome.left + 10; //14;
  4410. sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ;
  4411. sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ;
  4412. sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ;
  4413. sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ;
  4414. sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ;
  4415. sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ;
  4416. sImeG.rcPageDown.right = sImeG.xCandWi-1;//2;
  4417. sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
  4418. sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ;
  4419. sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl
  4420. sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ;
  4421. sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ;
  4422. sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
  4423. sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right;
  4424. sImeG.rcCandText.top = 4;
  4425. sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2;
  4426. sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3;
  4427. }
  4428. if (hWnd){
  4429. ptPos.x = 0 ;
  4430. ptPos.y = 0 ;
  4431. ClientToScreen(hWnd, &ptPos);
  4432. lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl
  4433. lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl
  4434. lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl
  4435. lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl
  4436. if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){
  4437. lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
  4438. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;
  4439. }
  4440. if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
  4441. lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2;
  4442. }else{
  4443. ptPos.x = lpImeL->Ox ;
  4444. ptPos.y = lpImeL->Oy ;
  4445. lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2;
  4446. lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
  4447. lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi;
  4448. lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ;
  4449. }
  4450. return ;
  4451. }
  4452. /**********************************************************************/
  4453. /* InitUserSetting() */
  4454. /**********************************************************************/
  4455. int InitUserSetting(void)
  4456. {
  4457. HKEY hKey,hFirstKey;
  4458. DWORD dwSize, dx;
  4459. int lRet;
  4460. RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey);
  4461. RegCreateKey(hFirstKey, szAIABC, &hKey);
  4462. RegCloseKey(hFirstKey);
  4463. //1 KeyType
  4464. dwSize = sizeof(dwSize);
  4465. lRet = RegQueryValueEx(hKey, szKeyType, NULL, NULL,
  4466. (LPBYTE)&dx, &dwSize);
  4467. if (lRet != ERROR_SUCCESS) {
  4468. dx = 0;
  4469. RegSetValueEx(hKey,szKeyType , 0, REG_DWORD,
  4470. (LPBYTE)&dx, sizeof(int));
  4471. }else {
  4472. sImeG.KbType =(BYTE)dx ;
  4473. }
  4474. // 2 ImeStyle
  4475. dwSize = sizeof(dwSize);
  4476. lRet = RegQueryValueEx(hKey,szImeStyle , NULL, NULL,
  4477. (LPBYTE)&dx, &dwSize);
  4478. if (lRet != ERROR_SUCCESS) {
  4479. dx = 0;
  4480. RegSetValueEx(hKey,szImeStyle, 0, REG_DWORD,
  4481. (LPBYTE)&dx, sizeof(int));
  4482. }else {
  4483. lpImeL->wImeStyle = (WORD)dx ;
  4484. }
  4485. // 3 AutoCp
  4486. dwSize = sizeof(dwSize);
  4487. lRet = RegQueryValueEx(hKey, szCpAuto, NULL, NULL,
  4488. (LPBYTE)&dx, &dwSize);
  4489. if (lRet != ERROR_SUCCESS) {
  4490. dx = 0;
  4491. RegSetValueEx(hKey,szCpAuto, 0, REG_DWORD,
  4492. (LPBYTE)&dx, sizeof(int));
  4493. }else {
  4494. sImeG.auto_mode =(BYTE)dx ;
  4495. }
  4496. // 4 BxFlag
  4497. dwSize = sizeof(dwSize);
  4498. lRet = RegQueryValueEx(hKey, szBxFlag , NULL, NULL,
  4499. (LPBYTE)&dx, &dwSize);
  4500. if (lRet != ERROR_SUCCESS) {
  4501. dx = 0;
  4502. RegSetValueEx(hKey, szBxFlag , 0, REG_DWORD,
  4503. (LPBYTE)&dx, sizeof(int));
  4504. }else {
  4505. sImeG.cbx_flag =(BYTE)dx ;
  4506. }
  4507. // 5 TuneFlag
  4508. dwSize = sizeof(dwSize);
  4509. lRet = RegQueryValueEx(hKey, szTuneFlag , NULL, NULL,
  4510. (LPBYTE)&dx, &dwSize);
  4511. if (lRet != ERROR_SUCCESS) {
  4512. dx = 0;
  4513. RegSetValueEx(hKey, szTuneFlag , 0, REG_DWORD,
  4514. (LPBYTE)&dx, sizeof(int));
  4515. }else {
  4516. sImeG.tune_flag=(BYTE)dx ;
  4517. }
  4518. // 6 AutoCvt
  4519. dwSize = sizeof(dwSize);
  4520. lRet = RegQueryValueEx(hKey, szAutoCvt , NULL, NULL,
  4521. (LPBYTE)&dx, &dwSize);
  4522. if (lRet != ERROR_SUCCESS) {
  4523. dx = 0;
  4524. RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD,
  4525. (LPBYTE)&dx, sizeof(int));
  4526. }else {
  4527. sImeG.auto_cvt_flag=(BYTE)dx ;
  4528. }
  4529. // 7 SdaHelp
  4530. dwSize = sizeof(dwSize);
  4531. lRet = RegQueryValueEx(hKey, szSdaHelp , NULL, NULL,
  4532. (LPBYTE)&dx, &dwSize);
  4533. if (lRet != ERROR_SUCCESS) {
  4534. dx = 0;
  4535. RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD,
  4536. (LPBYTE)&dx, sizeof(int));
  4537. }else {
  4538. sImeG.SdOpenFlag=(BYTE)dx ;
  4539. }
  4540. RegCloseKey(hKey);
  4541. //ReInitIme2(NULL, lpImeL->wImeStyle);
  4542. return 0;
  4543. }
  4544. /**********************************************************************/
  4545. /* ChangeUserSetting() */
  4546. /**********************************************************************/
  4547. ChangeUserSetting()
  4548. {
  4549. HKEY hKey,hFirstKey;
  4550. DWORD dwSize, dx;
  4551. int lRet;
  4552. RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey);
  4553. RegCreateKey(hFirstKey, szAIABC, &hKey);
  4554. RegCloseKey(hFirstKey);
  4555. RegSetValueEx(hKey, szKeyType, 0, REG_DWORD,
  4556. (LPBYTE)&sImeG.KbType, sizeof(int));
  4557. RegSetValueEx(hKey, szImeStyle, 0, REG_DWORD,
  4558. (LPBYTE)&lpImeL->wImeStyle, sizeof(int));
  4559. RegSetValueEx(hKey, szCpAuto, 0, REG_DWORD,
  4560. (LPBYTE)&sImeG.auto_mode, sizeof(int));
  4561. RegSetValueEx(hKey, szBxFlag, 0, REG_DWORD,
  4562. (LPBYTE)&sImeG.cbx_flag, sizeof(int));
  4563. RegSetValueEx(hKey, szTuneFlag, 0, REG_DWORD,
  4564. (LPBYTE)&sImeG.tune_flag, sizeof(int));
  4565. RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD,
  4566. (LPBYTE)&sImeG.auto_cvt_flag, sizeof(int));
  4567. RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD,
  4568. (LPBYTE)&sImeG.SdOpenFlag, sizeof(int));
  4569. RegCloseKey(hKey);
  4570. return 0;
  4571. }
  4572. /**********************************************************************/
  4573. /* InitImeGlobalData() */
  4574. /**********************************************************************/
  4575. void PASCAL InitImeGlobalData(
  4576. HINSTANCE hInstance)
  4577. {
  4578. int cxBorder, cyBorder;
  4579. HDC hDC;
  4580. BYTE szChiChar[4];
  4581. SIZE lTextSize;
  4582. HGLOBAL hResData;
  4583. int i;
  4584. DWORD dwSize;
  4585. HKEY hKeyIMESetting;
  4586. LONG lRet;
  4587. BYTE NumChar[]="1.2.3.4.5.6.7.8.9.";
  4588. BYTE CNumChar[]="����ԭ�ϲ�һ��һ����";
  4589. SIZE hSize;
  4590. sImeG.WhitePen = GetStockObject(WHITE_PEN);
  4591. sImeG.BlackPen = GetStockObject(BLACK_PEN);
  4592. sImeG.GrayPen = CreatePen(PS_SOLID, 1, 0x00808080);
  4593. sImeG.LightGrayPen = CreatePen(PS_SOLID, 1, 0x00c0c0c0);
  4594. hInst = hInstance;
  4595. // get the UI class name
  4596. LoadString(hInst, IDS_IMEUICLASS, szUIClassName, sizeof(szUIClassName));
  4597. // get the composition class name
  4598. LoadString(hInst, IDS_IMECOMPCLASS, szCompClassName, sizeof(szCompClassName));
  4599. // get the candidate class name
  4600. LoadString(hInst, IDS_IMECANDCLASS, szCandClassName, sizeof(szCandClassName));
  4601. // get the status class name
  4602. LoadString(hInst, IDS_IMESTATUSCLASS, szStatusClassName, sizeof(szStatusClassName));
  4603. // work area
  4604. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  4605. // border + raising edge + sunken edge
  4606. cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) /* 2*/;
  4607. cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) /* 2*/;
  4608. // get the Chinese char
  4609. LoadString(hInst, IDS_CHICHAR, szChiChar, sizeof(szChiChar));
  4610. // get size of Chinese char
  4611. hDC = GetDC(NULL);
  4612. GetTextExtentPoint32(hDC, "��", 2, &lTextSize);
  4613. if (sImeG.rcWorkArea.right < 2 * UI_MARGIN) {
  4614. sImeG.rcWorkArea.left = 0;
  4615. sImeG.rcWorkArea.right = GetDeviceCaps(hDC, HORZRES);
  4616. }
  4617. if (sImeG.rcWorkArea.bottom < 2 * UI_MARGIN) {
  4618. sImeG.rcWorkArea.top = 0;
  4619. sImeG.rcWorkArea.bottom = GetDeviceCaps(hDC, VERTRES);
  4620. }
  4621. GetTextExtentPoint32(hDC,(LPCTSTR)"2.", 2, &hSize);
  4622. sImeG.Ajust = hSize.cx;
  4623. // get text metrics to decide the width & height of composition window
  4624. // these IMEs always use system font to show
  4625. GetTextExtentPoint32(hDC,(LPCTSTR)&CNumChar, 20, &hSize);
  4626. sImeG.TextLen = hSize.cx +2;//zl
  4627. sImeG.xChiCharWi = lTextSize.cx;
  4628. sImeG.yChiCharHi = lTextSize.cy;
  4629. // the width/high and status position relative to status window
  4630. sImeG.rcStatusText.left = 0;
  4631. sImeG.rcStatusText.top = 0;
  4632. sImeG.rcStatusText.right = STATUS_DIM_X * 5+6+20;//4; // chg
  4633. sImeG.rcStatusText.bottom = STATUS_DIM_Y;
  4634. sImeG.xStatusWi = STATUS_DIM_X * 5 + cxBorder * 2+3+18 ; //chg
  4635. if(sImeG.yChiCharHi==0x10)
  4636. sImeG.yStatusHi = STATUS_DIM_Y + cyBorder * 2-1; //zl
  4637. else
  4638. sImeG.yStatusHi = STATUS_DIM_Y + cyBorder * 2-1+2;
  4639. // left bottom of status
  4640. sImeG.rcInputText.left = sImeG.rcStatusText.left+3;//2; //zl
  4641. sImeG.rcInputText.top = sImeG.rcStatusText.top ; //zl
  4642. sImeG.rcInputText.right = sImeG.rcInputText.left + STATUS_DIM_X; //z
  4643. sImeG.rcInputText.bottom = sImeG.rcStatusText.bottom;
  4644. // no. 2 bottom of status
  4645. sImeG.rcCmdText.left = sImeG.rcInputText.right+1;//95.9.23+1;
  4646. sImeG.rcCmdText.top = sImeG.rcStatusText.top -1; //zl
  4647. sImeG.rcCmdText.right = sImeG.rcCmdText.left + STATUS_DIM_X+20; //zl
  4648. sImeG.rcCmdText.bottom = sImeG.rcStatusText.bottom;
  4649. // no. 3 bottom of status
  4650. sImeG.rcShapeText.left =sImeG.rcCmdText.right;//+1;
  4651. sImeG.rcShapeText.top = sImeG.rcStatusText.top - 1; //zl
  4652. sImeG.rcShapeText.right = sImeG.rcShapeText.left + STATUS_DIM_X; //zl
  4653. sImeG.rcShapeText.bottom = sImeG.rcStatusText.bottom;
  4654. // no 4 bottom of status
  4655. sImeG.rcPctText.left =sImeG.rcShapeText.right;
  4656. sImeG.rcPctText.top = sImeG.rcStatusText.top -1; //zl
  4657. sImeG.rcPctText.right = sImeG.rcPctText.left + STATUS_DIM_X; //zl
  4658. sImeG.rcPctText.bottom = sImeG.rcStatusText.bottom;
  4659. // 5
  4660. // right bottom of status
  4661. sImeG.rcSKText.left = sImeG.rcPctText.right;
  4662. sImeG.rcSKText.top = sImeG.rcStatusText.top - 1;
  4663. sImeG.rcSKText.right = sImeG.rcSKText.left + STATUS_DIM_X; //zl
  4664. sImeG.rcSKText.bottom = sImeG.rcStatusText.bottom;
  4665. // full shape space
  4666. sImeG.wFullSpace = sImeG.wFullABC[0];
  4667. // reverse internal code to internal code, NT don't need it
  4668. for (i = 0; i < (sizeof(sImeG.wFullABC) / 2); i++) {
  4669. sImeG.wFullABC[i] = (sImeG.wFullABC[i] << 8) |
  4670. (sImeG.wFullABC[i] >> 8);
  4671. }
  4672. LoadString(hInst, IDS_STATUSERR, sImeG.szStatusErr,
  4673. sizeof(sImeG.szStatusErr));
  4674. sImeG.cbStatusErr = lstrlen(sImeG.szStatusErr);
  4675. sImeG.iCandStart = CAND_START;
  4676. sImeG.Prop = 0;
  4677. // get the UI offset for near caret operation
  4678. RegCreateKey(HKEY_CURRENT_USER, szRegIMESetting, &hKeyIMESetting);
  4679. dwSize = sizeof(dwSize);
  4680. lRet = RegQueryValueEx(hKeyIMESetting, szPara, NULL, NULL,
  4681. (LPBYTE)&sImeG.iPara, &dwSize);
  4682. if (lRet != ERROR_SUCCESS) {
  4683. sImeG.iPara = 0;
  4684. RegSetValueEx(hKeyIMESetting, szPara, (DWORD)0, REG_BINARY,
  4685. (LPBYTE)&sImeG.iPara, sizeof(int));
  4686. }
  4687. dwSize = sizeof(dwSize);
  4688. lRet = RegQueryValueEx(hKeyIMESetting, szPerp, NULL, NULL,
  4689. (LPBYTE)&sImeG.iPerp, &dwSize);
  4690. if (lRet != ERROR_SUCCESS) {
  4691. sImeG.iPerp = sImeG.yChiCharHi;
  4692. RegSetValueEx(hKeyIMESetting, szPerp, (DWORD)0, REG_BINARY,
  4693. (LPBYTE)&sImeG.iPerp, sizeof(int));
  4694. }
  4695. dwSize = sizeof(dwSize);
  4696. lRet = RegQueryValueEx(hKeyIMESetting, szParaTol, NULL, NULL,
  4697. (LPBYTE)&sImeG.iParaTol, &dwSize);
  4698. if (lRet != ERROR_SUCCESS) {
  4699. sImeG.iParaTol = sImeG.xChiCharWi * 4;
  4700. RegSetValueEx(hKeyIMESetting, szParaTol, (DWORD)0, REG_BINARY,
  4701. (LPBYTE)&sImeG.iParaTol, sizeof(int));
  4702. }
  4703. dwSize = sizeof(dwSize);
  4704. lRet = RegQueryValueEx(hKeyIMESetting, szPerpTol, NULL, NULL,
  4705. (LPBYTE)&sImeG.iPerpTol, &dwSize);
  4706. if (lRet != ERROR_SUCCESS) {
  4707. sImeG.iPerpTol = lTextSize.cy;
  4708. RegSetValueEx(hKeyIMESetting,
  4709. szPerpTol,
  4710. (DWORD)0,
  4711. REG_BINARY,
  4712. (LPBYTE)&sImeG.iPerpTol,
  4713. sizeof(int));
  4714. }
  4715. RegCloseKey(hKeyIMESetting);
  4716. ReleaseDC(NULL, hDC);
  4717. return;
  4718. }
  4719. /**********************************************************************/
  4720. /* InitImeLocalData() */
  4721. /**********************************************************************/
  4722. BOOL PASCAL InitImeLocalData(
  4723. HINSTANCE hInstL)
  4724. {
  4725. HGLOBAL hResData;
  4726. int cxBorder, cyBorder;
  4727. register int i;
  4728. register WORD nSeqCode;
  4729. lpImeL->hInst = hInstL;
  4730. // load valid char in choose/input state
  4731. lpImeL->nMaxKey = 20 ;
  4732. // border + raising edge + sunken edge
  4733. cxBorder = GetSystemMetrics(SM_CXBORDER) +
  4734. GetSystemMetrics(SM_CXEDGE) * 2;
  4735. cyBorder = GetSystemMetrics(SM_CYBORDER) +
  4736. GetSystemMetrics(SM_CYEDGE) * 2;
  4737. // text position relative to the composition window
  4738. lpImeL->rcCompText.left = 3;
  4739. lpImeL->rcCompText.top = 3;
  4740. lpImeL->rcCompText.right = sImeG.xChiCharWi * lpImeL->nMaxKey/2+3;
  4741. lpImeL->rcCompText.bottom = sImeG.yChiCharHi+3;
  4742. lpImeL->cxCompBorder = cxBorder;
  4743. lpImeL->cyCompBorder = cyBorder;
  4744. // set the width & height for composition window
  4745. lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
  4746. lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2;
  4747. // default position of composition window
  4748. lpImeL->ptDefComp.x = sImeG.rcWorkArea.right -
  4749. lpImeL->yCompHi - cxBorder;
  4750. lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom -
  4751. lpImeL->xCompWi - cyBorder;
  4752. lpImeL->Ox = lpImeL->ptDefComp.x;
  4753. lpImeL->Oy = lpImeL->ptDefComp.y;
  4754. return (TRUE);
  4755. }
  4756. /**********************************************************************/
  4757. /* RegisterImeClass() */
  4758. /**********************************************************************/
  4759. void PASCAL RegisterImeClass(
  4760. HINSTANCE hInstance,
  4761. HINSTANCE hInstL)
  4762. {
  4763. WNDCLASSEX wcWndCls;
  4764. // IME UI class
  4765. wcWndCls.cbSize = sizeof(WNDCLASSEX);
  4766. wcWndCls.cbClsExtra = 0;
  4767. wcWndCls.cbWndExtra = sizeof(LONG) * 2;
  4768. wcWndCls.hIcon = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
  4769. IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
  4770. wcWndCls.hInstance = hInstance;
  4771. wcWndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
  4772. wcWndCls.hbrBackground = GetStockObject(LTGRAY_BRUSH/*NULL_BRUSH*/);
  4773. wcWndCls.lpszMenuName = (LPSTR)NULL;
  4774. wcWndCls.hIconSm = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
  4775. IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  4776. // IME UI class
  4777. if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
  4778. wcWndCls.style = CS_IME;
  4779. wcWndCls.lpfnWndProc = UIWndProc;
  4780. wcWndCls.lpszClassName = (LPSTR)szUIClassName;
  4781. RegisterClassEx(&wcWndCls);
  4782. }
  4783. wcWndCls.style = CS_IME|CS_HREDRAW|CS_VREDRAW;
  4784. // IME composition class
  4785. if (!GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
  4786. wcWndCls.lpfnWndProc = CompWndProc;
  4787. wcWndCls.lpszClassName = (LPSTR)szCompClassName;
  4788. RegisterClassEx(&wcWndCls);
  4789. }
  4790. // IME candidate class
  4791. if (!GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
  4792. wcWndCls.lpfnWndProc = CandWndProc;
  4793. wcWndCls.hbrBackground = GetStockObject(LTGRAY_BRUSH);
  4794. wcWndCls.lpszClassName = (LPSTR)szCandClassName;
  4795. RegisterClassEx(&wcWndCls);
  4796. }
  4797. // IME status class
  4798. if (!GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
  4799. wcWndCls.lpfnWndProc = StatusWndProc;
  4800. wcWndCls.lpszClassName = (LPSTR)szStatusClassName;
  4801. RegisterClassEx(&wcWndCls);
  4802. }
  4803. if (!GetClassInfoEx(hInstance, "Abc95Menu", &wcWndCls)) {
  4804. wcWndCls.style = 0;
  4805. wcWndCls.cbWndExtra = WND_EXTRA_SIZE;
  4806. wcWndCls.hbrBackground = GetStockObject(NULL_BRUSH);
  4807. wcWndCls.lpfnWndProc = ContextMenuWndProc;
  4808. wcWndCls.lpszClassName = "Abc95Menu";
  4809. RegisterClassEx(&wcWndCls);
  4810. }
  4811. return;
  4812. }
  4813. /**********************************************************************/
  4814. /* QuitBefore() */
  4815. /* Return Value: */
  4816. /* TRUE - successful */
  4817. /* FALSE - failure */
  4818. /**********************************************************************/
  4819. int WINAPI QuitBefore()
  4820. {
  4821. GlobalUnlock(cisu_hd);
  4822. if(cisu_hd)
  4823. GlobalFree(cisu_hd);
  4824. return 0;
  4825. }
  4826. /**********************************************************************/
  4827. /* ImeDllInit() */
  4828. /* Return Value: */
  4829. /* TRUE - successful */
  4830. /* FALSE - failure */
  4831. /**********************************************************************/
  4832. BOOL CALLBACK ImeDllInit(
  4833. HINSTANCE hInstance, // instance handle of this library
  4834. DWORD fdwReason, // reason called
  4835. LPVOID lpvReserve) // reserve pointer
  4836. {
  4837. // DebugShow("Init Stat",NULL);
  4838. switch (fdwReason) {
  4839. case DLL_PROCESS_ATTACH:
  4840. if (!hInst) {
  4841. InitImeGlobalData(hInstance);
  4842. // data_init(); /* move to the Select( ) to avoid app hang */
  4843. }
  4844. if (!lpImeL) {
  4845. lpImeL = &sImeL;
  4846. InitImeLocalData(hInstance);
  4847. }
  4848. InitUserSetting();
  4849. RegisterImeClass(hInstance, hInstance);
  4850. break;
  4851. case DLL_PROCESS_DETACH:
  4852. {
  4853. WNDCLASSEX wcWndCls;
  4854. DeleteObject (sImeG.WhitePen);
  4855. DeleteObject (sImeG.BlackPen);
  4856. DeleteObject (sImeG.GrayPen);
  4857. DeleteObject (sImeG.LightGrayPen);
  4858. QuitBefore();
  4859. if (GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
  4860. UnregisterClass(szStatusClassName, hInstance);
  4861. }
  4862. if (GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
  4863. UnregisterClass(szCandClassName, hInstance);
  4864. }
  4865. if (GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
  4866. UnregisterClass(szCompClassName, hInstance);
  4867. }
  4868. if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
  4869. } else if (!UnregisterClass(szUIClassName, hInstance)) {
  4870. } else {
  4871. DestroyIcon(wcWndCls.hIcon);
  4872. DestroyIcon(wcWndCls.hIconSm);
  4873. }
  4874. break;
  4875. }
  4876. default:
  4877. break;
  4878. }
  4879. return (TRUE);
  4880. }
  4881. /**********************************************************************/
  4882. /* GenerateMessage2() */
  4883. /**********************************************************************/
  4884. void PASCAL GenerateMessage2(
  4885. HIMC hIMC,
  4886. LPINPUTCONTEXT lpIMC,
  4887. LPPRIVCONTEXT lpImcP)
  4888. {
  4889. LPTRANSMSG lpMsgBuf;
  4890. HIMCC hMem;
  4891. BOOL bCantReSize;
  4892. if (!hIMC) {
  4893. return;
  4894. } else if (!lpIMC) {
  4895. return;
  4896. } else if (!lpImcP) {
  4897. return;
  4898. } else if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
  4899. return;
  4900. } else {
  4901. }
  4902. bCantReSize = FALSE;
  4903. if (!lpIMC->hMsgBuf) {
  4904. // it maybe free by IME, up to GEN_MSG_MAX messages for max case
  4905. lpIMC->hMsgBuf = ImmCreateIMCC(GEN_MSG_MAX * sizeof(TRANSMSG));
  4906. } else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf
  4907. + GEN_MSG_MAX) * sizeof(TRANSMSG))) {
  4908. lpIMC->hMsgBuf = hMem;
  4909. } else {
  4910. bCantReSize = TRUE;
  4911. }
  4912. if (!lpIMC->hMsgBuf) {
  4913. lpIMC->dwNumMsgBuf = 0;
  4914. return;
  4915. }
  4916. lpMsgBuf = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
  4917. if (!lpMsgBuf) {
  4918. return;
  4919. }
  4920. if (bCantReSize) {
  4921. LPTRANSMSG lpNewBuf;
  4922. hMem = ImmCreateIMCC((lpIMC->dwNumMsgBuf + GEN_MSG_MAX) *
  4923. sizeof(TRANSMSG));
  4924. if (!hMem) {
  4925. ImmUnlockIMCC(lpIMC->hMsgBuf);
  4926. return;
  4927. }
  4928. lpNewBuf = (LPTRANSMSG)ImmLockIMCC(hMem);
  4929. if (!lpMsgBuf) {
  4930. ImmUnlockIMCC(lpIMC->hMsgBuf);
  4931. return;
  4932. }
  4933. CopyMemory(lpNewBuf, lpMsgBuf, lpIMC->dwNumMsgBuf *
  4934. sizeof(TRANSMSG));
  4935. ImmUnlockIMCC(lpIMC->hMsgBuf);
  4936. ImmDestroyIMCC(lpIMC->hMsgBuf);
  4937. lpIMC->hMsgBuf = hMem;
  4938. lpMsgBuf = lpNewBuf;
  4939. }
  4940. if(TypeOfOutMsg){
  4941. lpIMC->dwNumMsgBuf += TransAbcMsg2(lpMsgBuf, lpImcP);
  4942. }else{
  4943. lpIMC->dwNumMsgBuf += TranslateImeMessage(NULL, lpIMC, lpImcP);
  4944. }
  4945. // lpIMC->dwNumMsgBuf += TransAbcMsg(lpMsgBuf, lpImcP,lpIMC,0,0,0);
  4946. ImmUnlockIMCC(lpIMC->hMsgBuf);
  4947. lpImcP->fdwImeMsg &= (MSG_ALREADY_OPEN|MSG_ALREADY_START);
  4948. lpImcP->fdwGcsFlag &= (GCS_RESULTREAD|GCS_RESULT); // ?
  4949. ImmGenerateMessage(hIMC);
  4950. return;
  4951. }
  4952. /**********************************************************************/
  4953. /* GenerateMessage() */
  4954. /**********************************************************************/
  4955. void PASCAL GenerateMessage(
  4956. HIMC hIMC,
  4957. LPINPUTCONTEXT lpIMC,
  4958. LPPRIVCONTEXT lpImcP)
  4959. {
  4960. LPTRANSMSG lpMsgBuf;
  4961. HIMCC hMem;
  4962. BOOL bCantReSize;
  4963. if (!hIMC) {
  4964. return;
  4965. } else if (!lpIMC) {
  4966. return;
  4967. } else if (!lpImcP) {
  4968. return;
  4969. } else if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
  4970. return;
  4971. } else {
  4972. }
  4973. bCantReSize = FALSE;
  4974. if (!lpIMC->hMsgBuf) {
  4975. // it maybe free by IME, up to GEN_MSG_MAX messages for max case
  4976. lpIMC->hMsgBuf = ImmCreateIMCC(GEN_MSG_MAX * sizeof(TRANSMSG));
  4977. } else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf
  4978. + GEN_MSG_MAX) * sizeof(TRANSMSG))) {
  4979. lpIMC->hMsgBuf = hMem;
  4980. } else {
  4981. bCantReSize = TRUE;
  4982. }
  4983. if (!lpIMC->hMsgBuf) {
  4984. lpIMC->dwNumMsgBuf = 0;
  4985. return;
  4986. }
  4987. lpMsgBuf = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
  4988. if (!lpMsgBuf) {
  4989. return;
  4990. }
  4991. if (bCantReSize) {
  4992. LPTRANSMSG lpNewBuf;
  4993. hMem = ImmCreateIMCC((lpIMC->dwNumMsgBuf + GEN_MSG_MAX) *
  4994. sizeof(TRANSMSG));
  4995. if (!hMem) {
  4996. ImmUnlockIMCC(lpIMC->hMsgBuf);
  4997. return;
  4998. }
  4999. lpNewBuf = (LPTRANSMSG)ImmLockIMCC(hMem);
  5000. if (!lpMsgBuf) {
  5001. ImmUnlockIMCC(lpIMC->hMsgBuf);
  5002. return;
  5003. }
  5004. CopyMemory(lpNewBuf, lpMsgBuf, lpIMC->dwNumMsgBuf *
  5005. sizeof(TRANSMSG));
  5006. ImmUnlockIMCC(lpIMC->hMsgBuf);
  5007. ImmDestroyIMCC(lpIMC->hMsgBuf);
  5008. lpIMC->hMsgBuf = hMem;
  5009. lpMsgBuf = lpNewBuf;
  5010. }
  5011. lpIMC->dwNumMsgBuf += TranslateImeMessage(NULL, lpIMC, lpImcP);
  5012. ImmUnlockIMCC(lpIMC->hMsgBuf);
  5013. lpImcP->fdwImeMsg &= (MSG_ALREADY_OPEN|MSG_ALREADY_START);
  5014. lpImcP->fdwGcsFlag &= (GCS_RESULTREAD|GCS_RESULT); // ?
  5015. ImmGenerateMessage(hIMC);
  5016. return;
  5017. }
  5018. /**********************************************************************/
  5019. /* SetString() */
  5020. /* Return Value: */
  5021. /* TRUE - successful, FALSE - failure */
  5022. /**********************************************************************/
  5023. BOOL PASCAL SetString(
  5024. HIMC hIMC,
  5025. LPINPUTCONTEXT lpIMC,
  5026. LPCOMPOSITIONSTRING lpCompStr,
  5027. LPPRIVCONTEXT lpImcP,
  5028. LPSTR lpszRead,
  5029. DWORD dwReadLen)
  5030. {
  5031. DWORD dwPattern;
  5032. DWORD i;
  5033. if (dwReadLen > (lpImeL->nMaxKey * sizeof(WORD)+20)) {
  5034. return (FALSE);
  5035. }
  5036. // compoition/reading attribute
  5037. lpCompStr->dwCompReadAttrLen = dwReadLen;
  5038. lpCompStr->dwCompAttrLen = lpCompStr->dwCompReadAttrLen;
  5039. for (i = 0; i < dwReadLen; i++) { // The IME has converted these chars
  5040. *((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset + i) =
  5041. ATTR_TARGET_CONVERTED;
  5042. }
  5043. // composition/reading clause, 1 clause only
  5044. lpCompStr->dwCompReadClauseLen = 2 * sizeof(DWORD);
  5045. lpCompStr->dwCompClauseLen = lpCompStr->dwCompReadClauseLen;
  5046. *(LPUNADWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadClauseOffset +
  5047. sizeof(DWORD)) = dwReadLen;
  5048. lpCompStr->dwCompReadStrLen = dwReadLen;
  5049. lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
  5050. CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset, lpszRead,
  5051. dwReadLen);
  5052. // dlta start from 0;
  5053. lpCompStr->dwDeltaStart = 0;
  5054. // cursor is next to composition string
  5055. lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
  5056. lpCompStr->dwResultReadClauseLen = 0;
  5057. lpCompStr->dwResultReadStrLen = 0;
  5058. lpCompStr->dwResultClauseLen = 0;
  5059. lpCompStr->dwResultStrLen = 0;
  5060. // set private input context
  5061. lpImcP->iImeState = CST_INPUT;
  5062. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  5063. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  5064. ~(MSG_OPEN_CANDIDATE);
  5065. }
  5066. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  5067. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) &
  5068. ~(MSG_END_COMPOSITION);
  5069. }
  5070. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  5071. //zst lpImcP->dwCompChar = (DWORD)lpImeL->wSeq2CompTbl[
  5072. //zst lpImcP->bSeq[lpCompStr->dwCompReadStrLen / 2 - 1]];
  5073. lpImcP->dwCompChar = HIBYTE(lpImcP->dwCompChar) |
  5074. (LOBYTE(lpImcP->dwCompChar) << 8);
  5075. lpImcP->fdwGcsFlag = GCS_COMPREAD|GCS_COMP|
  5076. GCS_DELTASTART|GCS_CURSORPOS;
  5077. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  5078. if (lpCompStr->dwCompReadStrLen >= sizeof(WORD) * lpImeL->nMaxKey) {
  5079. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  5080. lpImcP->fdwGcsFlag |= GCS_RESULTREAD|GCS_RESULTSTR;
  5081. }
  5082. } else {
  5083. if (dwReadLen < sizeof(WORD) * lpImeL->nMaxKey) {
  5084. // quick key
  5085. if (lpImeL->fModeConfig & MODE_CONFIG_QUICK_KEY) {
  5086. //zst Finalize(lpIMC, lpCompStr, lpImcP, FALSE);
  5087. }
  5088. } else {
  5089. UINT nCand;
  5090. LPGUIDELINE lpGuideLine;
  5091. //zst nCand = Finalize(lpIMC, lpCompStr, lpImcP, TRUE);
  5092. if (!lpIMC->hGuideLine) {
  5093. goto SeStGenMsg;
  5094. }
  5095. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  5096. if (!lpGuideLine) {
  5097. goto SeStGenMsg;
  5098. /*
  5099. } else if (nCand == 1) {
  5100. } else if (nCand > 1) {
  5101. */
  5102. } else {
  5103. // nothing found, end user, you have an error now
  5104. lpGuideLine->dwLevel = GL_LEVEL_ERROR;
  5105. lpGuideLine->dwIndex = GL_ID_TYPINGERROR;
  5106. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  5107. }
  5108. ImmUnlockIMCC(lpIMC->hGuideLine);
  5109. }
  5110. }
  5111. SeStGenMsg:
  5112. GenerateMessage(hIMC, lpIMC, lpImcP);
  5113. return (TRUE);
  5114. }
  5115. /**********************************************************************/
  5116. /* CompEscapeKey() */
  5117. /**********************************************************************/
  5118. void PASCAL CompEscapeKey(
  5119. LPINPUTCONTEXT lpIMC,
  5120. LPCOMPOSITIONSTRING lpCompStr,
  5121. LPGUIDELINE lpGuideLine,
  5122. LPPRIVCONTEXT lpImcP)
  5123. {
  5124. if (!lpGuideLine) {
  5125. MessageBeep((UINT)-1);
  5126. } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
  5127. } else {
  5128. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  5129. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  5130. lpGuideLine->dwStrLen = 0;
  5131. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  5132. }
  5133. if (lpImcP->iImeState != CST_INIT) {
  5134. } else if (lpCompStr->dwCompStrLen) {
  5135. // clean the compose string
  5136. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  5137. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
  5138. ~(MSG_START_COMPOSITION);
  5139. } else {
  5140. }
  5141. lpImcP->iImeState = CST_INIT;
  5142. // *(LPDWORD)lpImcP->bSeq = 0;
  5143. // lpImcP->wPhraseNextOffset = lpImcP->wWordNextOffset = 0;
  5144. InitCvtPara();
  5145. if (lpCompStr) {
  5146. InitCompStr(lpCompStr);
  5147. lpImcP->fdwImeMsg |= MSG_END_COMPOSITION;
  5148. lpImcP->dwCompChar = VK_ESCAPE;
  5149. lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  5150. GCS_DELTASTART);
  5151. }
  5152. return;
  5153. }
  5154. /**********************************************************************/
  5155. /* CandEscapeKey() */
  5156. /**********************************************************************/
  5157. void PASCAL CandEscapeKey(
  5158. LPINPUTCONTEXT lpIMC,
  5159. LPPRIVCONTEXT lpImcP)
  5160. {
  5161. LPCOMPOSITIONSTRING lpCompStr;
  5162. LPGUIDELINE lpGuideLine;
  5163. // clean all candidate information
  5164. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  5165. ClearCand(lpIMC);
  5166. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  5167. ~(MSG_OPEN_CANDIDATE);
  5168. }
  5169. lpImcP->iImeState = CST_INPUT;
  5170. // if it start composition, we need to clean composition
  5171. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  5172. return;
  5173. }
  5174. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  5175. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  5176. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  5177. ImmUnlockIMCC(lpIMC->hGuideLine);
  5178. ImmUnlockIMCC(lpIMC->hCompStr);
  5179. return;
  5180. }
  5181. /**********************************************************************/
  5182. /* CompCancel() */
  5183. /**********************************************************************/
  5184. void PASCAL CompCancel(
  5185. HIMC hIMC,
  5186. LPINPUTCONTEXT lpIMC)
  5187. {
  5188. LPPRIVCONTEXT lpImcP;
  5189. if (!lpIMC->hPrivate) {
  5190. return;
  5191. }
  5192. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5193. if (!lpImcP) {
  5194. return;
  5195. }
  5196. lpImcP->fdwGcsFlag = (DWORD)0;
  5197. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  5198. CandEscapeKey(lpIMC, lpImcP);
  5199. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  5200. LPCOMPOSITIONSTRING lpCompStr;
  5201. LPGUIDELINE lpGuideLine;
  5202. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  5203. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  5204. if ( lpCompStr && lpGuideLine )
  5205. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  5206. ImmUnlockIMCC(lpIMC->hGuideLine);
  5207. ImmUnlockIMCC(lpIMC->hCompStr);
  5208. } else {
  5209. ImmUnlockIMCC(lpIMC->hPrivate);
  5210. return;
  5211. }
  5212. lpImcP->fdwImeMsg |= MSG_COMPOSITION; //#52224
  5213. GenerateMessage(hIMC, lpIMC, lpImcP);
  5214. ImmUnlockIMCC(lpIMC->hPrivate);
  5215. InitCvtPara();
  5216. return;
  5217. }
  5218. /**********************************************************************/
  5219. /* ImeSetCompositionString() */
  5220. /* Return Value: */
  5221. /* TRUE - successful, FALSE - failure */
  5222. /**********************************************************************/
  5223. BOOL WINAPI ImeSetCompositionString(
  5224. HIMC hIMC,
  5225. DWORD dwIndex,
  5226. LPVOID lpComp,
  5227. DWORD dwCompLen,
  5228. LPVOID lpRead,
  5229. DWORD dwReadLen)
  5230. {
  5231. LPINPUTCONTEXT lpIMC;
  5232. LPCOMPOSITIONSTRING lpCompStr;
  5233. LPPRIVCONTEXT lpImcP;
  5234. BOOL fRet;
  5235. if (!hIMC) {
  5236. return (FALSE);
  5237. }
  5238. // composition string must == reading string
  5239. // reading is more important
  5240. if (!dwReadLen) {
  5241. dwReadLen = dwCompLen;
  5242. }
  5243. // composition string must == reading string
  5244. // reading is more important
  5245. if (!lpRead) {
  5246. lpRead = lpComp;
  5247. }
  5248. if (!dwReadLen) {
  5249. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5250. if (!lpIMC) {
  5251. return (FALSE);
  5252. }
  5253. CompCancel(hIMC, lpIMC);
  5254. ImmUnlockIMC(hIMC);
  5255. return (TRUE);
  5256. } else if (!lpRead) {
  5257. return (FALSE);
  5258. } else if (!dwCompLen) {
  5259. } else if (!lpComp) {
  5260. } else if (dwReadLen != dwCompLen) {
  5261. return (FALSE);
  5262. } else if (lpRead == lpComp) {
  5263. } else if (!lstrcmp(lpRead, lpComp)) {
  5264. // composition string must == reading string
  5265. } else {
  5266. // composition string != reading string
  5267. return (FALSE);
  5268. }
  5269. if (dwIndex != SCS_SETSTR) {
  5270. return (FALSE);
  5271. }
  5272. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5273. if (!lpIMC) {
  5274. return (FALSE);
  5275. }
  5276. if (!lpIMC->hCompStr) {
  5277. ImmUnlockIMC(hIMC);
  5278. return (FALSE);
  5279. }
  5280. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  5281. if (!lpCompStr) {
  5282. ImmUnlockIMC(hIMC);
  5283. return (FALSE);
  5284. }
  5285. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5286. fRet = SetString(hIMC, lpIMC, lpCompStr, lpImcP, lpRead, dwReadLen);
  5287. ImmUnlockIMCC(lpIMC->hPrivate);
  5288. ImmUnlockIMCC(lpIMC->hCompStr);
  5289. ImmUnlockIMC(hIMC);
  5290. return (fRet);
  5291. }
  5292. /**********************************************************************/
  5293. /* ToggleSoftKbd() */
  5294. /**********************************************************************/
  5295. void PASCAL ToggleSoftKbd(
  5296. HIMC hIMC,
  5297. LPINPUTCONTEXT lpIMC)
  5298. {
  5299. LPPRIVCONTEXT lpImcP;
  5300. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5301. if (!lpImcP) {
  5302. return;
  5303. }
  5304. lpImcP->fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  5305. GenerateMessage(hIMC, lpIMC, lpImcP);
  5306. ImmUnlockIMCC(lpIMC->hPrivate);
  5307. return;
  5308. }
  5309. /**********************************************************************/
  5310. /* NotifySelectCand() */
  5311. /**********************************************************************/
  5312. void PASCAL NotifySelectCand( // app tell IME that one candidate string is
  5313. // selected (by mouse or non keyboard action
  5314. // - for example sound)
  5315. HIMC hIMC,
  5316. LPINPUTCONTEXT lpIMC,
  5317. LPCANDIDATEINFO lpCandInfo,
  5318. DWORD dwIndex,
  5319. DWORD dwValue)
  5320. {
  5321. LPPRIVCONTEXT lpImcP;
  5322. if (!lpCandInfo) {
  5323. return;
  5324. }
  5325. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5326. CharProc((WORD)dwValue,0,0,hIMC,lpIMC,lpImcP);
  5327. GenerateMessage2(hIMC, lpIMC, lpImcP);
  5328. ImmUnlockIMCC(lpIMC->hPrivate);
  5329. ImmUnlockIMCC(lpIMC->hCompStr);
  5330. return;
  5331. }
  5332. /**********************************************************************/
  5333. /* NotifySetMode() */
  5334. /**********************************************************************/
  5335. void PASCAL NotifySetMode(
  5336. HIMC hIMC)
  5337. {
  5338. LPINPUTCONTEXT lpIMC;
  5339. LPPRIVCONTEXT lpImcP;
  5340. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5341. if(!lpIMC) return ;
  5342. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5343. if (!lpImcP){
  5344. ImmUnlockIMC(hIMC);
  5345. return ;
  5346. }
  5347. GenerateMessage(hIMC, lpIMC, lpImcP);
  5348. ImmUnlockIMCC(lpIMC->hPrivate);
  5349. ImmUnlockIMC(hIMC);
  5350. return;
  5351. }
  5352. /**********************************************************************/
  5353. /* GenerateImeMessage() */
  5354. /**********************************************************************/
  5355. void PASCAL GenerateImeMessage(
  5356. HIMC hIMC,
  5357. LPINPUTCONTEXT lpIMC,
  5358. DWORD fdwImeMsg)
  5359. {
  5360. LPPRIVCONTEXT lpImcP;
  5361. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5362. if (!lpImcP) {
  5363. return;
  5364. }
  5365. lpImcP->fdwImeMsg |= fdwImeMsg;
  5366. if (fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  5367. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  5368. } else if (fdwImeMsg & (MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE)) {
  5369. lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE);
  5370. } else {
  5371. }
  5372. if (fdwImeMsg & MSG_END_COMPOSITION) {
  5373. lpImcP->fdwImeMsg &= ~(MSG_START_COMPOSITION);
  5374. } else if (fdwImeMsg & MSG_START_COMPOSITION) {
  5375. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION);
  5376. } else {
  5377. }
  5378. GenerateMessage(hIMC, lpIMC, lpImcP);
  5379. ImmUnlockIMCC(lpIMC->hPrivate);
  5380. return;
  5381. }
  5382. /**********************************************************************/
  5383. /* NotifyIME() */
  5384. /* Return Value: */
  5385. /* TRUE - successful, FALSE - failure */
  5386. /**********************************************************************/
  5387. BOOL WINAPI NotifyIME(
  5388. HIMC hIMC,
  5389. DWORD dwAction,
  5390. DWORD dwIndex,
  5391. DWORD dwValue)
  5392. {
  5393. LPINPUTCONTEXT lpIMC;
  5394. DWORD fdwImeMsg;
  5395. LPPRIVCONTEXT lpImcP;
  5396. if (!hIMC) {
  5397. return (TRUE);
  5398. }
  5399. switch (dwAction) {
  5400. case NI_OPENCANDIDATE: // after a composition string is determined
  5401. // if an IME can open candidate, it will.
  5402. // if it can not, app also can not open it.
  5403. case NI_CLOSECANDIDATE:
  5404. return (FALSE);
  5405. case NI_SELECTCANDIDATESTR:
  5406. break; // need to handle it
  5407. case NI_CHANGECANDIDATELIST:
  5408. return (TRUE); // not important to the IME
  5409. case NI_CONTEXTUPDATED:
  5410. switch (dwValue) {
  5411. case IMC_SETCONVERSIONMODE:
  5412. case IMC_SETSENTENCEMODE:
  5413. case IMC_SETOPENSTATUS:
  5414. break; // need to handle it
  5415. case IMC_SETCANDIDATEPOS:
  5416. case IMC_SETCOMPOSITIONFONT:
  5417. case IMC_SETCOMPOSITIONWINDOW:
  5418. return (TRUE); // not important to the IME
  5419. default:
  5420. return (FALSE); // not supported
  5421. }
  5422. break;
  5423. case NI_COMPOSITIONSTR:
  5424. switch (dwIndex) {
  5425. case CPS_CONVERT: // all composition string can not be convert
  5426. case CPS_REVERT: // any more, it maybe work for some
  5427. // intelligent phonetic IMEs
  5428. return (FALSE);
  5429. case CPS_CANCEL:
  5430. break; // need to handle it
  5431. default:
  5432. return (FALSE); // not supported
  5433. }
  5434. break; // need to handle it
  5435. default:
  5436. return (FALSE); // not supported
  5437. }
  5438. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5439. if (!lpIMC) {
  5440. return (FALSE);
  5441. }
  5442. switch (dwAction) {
  5443. case NI_CONTEXTUPDATED:
  5444. switch (dwValue) {
  5445. case IMC_SETCONVERSIONMODE:
  5446. if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_FULLSHAPE) {
  5447. break;
  5448. }
  5449. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SOFTKBD) {
  5450. ToggleSoftKbd(hIMC, lpIMC);
  5451. if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_SOFTKBD) {
  5452. break;
  5453. }
  5454. }
  5455. if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_NATIVE) {
  5456. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  5457. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC);
  5458. }
  5459. // if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_CHARCODE) {
  5460. // lpIMC->fdwConversion &= ~(IME_CMODE_EUDC);
  5461. // }
  5462. CompCancel(hIMC, lpIMC);
  5463. break;
  5464. /*
  5465. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_CHARCODE) {
  5466. // reject CHARCODE
  5467. lpIMC->fdwConversion &= ~IME_CMODE_CHARCODE;
  5468. MessageBeep((UINT)-1);
  5469. break;
  5470. }
  5471. fdwImeMsg = 0;
  5472. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_NOCONVERSION) {
  5473. lpIMC->fdwConversion |= IME_CMODE_NATIVE;
  5474. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  5475. IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  5476. }
  5477. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_EUDC) {
  5478. lpIMC->fdwConversion |= IME_CMODE_NATIVE;
  5479. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  5480. IME_CMODE_NOCONVERSION|IME_CMODE_SYMBOL);
  5481. }
  5482. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SOFTKBD) {
  5483. LPPRIVCONTEXT lpImcP;
  5484. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  5485. MessageBeep((UINT)-1);
  5486. break;
  5487. }
  5488. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  5489. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  5490. } else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  5491. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  5492. } else {
  5493. }
  5494. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5495. if (!lpImcP) {
  5496. goto NotifySKOvr;
  5497. }
  5498. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  5499. // now we already in soft keyboard state by
  5500. // this change
  5501. // even end user finish the symbol, we should not
  5502. // turn off soft keyboard
  5503. lpImcP->fdwImeMsg |= MSG_ALREADY_SOFTKBD;
  5504. } else {
  5505. // now we are not in soft keyboard state by
  5506. // this change
  5507. // after end user finish the symbol, we should
  5508. // turn off soft keyboard
  5509. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_SOFTKBD);
  5510. }
  5511. ImmUnlockIMCC(lpIMC->hPrivate);
  5512. NotifySKOvr:
  5513. ; // NULL statement for goto
  5514. }
  5515. if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_NATIVE) {
  5516. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  5517. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  5518. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  5519. }
  5520. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SYMBOL) {
  5521. LPCOMPOSITIONSTRING lpCompStr;
  5522. LPPRIVCONTEXT lpImcP;
  5523. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  5524. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  5525. MessageBeep((UINT)-1);
  5526. break;
  5527. }
  5528. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  5529. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  5530. lpIMC->fdwConversion |= (dwIndex & IME_CMODE_SYMBOL);
  5531. MessageBeep((UINT)-1);
  5532. break;
  5533. }
  5534. lpCompStr = ImmLockIMCC(lpIMC->hCompStr);
  5535. if (lpCompStr) {
  5536. if (!lpCompStr->dwCompStrLen) {
  5537. } else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  5538. // if there is a string we could not change
  5539. // to symbol mode
  5540. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  5541. MessageBeep((UINT)-1);
  5542. break;
  5543. } else {
  5544. }
  5545. ImmUnlockIMCC(lpIMC->hCompStr);
  5546. }
  5547. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  5548. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC);
  5549. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  5550. lpIMC->fdwConversion |= IME_CMODE_SOFTKBD;
  5551. } else if (lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate)) {
  5552. // we borrow the bit for this usage
  5553. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_SOFTKBD)) {
  5554. lpIMC->fdwConversion &= ~(IME_CMODE_SOFTKBD);
  5555. }
  5556. ImmUnlockIMCC(lpIMC->hPrivate);
  5557. } else {
  5558. }
  5559. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  5560. }
  5561. if (fdwImeMsg) {
  5562. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5563. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5564. if(!lpImcP){
  5565. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg &~(MSG_IN_IMETOASCIIEX);
  5566. }
  5567. ImmUnlockIMCC(lpIMC->hPrivate);
  5568. ImmUnlockIMC(hIMC);
  5569. GenerateImeMessage(hIMC, lpIMC, fdwImeMsg);
  5570. }
  5571. if ((lpIMC->fdwConversion ^ dwIndex) & ~(IME_CMODE_FULLSHAPE|
  5572. IME_CMODE_SOFTKBD)) {
  5573. } else {
  5574. break;
  5575. }
  5576. CompCancel(hIMC, lpIMC);
  5577. break;
  5578. */
  5579. case IMC_SETOPENSTATUS:
  5580. CompCancel(hIMC, lpIMC);
  5581. break;
  5582. default:
  5583. break;
  5584. }
  5585. break;
  5586. case NI_SELECTCANDIDATESTR:
  5587. if (!lpIMC->fOpen) {
  5588. break;
  5589. } else if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
  5590. break;
  5591. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  5592. break;
  5593. } else if (!lpIMC->hCandInfo) {
  5594. break;
  5595. } else {
  5596. LPCANDIDATEINFO lpCandInfo;
  5597. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  5598. NotifySelectCand(hIMC, lpIMC, lpCandInfo, dwIndex, dwValue);
  5599. ImmUnlockIMCC(lpIMC->hCandInfo);
  5600. }
  5601. break;
  5602. case NI_COMPOSITIONSTR:
  5603. switch (dwIndex) {
  5604. case CPS_CANCEL:
  5605. CompCancel(hIMC, lpIMC);
  5606. break;
  5607. default:
  5608. break;
  5609. }
  5610. break;
  5611. default:
  5612. break;
  5613. }
  5614. ImmUnlockIMC(hIMC);
  5615. return (TRUE);
  5616. }
  5617. /**********************************************************************/
  5618. /* ImeRegsisterWord */
  5619. /* Return Value: */
  5620. /* TRUE - successful, FALSE - failure */
  5621. /**********************************************************************/
  5622. BOOL WINAPI ImeRegisterWord(
  5623. LPCTSTR lpszReading,
  5624. DWORD dwStyle,
  5625. LPCTSTR lpszString)
  5626. {
  5627. return (0);
  5628. }
  5629. /**********************************************************************/
  5630. /* ImeUnregsisterWord */
  5631. /* Return Value: */
  5632. /* TRUE - successful, FALSE - failure */
  5633. /**********************************************************************/
  5634. BOOL WINAPI ImeUnregisterWord(
  5635. LPCTSTR lpszReading,
  5636. DWORD dwStyle,
  5637. LPCTSTR lpszString)
  5638. {
  5639. return (0);
  5640. }
  5641. /**********************************************************************/
  5642. /* ImeGetRegsisterWordStyle */
  5643. /* Return Value: */
  5644. /* number of styles copied/required */
  5645. /**********************************************************************/
  5646. UINT WINAPI ImeGetRegisterWordStyle(
  5647. UINT nItem,
  5648. LPSTYLEBUF lpStyleBuf)
  5649. {
  5650. return (1);
  5651. }
  5652. /**********************************************************************/
  5653. /* ImeEnumRegisterWord */
  5654. /* Return Value: */
  5655. /* the last value return by the callback function */
  5656. /**********************************************************************/
  5657. UINT WINAPI ImeEnumRegisterWord(
  5658. REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
  5659. LPCTSTR lpszReading,
  5660. DWORD dwStyle,
  5661. LPCTSTR lpszString,
  5662. LPVOID lpData)
  5663. {
  5664. return (0);
  5665. }
  5666. /**********************************************************************/
  5667. /* GetStatusWnd */
  5668. /* Return Value : */
  5669. /* window handle of status window */
  5670. /**********************************************************************/
  5671. HWND PASCAL GetStatusWnd(
  5672. HWND hUIWnd) // UI window
  5673. {
  5674. HGLOBAL hUIPrivate;
  5675. LPUIPRIV lpUIPrivate;
  5676. HWND hStatusWnd;
  5677. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  5678. if (!hUIPrivate) { // can not darw status window
  5679. return (HWND)NULL;
  5680. }
  5681. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  5682. if (!lpUIPrivate) { // can not draw status window
  5683. return (HWND)NULL;
  5684. }
  5685. hStatusWnd = lpUIPrivate->hStatusWnd;
  5686. GlobalUnlock(hUIPrivate);
  5687. return (hStatusWnd);
  5688. }
  5689. /**********************************************************************/
  5690. /* SetStatusWindowPos() */
  5691. /**********************************************************************/
  5692. LRESULT PASCAL SetStatusWindowPos(
  5693. HWND hStatusWnd)
  5694. {
  5695. HWND hUIWnd;
  5696. HIMC hIMC;
  5697. LPINPUTCONTEXT lpIMC;
  5698. RECT rcStatusWnd;
  5699. POINT ptPos;
  5700. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  5701. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  5702. if (!hIMC) {
  5703. return (1L);
  5704. }
  5705. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5706. if (!lpIMC) { // Oh! Oh!
  5707. return (1L);
  5708. }
  5709. GetWindowRect(hStatusWnd, &rcStatusWnd);
  5710. //DebugShow2( "ptPos=",lpIMC->ptStatusWndPos.x,"ptPos.y", rcStatusWnd.left);
  5711. if (lpIMC->ptStatusWndPos.x != rcStatusWnd.left) {
  5712. } else if (lpIMC->ptStatusWndPos.y != rcStatusWnd.top) {
  5713. } else {
  5714. ImmUnlockIMC(hIMC);
  5715. return (0L);
  5716. }
  5717. //DebugShow2( "ptPos111=",NULL,"ptPos.y",NULL);
  5718. // ptPos = lpIMC->ptStatusWndPos;
  5719. // display boundary adjust
  5720. ptPos.x = lpIMC->ptStatusWndPos.x;
  5721. ptPos.y = lpIMC->ptStatusWndPos.y;
  5722. AdjustStatusBoundary(&ptPos);
  5723. SetWindowPos(hStatusWnd, NULL,
  5724. ptPos.x, ptPos.y,
  5725. 0, 0, /*SWP_SHOWWINDOW|*/SWP_NOACTIVATE/*|SWP_NOCOPYBITS*/|SWP_NOSIZE|SWP_NOZORDER);
  5726. CountDefaultComp(ptPos.x,ptPos.y,sImeG.rcWorkArea);
  5727. ImmUnlockIMC(hIMC);
  5728. return (0L);
  5729. }
  5730. /**********************************************************************/
  5731. /* CountDefaultComp() */
  5732. /**********************************************************************/
  5733. int CountDefaultComp(int x, int y, RECT Area)
  5734. {
  5735. POINT Comp,Cand;
  5736. Comp.x = lpImeL->ptZLComp.x;
  5737. Comp.y = lpImeL->ptZLComp.y;
  5738. Cand.x = lpImeL->ptZLCand.x;
  5739. Cand.y = lpImeL->ptZLCand.y;
  5740. lpImeL->ptZLComp.x = x + sImeG.xStatusWi+4;
  5741. lpImeL->ptZLComp.y = y;
  5742. if ((Area.right-lpImeL->ptZLComp.x -lpImeL->xCompWi)<10){
  5743. lpImeL->ptZLComp.x = x - lpImeL->xCompWi-4;
  5744. }
  5745. // lpImeL->ptZLCand.x = lpImeL->ptZLComp.x - lpImeL->xCandWi -4;}
  5746. return 0;
  5747. }
  5748. /**********************************************************************/
  5749. /* ShowStatus() */
  5750. /**********************************************************************/
  5751. void PASCAL ShowStatus( // Show the status window - shape / soft KBD
  5752. // alphanumeric ...
  5753. HWND hUIWnd,
  5754. int nShowStatusCmd)
  5755. {
  5756. HGLOBAL hUIPrivate;
  5757. LPUIPRIV lpUIPrivate;
  5758. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  5759. if (!hUIPrivate) { // can not darw status window
  5760. return;
  5761. }
  5762. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  5763. if (!lpUIPrivate) { // can not draw status window
  5764. return;
  5765. }
  5766. if (!lpUIPrivate->hStatusWnd) {
  5767. // not in show status window mode
  5768. } else if (lpUIPrivate->nShowStatusCmd != nShowStatusCmd) {
  5769. RECT Area;
  5770. SystemParametersInfo(SPI_GETWORKAREA, 0, &Area, 0);
  5771. if((sImeG.rcWorkArea.bottom != Area.bottom)
  5772. ||(sImeG.rcWorkArea.top != Area.top)
  5773. ||(sImeG.rcWorkArea.left != Area.left)
  5774. ||(sImeG.rcWorkArea.right != Area.right))
  5775. {
  5776. HIMC hIMC;
  5777. LPINPUTCONTEXT lpIMC;
  5778. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  5779. if(hIMC){
  5780. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5781. if (lpIMC){
  5782. if (((lpIMC->ptStatusWndPos.y + sImeG.yStatusHi)==sImeG.rcWorkArea.bottom)
  5783. ||((lpIMC->ptStatusWndPos.y + sImeG.yStatusHi)>Area.bottom)){
  5784. lpIMC->ptStatusWndPos.y = Area.bottom - sImeG.yStatusHi;
  5785. } else if ((lpIMC->ptStatusWndPos.y ==sImeG.rcWorkArea.top)
  5786. ||(lpIMC->ptStatusWndPos.y < Area.top)){
  5787. lpIMC->ptStatusWndPos.y = Area.top;
  5788. }
  5789. if ((lpIMC->ptStatusWndPos.x==sImeG.rcWorkArea.left)
  5790. ||(lpIMC->ptStatusWndPos.x<Area.left)){
  5791. lpIMC->ptStatusWndPos.x = Area.left;
  5792. }else if (((lpIMC->ptStatusWndPos.x + sImeG.xStatusWi)==sImeG.rcWorkArea.right)
  5793. ||((lpIMC->ptStatusWndPos.x + sImeG.xStatusWi)>Area.right)){
  5794. lpIMC->ptStatusWndPos.x = Area.right - sImeG.xStatusWi;
  5795. }
  5796. SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
  5797. lpIMC->ptStatusWndPos.x,
  5798. lpIMC->ptStatusWndPos.y,
  5799. 0, 0,
  5800. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  5801. CountDefaultComp(lpIMC->ptStatusWndPos.x,lpIMC->ptStatusWndPos.y,Area);
  5802. ImmUnlockIMC(hIMC);
  5803. sImeG.rcWorkArea.bottom = Area.bottom;
  5804. sImeG.rcWorkArea.top = Area.top;
  5805. sImeG.rcWorkArea.left = Area.left;
  5806. sImeG.rcWorkArea.right = Area.right;
  5807. }
  5808. }
  5809. }
  5810. ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
  5811. lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
  5812. } else {
  5813. }
  5814. GlobalUnlock(hUIPrivate);
  5815. return;
  5816. }
  5817. /**********************************************************************/
  5818. /* OpenStatus() */
  5819. /**********************************************************************/
  5820. void PASCAL OpenStatus( // open status window
  5821. HWND hUIWnd)
  5822. {
  5823. HGLOBAL hUIPrivate;
  5824. LPUIPRIV lpUIPrivate;
  5825. HIMC hIMC;
  5826. LPINPUTCONTEXT lpIMC;
  5827. POINT ptPos;
  5828. int nShowStatusCmd;
  5829. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  5830. if (!hUIPrivate) { // can not darw status window
  5831. return;
  5832. }
  5833. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  5834. if (!lpUIPrivate) { // can not draw status window
  5835. return;
  5836. }
  5837. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  5838. if (!hIMC) {
  5839. ptPos.x = sImeG.rcWorkArea.left;
  5840. ptPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
  5841. nShowStatusCmd = SW_HIDE;
  5842. } else if (lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)) {
  5843. if (lpIMC->ptStatusWndPos.x < sImeG.rcWorkArea.left) {
  5844. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
  5845. } else if (lpIMC->ptStatusWndPos.x + sImeG.xStatusWi >
  5846. sImeG.rcWorkArea.right) {
  5847. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
  5848. sImeG.xStatusWi;
  5849. }
  5850. if (lpIMC->ptStatusWndPos.y < sImeG.rcWorkArea.top) {
  5851. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.top;
  5852. } else if (lpIMC->ptStatusWndPos.y + sImeG.yStatusHi >
  5853. sImeG.rcWorkArea.right) {
  5854. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  5855. sImeG.yStatusHi;
  5856. }
  5857. ptPos.x = lpIMC->ptStatusWndPos.x;
  5858. ptPos.y = lpIMC->ptStatusWndPos.y,
  5859. ImmUnlockIMC(hIMC);
  5860. nShowStatusCmd = SW_SHOWNOACTIVATE;
  5861. } else {
  5862. ptPos.x = sImeG.rcWorkArea.left;
  5863. ptPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
  5864. nShowStatusCmd = SW_HIDE;
  5865. }
  5866. if (lpUIPrivate->hStatusWnd) {
  5867. SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
  5868. ptPos.x, ptPos.y,
  5869. 0, 0,
  5870. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  5871. } else { // create status window
  5872. lpUIPrivate->hStatusWnd = CreateWindowEx(
  5873. 0,
  5874. szStatusClassName, NULL, WS_POPUP|WS_DISABLED/*|WS_BORDER*/,
  5875. ptPos.x, ptPos.y,
  5876. sImeG.xStatusWi, sImeG.yStatusHi,
  5877. hUIWnd, (HMENU)NULL, hInst, NULL);
  5878. if ( lpUIPrivate->hStatusWnd )
  5879. {
  5880. ReInitIme(lpUIPrivate->hStatusWnd, lpImeL->wImeStyle); //#@2
  5881. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_OFFSET,
  5882. WINDOW_NOT_DRAG);
  5883. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_XY, 0L);
  5884. }
  5885. }
  5886. GlobalUnlock(hUIPrivate);
  5887. return;
  5888. }
  5889. /**********************************************************************/
  5890. /* DestroyStatusWindow() */
  5891. /**********************************************************************/
  5892. void PASCAL DestroyStatusWindow(
  5893. HWND hStatusWnd)
  5894. {
  5895. HWND hUIWnd;
  5896. HGLOBAL hUIPrivate;
  5897. LPUIPRIV lpUIPrivate;
  5898. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  5899. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  5900. if (!hUIPrivate) { // can not darw status window
  5901. return;
  5902. }
  5903. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  5904. if (!lpUIPrivate) { // can not draw status window
  5905. return;
  5906. }
  5907. lpUIPrivate->nShowStatusCmd = SW_HIDE;
  5908. lpUIPrivate->hStatusWnd = (HWND)NULL;
  5909. GlobalUnlock(hUIPrivate);
  5910. return;
  5911. }
  5912. /**********************************************************************/
  5913. /* SetStatus */
  5914. /**********************************************************************/
  5915. void PASCAL SetStatus(
  5916. HWND hStatusWnd,
  5917. LPPOINT lpptCursor)
  5918. {
  5919. HWND hUIWnd;
  5920. HIMC hIMC;
  5921. LPINPUTCONTEXT lpIMC;
  5922. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  5923. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  5924. if (!hIMC) {
  5925. return;
  5926. }
  5927. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  5928. if (!lpIMC) {
  5929. return;
  5930. }
  5931. if (!lpIMC->fOpen) {
  5932. ImmSetOpenStatus(hIMC, TRUE);
  5933. } else if (PtInRect(&sImeG.rcInputText, *lpptCursor)) {
  5934. DWORD fdwConversion;
  5935. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  5936. // change to alphanumeric mode
  5937. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_NATIVE );
  5938. {
  5939. LPPRIVCONTEXT lpImcP;
  5940. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  5941. ghIMC=hIMC;
  5942. glpIMCP=lpImcP;
  5943. glpIMC=lpIMC;
  5944. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  5945. cls_prompt();
  5946. InitCvtPara();
  5947. GenerateMessage(hIMC, lpIMC, lpImcP);
  5948. ImmUnlockIMCC(lpIMC->hPrivate);
  5949. }
  5950. } else {
  5951. if(lpIMC->fdwConversion & IME_CMODE_NOCONVERSION){
  5952. // Simulate a key press
  5953. keybd_event( VK_CAPITAL,
  5954. 0x3A,
  5955. KEYEVENTF_EXTENDEDKEY | 0,
  5956. 0 );
  5957. // Simulate a key release
  5958. keybd_event( VK_CAPITAL,
  5959. 0x3A,
  5960. KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
  5961. 0);
  5962. cap_mode = 0;
  5963. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  5964. ~(IME_CMODE_NOCONVERSION);
  5965. }else
  5966. fdwConversion = lpIMC->fdwConversion |IME_CMODE_NATIVE;
  5967. }
  5968. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  5969. }
  5970. if (PtInRect(&sImeG.rcShapeText, *lpptCursor)) {
  5971. DWORD dwConvMode;
  5972. dwConvMode = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
  5973. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  5974. }
  5975. if (PtInRect(&sImeG.rcSKText, *lpptCursor)) {
  5976. DWORD fdwConversion;
  5977. KeyBoardState = ~KeyBoardState ;
  5978. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SOFTKBD;
  5979. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  5980. }
  5981. if (PtInRect(&sImeG.rcPctText, *lpptCursor)) {
  5982. DWORD fdwConversion;
  5983. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SYMBOL;
  5984. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  5985. }
  5986. if (PtInRect(&sImeG.rcCmdText, *lpptCursor)) {
  5987. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  5988. DWORD fdc;
  5989. if (kb_mode==CIN_STD){
  5990. kb_mode = CIN_SDA;
  5991. fdc = lpIMC->fdwConversion|IME_CMODE_SDA;
  5992. }else{
  5993. kb_mode = CIN_STD;
  5994. fdc = lpIMC->fdwConversion&~IME_CMODE_SDA;
  5995. }
  5996. ImmSetConversionStatus(hIMC, fdc, lpIMC->fdwSentence);
  5997. {
  5998. LPPRIVCONTEXT lpImcP;
  5999. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  6000. ghIMC=hIMC;
  6001. glpIMCP=lpImcP;
  6002. glpIMC=lpIMC;
  6003. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  6004. cls_prompt();
  6005. InitCvtPara();
  6006. GenerateMessage(hIMC, lpIMC, lpImcP);
  6007. ImmUnlockIMCC(lpIMC->hPrivate);
  6008. }
  6009. DispMode(hIMC);
  6010. }else
  6011. MessageBeep((UINT)-1);
  6012. }
  6013. ImmUnlockIMC(hIMC);
  6014. return;
  6015. }
  6016. /**********************************************************************/
  6017. /* PaintStatusWindow() */
  6018. /**********************************************************************/
  6019. void PASCAL PaintStatusWindow(
  6020. HDC hDC,
  6021. HWND hStatusWnd)
  6022. {
  6023. HWND hUIWnd;
  6024. HIMC hIMC;
  6025. LPINPUTCONTEXT lpIMC;
  6026. HBITMAP hInputBmp, hShapeBmp, hSKBmp, hCmdBmp, hPctBmp;
  6027. HBITMAP hOldBmp;
  6028. HDC hMemDC;
  6029. int TopOfBmp = 2;
  6030. if (sImeG.yChiCharHi > 0x10)
  6031. TopOfBmp = 3;
  6032. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  6033. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  6034. if (!hIMC) {
  6035. MessageBeep((UINT)-1);
  6036. return;
  6037. }
  6038. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  6039. MessageBeep((UINT)-1);
  6040. return;
  6041. }
  6042. hInputBmp = (HBITMAP)NULL;
  6043. hShapeBmp = (HBITMAP)NULL;
  6044. hSKBmp = (HBITMAP)NULL;
  6045. hCmdBmp = (HBITMAP)NULL;
  6046. hPctBmp = (HBITMAP)NULL;
  6047. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  6048. hInputBmp = LoadBitmap(hInst, szChinese);
  6049. } else {
  6050. hInputBmp = LoadBitmap(hInst, szEnglish);
  6051. }
  6052. if (!lpIMC->fOpen) {
  6053. hShapeBmp = LoadBitmap(hInst, szNone);
  6054. hPctBmp = LoadBitmap(hInst, szNone);
  6055. hSKBmp = LoadBitmap(hInst, szNone);
  6056. if (kb_mode == CIN_SDA){
  6057. hCmdBmp = LoadBitmap(hInst, szNoSDA);
  6058. }else{
  6059. hCmdBmp = LoadBitmap(hInst, szNoSTD);
  6060. }
  6061. }else{
  6062. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  6063. hShapeBmp = LoadBitmap(hInst, szFullShape);
  6064. } else {
  6065. hShapeBmp = LoadBitmap(hInst, szHalfShape);
  6066. }
  6067. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  6068. hSKBmp = LoadBitmap(hInst, szSoftKBD);
  6069. if (sImeG.First){
  6070. DWORD fdw;
  6071. fdw = lpIMC->fdwConversion;
  6072. ImmSetConversionStatus(hIMC,lpIMC->fdwConversion^IME_CMODE_SOFTKBD, lpIMC->fdwSentence);
  6073. ImmSetConversionStatus(hIMC, fdw, lpIMC->fdwSentence);
  6074. sImeG.First = 0;
  6075. }
  6076. } else {
  6077. hSKBmp = LoadBitmap(hInst, szNoSoftKBD);
  6078. }
  6079. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL)
  6080. hPctBmp = LoadBitmap(hInst, szCPCT);
  6081. else
  6082. hPctBmp = LoadBitmap(hInst, szEPCT);
  6083. if (kb_mode == CIN_SDA){
  6084. hCmdBmp = LoadBitmap(hInst, szSDA);
  6085. }else{
  6086. hCmdBmp = LoadBitmap(hInst, szSTD);
  6087. }
  6088. }
  6089. ImmUnlockIMC(hIMC);
  6090. DrawStatusRect(hDC, 0,0,sImeG.xStatusWi-1, sImeG.yStatusHi-1);
  6091. hMemDC = CreateCompatibleDC(hDC);
  6092. if ( hMemDC )
  6093. {
  6094. hOldBmp = SelectObject(hMemDC, hInputBmp);
  6095. BitBlt(hDC, sImeG.rcInputText.left,TopOfBmp,
  6096. sImeG.rcInputText.right,
  6097. sImeG.yStatusHi,
  6098. hMemDC, 0, 0, SRCCOPY);
  6099. SelectObject(hMemDC, hCmdBmp);
  6100. BitBlt(hDC, sImeG.rcCmdText.left, TopOfBmp,
  6101. sImeG.rcCmdText.right - sImeG.rcCmdText.left,
  6102. sImeG.yStatusHi,
  6103. hMemDC, 0, 0, SRCCOPY);
  6104. SelectObject(hMemDC, hPctBmp);
  6105. BitBlt(hDC, sImeG.rcPctText.left, TopOfBmp,
  6106. sImeG.rcPctText.right - sImeG.rcPctText.left,
  6107. sImeG.yStatusHi,
  6108. hMemDC, 0, 0, SRCCOPY);
  6109. SelectObject(hMemDC, hShapeBmp);
  6110. BitBlt(hDC, sImeG.rcShapeText.left, TopOfBmp,
  6111. sImeG.rcShapeText.right - sImeG.rcShapeText.left,
  6112. sImeG.yStatusHi,
  6113. hMemDC, 0, 0, SRCCOPY);
  6114. SelectObject(hMemDC, hSKBmp);
  6115. BitBlt(hDC, sImeG.rcSKText.left, TopOfBmp,
  6116. sImeG.rcSKText.right - sImeG.rcSKText.left, //zl 95.8.25
  6117. sImeG.yStatusHi,
  6118. hMemDC, 0, 0, SRCCOPY);
  6119. SelectObject(hMemDC, hOldBmp);
  6120. DeleteDC(hMemDC);
  6121. }
  6122. DeleteObject(hInputBmp);
  6123. DeleteObject(hShapeBmp);
  6124. DeleteObject(hSKBmp);
  6125. DeleteObject(hCmdBmp);
  6126. DeleteObject(hPctBmp);
  6127. return;
  6128. }
  6129. /**********************************************************************/
  6130. /* NeedsKey() */
  6131. /* Function: Sub route for Proccesskey proc */
  6132. /* Return Value: */
  6133. /* The converted key value or 0 for not needs. */
  6134. /**********************************************************************/
  6135. WORD
  6136. NeedsKey(kv)
  6137. WORD kv;
  6138. {
  6139. WORD ascnum;
  6140. if((kv>='0')&&(kv<='9'))
  6141. return(kv);
  6142. if((kv>='A')&&(kv<='Z'))
  6143. if (cap_mode)
  6144. return(kv);
  6145. else
  6146. return(kv|0x20);
  6147. switch(kv){
  6148. case VK_RETURN:
  6149. case VK_SPACE:
  6150. case VK_ESCAPE:
  6151. case VK_BACK:
  6152. return(kv);
  6153. case VK_NUMPAD0: // 0x60
  6154. return('0');
  6155. case VK_NUMPAD1: // 0x61
  6156. case VK_NUMPAD2: // 0x62
  6157. case VK_NUMPAD3: // 0x63
  6158. case VK_NUMPAD4: // 0x64
  6159. case VK_NUMPAD5: // 0x65
  6160. case VK_NUMPAD6: // 0x66
  6161. case VK_NUMPAD7: // 0x67
  6162. case VK_NUMPAD8: // 0x68
  6163. case VK_NUMPAD9: // 0x69
  6164. ascnum = kv - VK_NUMPAD1 + '1';
  6165. break;
  6166. // case VK_MULTIPLY: // 0x6A
  6167. // return '*';
  6168. // case VK_ADD : // 0x6B
  6169. // return '+';
  6170. // case VK_SEPARATOR: // 0x6C
  6171. // case VK_SUBTRACT: // 0x6D
  6172. // case VK_DECIMAL : // 0x6E
  6173. // case VK_DIVIDE : // 0x6F
  6174. // ascnum = kv - 0x40;
  6175. // break;
  6176. case VK_DANYINHAO: // 0xc0 // [,] char = // 0x60
  6177. ascnum = 0x60;
  6178. break;
  6179. case VK_JIANHAO : // 0xbd // [-] char = // 0x2d
  6180. ascnum = 0x2d;
  6181. break;
  6182. case VK_DENGHAO : // 0xbb // [=] char = // 0x3d
  6183. ascnum = 0x3d;
  6184. break;
  6185. case VK_ZUOFANG : // 0xdb // "[" char = // 0x5b
  6186. ascnum = 0x5b;
  6187. break;
  6188. case VK_YOUFANG : // 0xdd // "]" char = // 0x5d
  6189. ascnum = 0x5d;
  6190. break;
  6191. case VK_FENHAO : // 0xba // [;] char = // 0x3b
  6192. ascnum = 0x3B;
  6193. break;
  6194. case VK_ZUODAN : // 0xde // ['] char = // 0x27
  6195. ascnum = 0x27;
  6196. break;
  6197. case VK_DOUHAO : // 0xbc // [,] char = // 0x2c
  6198. ascnum = 0x2c;
  6199. break;
  6200. case VK_JUHAO : // 0xbe // [.] char = // 0x2d
  6201. ascnum = '.';
  6202. break;
  6203. case VK_SHANGXIE : // 0xbf // [/] char = // 0x2f
  6204. ascnum = 0x2f;
  6205. break;
  6206. case VK_XIAXIE : // 0xdc // [\] char = // 0x5c
  6207. ascnum = 0x5c;
  6208. break;
  6209. case VK_SHIFT:
  6210. return(2);
  6211. default:
  6212. return(0);
  6213. }
  6214. return(ascnum);
  6215. }
  6216. /**********************************************************************/
  6217. /* NeedsKeyShift() */
  6218. /* Function: Deels with the case of Shift key Down */
  6219. /* Return Value: */
  6220. /* The converted key value. */
  6221. /**********************************************************************/
  6222. WORD
  6223. NeedsKeyShift(kv)
  6224. WORD kv;
  6225. {
  6226. WORD xx=0;
  6227. if((kv>='A')&&(kv<='Z'))
  6228. if (cap_mode)
  6229. return(kv|0x20);
  6230. else
  6231. return(kv);
  6232. switch(kv){
  6233. case '1':
  6234. xx='!';
  6235. break;
  6236. case '2':
  6237. xx='@';
  6238. break;
  6239. case '3':
  6240. xx='#';
  6241. break;
  6242. case '4':
  6243. xx='$';
  6244. break;
  6245. case '5':
  6246. xx='%';
  6247. break;
  6248. case '6':
  6249. xx='^';
  6250. break;
  6251. case '7':
  6252. xx='&';
  6253. break;
  6254. case '8':
  6255. xx='*';
  6256. break;
  6257. case '9':
  6258. xx='(';
  6259. break;
  6260. case '0':
  6261. xx=')';
  6262. break;
  6263. case VK_DANYINHAO: // 0xc0 // [,] char = // 0x60
  6264. xx = '~';
  6265. break;
  6266. case VK_JIANHAO : // 0xbd // [-] char = // 0x2d
  6267. xx = '_';
  6268. break;
  6269. case VK_DENGHAO : // 0xbb // [=] char = // 0x3d
  6270. xx = '+';
  6271. break;
  6272. case VK_ZUOFANG : // 0xdb // "[" char = // 0x5b
  6273. xx = '{';
  6274. break;
  6275. case VK_YOUFANG : // 0xdd // "]" char = // 0x5d
  6276. xx = '}';
  6277. break;
  6278. case VK_FENHAO : // 0xba // [;] char = // 0x3b
  6279. xx = ':';
  6280. break;
  6281. case VK_ZUODAN : // 0xde // ['] char = // 0x27
  6282. xx = '"';
  6283. break;
  6284. case VK_DOUHAO : // 0xbc // [,] char = // 0x2c
  6285. xx = '<';
  6286. break;
  6287. case VK_JUHAO : // 0xbe // [.] char = // 0x2d
  6288. xx = '>';
  6289. break;
  6290. case VK_SHANGXIE : // 0xbf // [/] char = // 0x2f
  6291. xx = '?';
  6292. break;
  6293. case VK_XIAXIE : // 0xdc // [\] char = // 0x5c
  6294. xx = '|';
  6295. break;
  6296. }
  6297. return xx;
  6298. }
  6299. /**********************************************************************/
  6300. /* ProcessKey() */
  6301. /* Function: Check a key if needs for the current processing */
  6302. /* Return Value: */
  6303. /* different state which input key will change IME to */
  6304. /**********************************************************************/
  6305. UINT PASCAL ProcessKey( // this key will cause the IME go to what state
  6306. WORD nCode,
  6307. UINT wParam, //uVirtKey,
  6308. UINT uScanCode,
  6309. LPBYTE lpbKeyState,
  6310. LPINPUTCONTEXT lpIMC,
  6311. LPPRIVCONTEXT lpImcP,
  6312. HIMC hIMC)
  6313. {
  6314. int x;
  6315. WORD w,op;
  6316. if (!lpIMC) {
  6317. return (CST_INVALID);
  6318. }
  6319. if (!lpImcP) {
  6320. return (CST_INVALID);
  6321. }
  6322. if (wParam == VK_MENU) { // no ALT key
  6323. return (CST_INVALID);
  6324. } else if (uScanCode & KF_ALTDOWN) { // no ALT-xx key
  6325. return (CST_INVALID);
  6326. } else if (!lpIMC->fOpen) {
  6327. return (CST_INVALID);
  6328. }
  6329. if (wParam == VK_CAPITAL){
  6330. x=cap_mode;
  6331. // Change to comply with NT 3.51 VK_CAPITAL check style 6
  6332. #ifdef LATER
  6333. if (!GetKeyState(VK_CAPITAL)&1){ //if the Caps Lock status
  6334. #else
  6335. if (GetKeyState(VK_CAPITAL)&1){ //if the Caps Lock status
  6336. #endif //LATER
  6337. DWORD fdwConversion;
  6338. cap_mode=1;
  6339. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  6340. // change to alphanumeric mode
  6341. fdwConversion = (lpIMC->fdwConversion|IME_CMODE_NOCONVERSION)
  6342. & ~(IME_CMODE_NATIVE);
  6343. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  6344. {
  6345. BOOL hbool;
  6346. hbool = ImmGetOpenStatus(hIMC);
  6347. //ImmSetOpenStatus(hIMC, !hbool);
  6348. ImmSetOpenStatus(hIMC, hbool);
  6349. ghIMC=hIMC;
  6350. glpIMCP=lpImcP;
  6351. glpIMC=lpIMC;
  6352. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  6353. cls_prompt();
  6354. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg|MSG_END_COMPOSITION;
  6355. GenerateMessage(ghIMC, glpIMC,glpIMCP);
  6356. V_Flag = 0;
  6357. bx_inpt_on = 0;
  6358. }
  6359. step_mode = 0;
  6360. }
  6361. }else{
  6362. DWORD fdwConversion;
  6363. cap_mode=0;
  6364. if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
  6365. // change to alphanumeric mode
  6366. fdwConversion = (lpIMC->fdwConversion |IME_CMODE_NATIVE)
  6367. & ~(IME_CMODE_NOCONVERSION);
  6368. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  6369. {
  6370. BOOL hbool;
  6371. hbool = ImmGetOpenStatus(hIMC);
  6372. //ImmSetOpenStatus(hIMC, !hbool);
  6373. ImmSetOpenStatus(hIMC, hbool);
  6374. ghIMC=hIMC;
  6375. glpIMCP=lpImcP;
  6376. glpIMC=lpIMC;
  6377. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  6378. cls_prompt();
  6379. lpImcP->fdwImeMsg=lpImcP->fdwImeMsg|MSG_END_COMPOSITION;
  6380. GenerateMessage(ghIMC, glpIMC,glpIMCP);
  6381. }
  6382. }
  6383. }
  6384. return (CST_INVALID);
  6385. }
  6386. if (lpbKeyState[VK_CONTROL]&0x80) // If CTRL pressed
  6387. // if (!((HIBYTE(HIWORD(lParam)))&0x80))
  6388. {
  6389. // DebugShow("In ProcessKey Keystate %X",*lpbKeyState);
  6390. op=0xffff;
  6391. if (nCode==VK_F2){
  6392. return TRUE;
  6393. }
  6394. if (!(lpIMC->fdwConversion &IME_CMODE_NOCONVERSION))
  6395. switch(nCode){
  6396. case '1':
  6397. op=SC_METHOD1;
  6398. break;
  6399. case '2':
  6400. op=SC_METHOD2;
  6401. break;
  6402. case '3':
  6403. op=SC_METHOD3;
  6404. break;
  6405. case '4':
  6406. op=SC_METHOD4;
  6407. break;
  6408. case '5':
  6409. op=SC_METHOD5;
  6410. break;
  6411. case '6':
  6412. op=SC_METHOD6;
  6413. break;
  6414. case '7':
  6415. op=SC_METHOD7;
  6416. break;
  6417. case '8':
  6418. op=SC_METHOD8;
  6419. break;
  6420. case '9':
  6421. op=SC_METHOD9;
  6422. break;
  6423. case '0':
  6424. op=SC_METHOD10;
  6425. break;
  6426. case 0xbd:
  6427. op='-'|0x8000;
  6428. break;
  6429. case 0xbb:
  6430. op='='|0x8000;
  6431. break;
  6432. //case 0xdb:
  6433. // op='['|0x8000;
  6434. // break;
  6435. //case 0xdd:
  6436. // op=']'|0x8000;
  6437. // break;
  6438. default:
  6439. op=0xffff;
  6440. }//switch
  6441. if(op!=0xffff){
  6442. return(TRUE);
  6443. }
  6444. return(CST_INVALID);
  6445. }
  6446. // if((nCode == VK_TAB)&&SdaPromptOpen) return 0;
  6447. if(!step_mode&&!(lpIMC->fdwConversion&IME_CMODE_FULLSHAPE))
  6448. if(nCode == ' ') return(CST_INVALID);
  6449. switch(wParam){
  6450. case VK_END:
  6451. case VK_HOME:
  6452. case VK_PRIOR:
  6453. case VK_NEXT:
  6454. if (step_mode == SELECT)
  6455. return(TRUE);
  6456. // case VK_SHIFT:
  6457. case VK_CONTROL:
  6458. // case VK_PRIOR:
  6459. // case VK_NEXT:
  6460. case VK_TAB:
  6461. // case VK_DELETE:
  6462. case VK_INSERT:
  6463. case VK_F1:
  6464. case VK_F2:
  6465. case VK_F3:
  6466. case VK_F4:
  6467. case VK_F5:
  6468. case VK_F6:
  6469. case VK_F7:
  6470. case VK_F8:
  6471. case VK_F9:
  6472. case VK_F10:
  6473. case VK_F11:
  6474. case VK_F12:
  6475. case VK_F13:
  6476. case VK_F14:
  6477. case VK_F15:
  6478. case VK_F16:
  6479. case VK_F17:
  6480. case VK_F18:
  6481. case VK_F19:
  6482. case VK_F20:
  6483. case VK_F21:
  6484. case VK_F22:
  6485. case VK_F23:
  6486. case VK_F24:
  6487. case VK_NUMLOCK:
  6488. case VK_SCROLL:
  6489. return(CST_INVALID);
  6490. }
  6491. // if ((cap_mode)&&(lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)) //zl
  6492. // return(CST_INVALID);
  6493. switch(nCode){
  6494. case VK_LEFT:
  6495. case VK_UP:
  6496. case VK_RIGHT:
  6497. case VK_DOWN:
  6498. case VK_DELETE:
  6499. if (step_mode!=ONINPUT)
  6500. return(CST_INVALID);
  6501. else
  6502. return(TRUE);
  6503. }
  6504. if((step_mode==START)||(step_mode==RESELECT))
  6505. switch(nCode){
  6506. case VK_SHIFT:
  6507. case VK_RETURN:
  6508. case VK_CANCEL:
  6509. case VK_BACK:
  6510. case VK_ESCAPE:
  6511. return(CST_INVALID);
  6512. }
  6513. if (lpbKeyState[VK_SHIFT]&0x80){
  6514. // If candidate windows is already opened, stop further process.
  6515. // Keep 'shift' for stroke input mode 4/17
  6516. if (sImeG.cbx_flag) {}
  6517. else
  6518. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)return(CST_INVALID);
  6519. if ((w=NeedsKeyShift(nCode))!=0)
  6520. return(TRUE);
  6521. else
  6522. return(CST_INVALID);
  6523. } else{
  6524. w=NeedsKey(nCode);
  6525. if( w != 0)
  6526. return(TRUE);
  6527. }
  6528. return(CST_INVALID);
  6529. }
  6530. /**********************************************************************/
  6531. /* ImeProcessKey() */
  6532. /* Return Value: */
  6533. /* TRUE - successful, FALSE - failure */
  6534. /**********************************************************************/
  6535. BOOL WINAPI ImeProcessKey( // if this key is need by IME?
  6536. HIMC hIMC,
  6537. UINT uVirtKey,
  6538. LPARAM lParam,
  6539. CONST LPBYTE lpbKeyState)
  6540. {
  6541. LPINPUTCONTEXT lpIMC;
  6542. LPPRIVCONTEXT lpImcP;
  6543. BYTE szAscii[4];
  6544. int nChars;
  6545. BOOL fRet;
  6546. // can't compose in NULL hIMC
  6547. if (!hIMC) {
  6548. return (FALSE);
  6549. }
  6550. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  6551. if (!lpIMC) {
  6552. return (FALSE);
  6553. }
  6554. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  6555. if (!lpImcP) {
  6556. ImmUnlockIMC(hIMC);
  6557. return (FALSE);
  6558. }
  6559. nChars = ToAscii(uVirtKey, HIWORD(lParam), lpbKeyState,
  6560. (LPVOID)szAscii, 0);
  6561. if (!nChars) {
  6562. szAscii[0] = 0;
  6563. }
  6564. if (ProcessKey((WORD)uVirtKey, uVirtKey, HIWORD(lParam), lpbKeyState,
  6565. lpIMC, lpImcP, hIMC) == CST_INVALID) {
  6566. fRet = FALSE;
  6567. } else {
  6568. fRet = TRUE;
  6569. }
  6570. ImmUnlockIMCC(lpIMC->hPrivate);
  6571. ImmUnlockIMC(hIMC);
  6572. return (fRet);
  6573. }
  6574. /**********************************************************************/
  6575. /* TranslateFullChar() */
  6576. /* Return Value: */
  6577. /* the number of translated chars */
  6578. /**********************************************************************/
  6579. UINT PASCAL TranslateFullChar( // convert to Double Byte Char
  6580. LPTRANSMSGLIST lpTransBuf,
  6581. WORD wCharCode)
  6582. {
  6583. LPTRANSMSG lpTransMsg;
  6584. // if your IME is possible to generate over ? messages,
  6585. // you need to take care about it
  6586. wCharCode = sImeG.wFullABC[wCharCode - ' '];
  6587. lpTransMsg = lpTransBuf->TransMsg;
  6588. // NT need to modify this!
  6589. lpTransMsg->message = WM_CHAR;
  6590. lpTransMsg->wParam = (DWORD)HIBYTE(wCharCode);
  6591. lpTransMsg->lParam = 1UL;
  6592. lpTransMsg++;
  6593. lpTransMsg->message = WM_CHAR;
  6594. lpTransMsg->wParam = (DWORD)LOBYTE(wCharCode);
  6595. lpTransMsg->lParam = 1UL;
  6596. return (2); // generate two messages
  6597. }
  6598. /**********************************************************************/
  6599. /* TranslateTo () */
  6600. /* Return Value: */
  6601. /* the number of translated chars */
  6602. /**********************************************************************/
  6603. UINT PASCAL TranslateToAscii( // translate the key to WM_CHAR
  6604. // as keyboard driver
  6605. UINT uVirtKey,
  6606. UINT uScanCode,
  6607. LPTRANSMSGLIST lpTransBuf,
  6608. WORD wCharCode)
  6609. {
  6610. LPTRANSMSG lpTransMsg;
  6611. lpTransMsg = lpTransBuf->TransMsg;
  6612. if (wCharCode) { // one char code
  6613. lpTransMsg->message = WM_CHAR;
  6614. lpTransMsg->wParam = wCharCode;
  6615. lpTransMsg->lParam = (uScanCode << 16) | 1UL;
  6616. return (1);
  6617. }
  6618. // no char code case
  6619. return (0);
  6620. }
  6621. /**********************************************************************/
  6622. /* TranslateImeMessage() */
  6623. /* Return Value: */
  6624. /* the number of translated messages */
  6625. /**********************************************************************/
  6626. UINT PASCAL TranslateImeMessage(
  6627. LPTRANSMSGLIST lpTransBuf,
  6628. LPINPUTCONTEXT lpIMC,
  6629. LPPRIVCONTEXT lpImcP)
  6630. {
  6631. UINT uNumMsg;
  6632. UINT i;
  6633. BOOL bLockMsgBuf;
  6634. LPTRANSMSG lpTransMsg;
  6635. uNumMsg = 0;
  6636. bLockMsgBuf = FALSE;
  6637. for (i = 0; i < 2; i++) {
  6638. if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONSIZE) {
  6639. if (!i) {
  6640. uNumMsg++;
  6641. } else {
  6642. lpTransMsg->message = WM_IME_NOTIFY;
  6643. lpTransMsg->wParam = IMN_PRIVATE;
  6644. lpTransMsg->lParam = IMN_PRIVATE_COMPOSITION_SIZE;
  6645. lpTransMsg++;
  6646. }
  6647. }
  6648. if (lpImcP->fdwImeMsg & MSG_START_COMPOSITION) {
  6649. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  6650. if (!i) {
  6651. uNumMsg++;
  6652. } else {
  6653. lpTransMsg->message = WM_IME_STARTCOMPOSITION;
  6654. lpTransMsg->wParam = 0;
  6655. lpTransMsg->lParam = 0;
  6656. lpTransMsg++;
  6657. lpImcP->fdwImeMsg |= MSG_ALREADY_START;
  6658. }
  6659. }
  6660. }
  6661. if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONPOS) {
  6662. if (!i) {
  6663. uNumMsg++;
  6664. } else {
  6665. lpTransMsg->message = WM_IME_NOTIFY;
  6666. lpTransMsg->wParam = IMN_SETCOMPOSITIONWINDOW;
  6667. lpTransMsg->lParam = 0;
  6668. lpTransMsg++;
  6669. }
  6670. }
  6671. if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
  6672. if (!i) {
  6673. uNumMsg++;
  6674. } else {
  6675. lpTransMsg->message = WM_IME_COMPOSITION;
  6676. lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
  6677. lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
  6678. lpTransMsg++;
  6679. }
  6680. }
  6681. if (lpImcP->fdwImeMsg & MSG_GUIDELINE) {
  6682. if (!i) {
  6683. uNumMsg++;
  6684. } else {
  6685. lpTransMsg->message = WM_IME_NOTIFY;
  6686. lpTransMsg->wParam = IMN_GUIDELINE;
  6687. lpTransMsg->lParam = 0;
  6688. lpTransMsg++;
  6689. }
  6690. }
  6691. if (lpImcP->fdwImeMsg & MSG_IMN_PAGEUP) {
  6692. if (!i) {
  6693. uNumMsg++;
  6694. } else {
  6695. lpTransMsg->message = WM_IME_NOTIFY;
  6696. lpTransMsg->wParam = IMN_PRIVATE;
  6697. lpTransMsg->lParam = IMN_PRIVATE_PAGEUP;
  6698. lpTransMsg++;
  6699. }
  6700. }
  6701. if (lpImcP->fdwImeMsg & MSG_OPEN_CANDIDATE) {
  6702. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)) {
  6703. if (!i) {
  6704. uNumMsg++;
  6705. } else {
  6706. lpTransMsg->message = WM_IME_NOTIFY;
  6707. lpTransMsg->wParam = IMN_OPENCANDIDATE;
  6708. lpTransMsg->lParam = 0x0001;
  6709. lpTransMsg++;
  6710. lpImcP->fdwImeMsg |= MSG_ALREADY_OPEN;
  6711. }
  6712. }
  6713. }
  6714. if (lpImcP->fdwImeMsg & MSG_CHANGE_CANDIDATE) {
  6715. if (!i) {
  6716. uNumMsg++;
  6717. } else {
  6718. lpTransMsg->message = WM_IME_NOTIFY;
  6719. lpTransMsg->wParam = IMN_CHANGECANDIDATE;
  6720. lpTransMsg->lParam = 0x0001;
  6721. lpTransMsg++;
  6722. }
  6723. }
  6724. if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_PREDICT) {
  6725. if (!i) {
  6726. uNumMsg++;
  6727. } else {
  6728. lpTransMsg->message = WM_IME_NOTIFY;
  6729. lpTransMsg->wParam = IMN_PRIVATE;
  6730. lpTransMsg->lParam = IMN_PRIVATE_UPDATE_PREDICT;
  6731. lpTransMsg++;
  6732. }
  6733. }
  6734. if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_SOFTKBD) {
  6735. if (!i) {
  6736. uNumMsg++;
  6737. } else {
  6738. lpTransMsg->message = WM_IME_NOTIFY;
  6739. lpTransMsg->wParam = IMN_PRIVATE;
  6740. lpTransMsg->lParam = IMN_PRIVATE_UPDATE_SOFTKBD;
  6741. lpTransMsg++;
  6742. }
  6743. }
  6744. if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  6745. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  6746. if (!i) {
  6747. uNumMsg++;
  6748. } else {
  6749. lpTransMsg->message = WM_IME_NOTIFY;
  6750. lpTransMsg->wParam = IMN_CLOSECANDIDATE;
  6751. lpTransMsg->lParam = 0x0001;
  6752. lpTransMsg++;
  6753. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
  6754. }
  6755. }
  6756. }
  6757. if (lpImcP->fdwImeMsg & MSG_END_COMPOSITION) {
  6758. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  6759. if (!i) {
  6760. uNumMsg++;
  6761. } else {
  6762. lpTransMsg->message = WM_IME_ENDCOMPOSITION;
  6763. lpTransMsg->wParam = 0;
  6764. lpTransMsg->lParam = 0;
  6765. lpTransMsg++;
  6766. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_START);
  6767. }
  6768. }
  6769. }
  6770. if (lpImcP->fdwImeMsg & MSG_IMN_TOGGLE_UI) {
  6771. if (!i) {
  6772. uNumMsg++;
  6773. } else {
  6774. lpTransMsg->message = WM_IME_NOTIFY;
  6775. lpTransMsg->wParam = IMN_PRIVATE;
  6776. lpTransMsg->lParam = IMN_PRIVATE_TOGGLE_UI;
  6777. lpTransMsg++;
  6778. }
  6779. }
  6780. if (!i) {
  6781. HIMCC hMem;
  6782. if (!uNumMsg) {
  6783. return (uNumMsg);
  6784. }
  6785. if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
  6786. UINT uNumMsgLimit;
  6787. // ++ for the start position of buffer to strore the messages
  6788. uNumMsgLimit = lpTransBuf->uMsgCount;
  6789. if (uNumMsg <= uNumMsgLimit) {
  6790. lpTransMsg = lpTransBuf->TransMsg;
  6791. continue;
  6792. }
  6793. }
  6794. // we need to use message buffer
  6795. if (!lpIMC->hMsgBuf) {
  6796. lpIMC->hMsgBuf = ImmCreateIMCC(uNumMsg * sizeof(TRANSMSG));
  6797. lpIMC->dwNumMsgBuf = 0;
  6798. } else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf,
  6799. (lpIMC->dwNumMsgBuf + uNumMsg) * sizeof(TRANSMSG))) {
  6800. if (hMem != lpIMC->hMsgBuf) {
  6801. ImmDestroyIMCC(lpIMC->hMsgBuf);
  6802. lpIMC->hMsgBuf = hMem;
  6803. }
  6804. } else {
  6805. return (0);
  6806. }
  6807. lpTransMsg = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
  6808. if (!lpTransMsg) {
  6809. return (0);
  6810. }
  6811. lpTransMsg += lpIMC->dwNumMsgBuf;
  6812. bLockMsgBuf = TRUE;
  6813. } else {
  6814. if (bLockMsgBuf) {
  6815. ImmUnlockIMCC(lpIMC->hMsgBuf);
  6816. }
  6817. }
  6818. }
  6819. return (uNumMsg);
  6820. }
  6821. /**********************************************************************/
  6822. /* TransAbcMsg2() */
  6823. /* Return Value: */
  6824. /* the number of translated messages */
  6825. /**********************************************************************/
  6826. UINT PASCAL TransAbcMsg2(
  6827. LPTRANSMSG lpTransMsg,
  6828. LPPRIVCONTEXT lpImcP)
  6829. {
  6830. UINT uNumMsg;
  6831. uNumMsg = 0;
  6832. if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
  6833. lpTransMsg->message = WM_IME_COMPOSITION;
  6834. lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
  6835. lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
  6836. lpTransMsg++;
  6837. uNumMsg++;
  6838. }
  6839. if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  6840. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  6841. lpTransMsg->message = WM_IME_NOTIFY;
  6842. lpTransMsg->wParam = IMN_CLOSECANDIDATE;
  6843. lpTransMsg->lParam = 0x0001;
  6844. lpTransMsg++;
  6845. uNumMsg++;
  6846. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
  6847. }
  6848. }
  6849. lpTransMsg->message = WM_IME_ENDCOMPOSITION;
  6850. lpTransMsg->wParam = 0;
  6851. lpTransMsg->lParam = 0;
  6852. uNumMsg++;
  6853. lpImcP->fdwImeMsg = 0;
  6854. return (uNumMsg);
  6855. }
  6856. /**********************************************************************/
  6857. /* TransAbcMsg() */
  6858. /* Return Value: */
  6859. /* the number of translated messages */
  6860. /**********************************************************************/
  6861. UINT PASCAL TransAbcMsg(
  6862. LPTRANSMSGLIST lpTransBuf,
  6863. LPPRIVCONTEXT lpImcP,
  6864. LPINPUTCONTEXT lpIMC,
  6865. UINT uVirtKey,
  6866. UINT uScanCode,
  6867. WORD wCharCode)
  6868. {
  6869. LPCOMPOSITIONSTRING lpCompStr ;
  6870. UINT uNumMsg;
  6871. int i;
  6872. int MsgCount;
  6873. LPSTR pp;
  6874. LPTRANSMSG lpTransMsg;
  6875. lpTransMsg = lpTransBuf->TransMsg;
  6876. uNumMsg = 0;
  6877. if (TypeOfOutMsg&ABC_OUT_ONE){
  6878. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,wCharCode);
  6879. lpTransMsg++;
  6880. return (uNumMsg);
  6881. }else{
  6882. if (TypeOfOutMsg&ABC_OUT_ASCII){
  6883. lpTransMsg = lpTransBuf->TransMsg;
  6884. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  6885. if (!lpCompStr)
  6886. uNumMsg = 0;
  6887. else{
  6888. MsgCount = lpCompStr->dwResultStrLen;
  6889. pp = (LPSTR)lpCompStr + lpCompStr->dwResultStrOffset;
  6890. for (i = 0; i < MsgCount; i++){
  6891. if((BYTE)pp[i]<0x80){
  6892. WORD x;
  6893. x =(WORD)VkKeyScan((TCHAR)(BYTE)pp[i]);
  6894. lpTransMsg->message = WM_KEYUP;
  6895. lpTransMsg->wParam = (DWORD)(BYTE)x;//(DWORD)(BYTE)pp[i];
  6896. lpTransMsg->lParam = 1UL;
  6897. lpTransMsg++;
  6898. uNumMsg++;
  6899. }else{
  6900. lpTransMsg->message = WM_CHAR;
  6901. lpTransMsg->wParam = (DWORD)(BYTE)pp[i];
  6902. lpTransMsg->lParam = 1UL;
  6903. lpTransMsg++;
  6904. uNumMsg++;
  6905. }
  6906. }
  6907. ImmUnlockIMCC(lpIMC->hCompStr);
  6908. }
  6909. }else{
  6910. lpTransMsg = lpTransBuf->TransMsg;
  6911. }
  6912. }
  6913. if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
  6914. lpTransMsg->message = WM_IME_COMPOSITION;
  6915. lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
  6916. lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
  6917. lpTransMsg++;
  6918. uNumMsg++;
  6919. }
  6920. if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  6921. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  6922. lpTransMsg->message = WM_IME_NOTIFY;
  6923. lpTransMsg->wParam = IMN_CLOSECANDIDATE;
  6924. lpTransMsg->lParam = 0x0001;
  6925. lpTransMsg++;
  6926. uNumMsg++;
  6927. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
  6928. }
  6929. }
  6930. lpTransMsg->message = WM_IME_ENDCOMPOSITION;
  6931. lpTransMsg->wParam = 0;
  6932. lpTransMsg->lParam = 0;
  6933. lpTransMsg++;
  6934. uNumMsg++;
  6935. lpImcP->fdwImeMsg = 0;
  6936. TypeOfOutMsg = TypeOfOutMsg | COMP_NEEDS_END;
  6937. if (wait_flag||waitzl_flag){ //waitzl 2
  6938. lpTransMsg->message = WM_IME_NOTIFY;
  6939. lpTransMsg->wParam = IMN_SETCOMPOSITIONWINDOW;
  6940. lpTransMsg->lParam = 0;
  6941. lpTransMsg++;
  6942. uNumMsg++;
  6943. lpTransMsg->message = WM_IME_STARTCOMPOSITION;
  6944. lpTransMsg->wParam = 0;
  6945. lpTransMsg->lParam = 0x6699;
  6946. lpTransMsg++;
  6947. uNumMsg++;
  6948. lpImcP->fdwImeMsg |= MSG_ALREADY_START;
  6949. }
  6950. return (uNumMsg);
  6951. }
  6952. /**********************************************************************/
  6953. /* KeyFilter() */
  6954. /* Return Value: */
  6955. /* the number of translated message */
  6956. /**********************************************************************/
  6957. WORD KeyFilter(nCode,wParam,lParam,lpImcP , lpbKeyState )
  6958. WORD nCode;
  6959. WORD wParam;
  6960. DWORD lParam;
  6961. LPPRIVCONTEXT lpImcP;
  6962. LPBYTE lpbKeyState;
  6963. {
  6964. int x;
  6965. WORD w,op;
  6966. if (lpbKeyState[VK_CONTROL]&0x80) // If CTRL pressed
  6967. {
  6968. op=0xffff;
  6969. if (nCode==VK_F2){
  6970. //zst futur PostMessage(hMenuWnd,WM_COMMAND,SC_METHODA,0);
  6971. return 0;
  6972. }
  6973. switch(nCode){
  6974. case '1':
  6975. op=SC_METHOD1;
  6976. break;
  6977. case '2':
  6978. op=SC_METHOD2;
  6979. break;
  6980. case '3':
  6981. op=SC_METHOD3;
  6982. break;
  6983. case '4':
  6984. op=SC_METHOD4;
  6985. break;
  6986. case '5':
  6987. op=SC_METHOD5;
  6988. break;
  6989. case '6':
  6990. op=SC_METHOD6;
  6991. break;
  6992. case '7':
  6993. op=SC_METHOD7;
  6994. break;
  6995. case '8':
  6996. op=SC_METHOD8;
  6997. break;
  6998. case '9':
  6999. op=SC_METHOD9;
  7000. break;
  7001. case '0':
  7002. op=SC_METHOD10;
  7003. break;
  7004. case 0xbd:
  7005. op='-'|0x8000;
  7006. break;
  7007. case 0xbb:
  7008. op='='|0x8000;
  7009. break;
  7010. //case 0xdb:
  7011. // op='['|0x8000;
  7012. // break;
  7013. //case 0xdd:
  7014. // op=']'|0x8000;
  7015. // break;
  7016. default:
  7017. op=0xffff;
  7018. }//switch
  7019. if(op!=0xffff){
  7020. if(op&(WORD)0x8000)
  7021. return op;
  7022. else{
  7023. //zst future PostMessage(hMenuWnd,WM_COMMAND,op,0);
  7024. //zst future EventFrom = 1;
  7025. }
  7026. return(0);
  7027. }
  7028. return(0);
  7029. }
  7030. switch(nCode){
  7031. case VK_PRIOR:
  7032. case VK_NEXT:
  7033. case VK_HOME:
  7034. case VK_END:
  7035. if(step_mode == SELECT)
  7036. return(nCode*0x100);
  7037. else return(0);
  7038. case VK_LEFT:
  7039. case VK_UP:
  7040. case VK_RIGHT:
  7041. case VK_DOWN:
  7042. case VK_DELETE:
  7043. if (step_mode!=ONINPUT)
  7044. return(0);
  7045. else
  7046. return(nCode+0x100);
  7047. }
  7048. if (lpbKeyState/*GetKeyState*/[VK_SHIFT]&0x80){
  7049. if ((w=NeedsKeyShift(nCode))!=0)
  7050. return (w);
  7051. else
  7052. return (0);
  7053. } else{
  7054. if((w=NeedsKey(nCode)) != 0)
  7055. return (w);
  7056. }
  7057. return(0);
  7058. }
  7059. /**********************************************************************/
  7060. /* TranslateSymbolChar() */
  7061. /* Return Value: */
  7062. /* the number of translated chars */
  7063. /**********************************************************************/
  7064. UINT PASCAL TranslateSymbolChar(
  7065. LPTRANSMSGLIST lpTransBuf,
  7066. WORD wSymbolCharCode)
  7067. {
  7068. UINT uRet;
  7069. LPTRANSMSG lpTransMsg;
  7070. uRet = 0;
  7071. lpTransMsg = lpTransBuf->TransMsg;
  7072. // NT need to modify this!
  7073. lpTransMsg->message = WM_CHAR;
  7074. lpTransMsg->wParam = (DWORD)HIBYTE(wSymbolCharCode);
  7075. lpTransMsg->lParam = 1UL;
  7076. lpTransMsg++;
  7077. uRet++;
  7078. lpTransMsg->message = WM_CHAR;
  7079. lpTransMsg->wParam = (DWORD)LOBYTE(wSymbolCharCode);
  7080. lpTransMsg->lParam = 1UL;
  7081. lpTransMsg++;
  7082. uRet++;
  7083. return (uRet); // generate two messages
  7084. }
  7085. /**********************************************************************/
  7086. /* ImeToAsciiEx() */
  7087. /* Return Value: */
  7088. /* the number of translated message */
  7089. /**********************************************************************/
  7090. UINT WINAPI ImeToAsciiEx(
  7091. UINT uVirtKey,
  7092. UINT uScanCode,
  7093. CONST LPBYTE lpbKeyState,
  7094. LPTRANSMSGLIST lpTransBuf,
  7095. UINT fuState,
  7096. HIMC hIMC)
  7097. {
  7098. WORD wCharCode;
  7099. WORD wCharZl;
  7100. LPINPUTCONTEXT lpIMC;
  7101. LPCOMPOSITIONSTRING lpCompStr;
  7102. LPPRIVCONTEXT lpImcP;
  7103. UINT uNumMsg;
  7104. int iRet;
  7105. wCharCode = HIBYTE(uVirtKey);
  7106. uVirtKey = LOBYTE(uVirtKey);
  7107. if (!hIMC) {
  7108. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  7109. wCharCode);
  7110. return (uNumMsg);
  7111. }
  7112. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  7113. if (!lpIMC) {
  7114. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  7115. wCharCode);
  7116. return (uNumMsg);
  7117. }
  7118. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  7119. if (!lpImcP) {
  7120. ImmUnlockIMC(hIMC);
  7121. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  7122. wCharCode);
  7123. return (uNumMsg);
  7124. }
  7125. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|
  7126. MSG_ALREADY_START) | MSG_IN_IMETOASCIIEX;
  7127. // deal with softkbd
  7128. if ((lpIMC->fdwConversion & IME_CMODE_SOFTKBD)
  7129. && (lpImeL->dwSKWant != 0) &&
  7130. (wCharCode >= ' ' && wCharCode <= '~')) {
  7131. WORD wSymbolCharCode;
  7132. WORD CHIByte, CLOByte;
  7133. int SKDataIndex;
  7134. // Mapping VK
  7135. if(uVirtKey == 0x20) {
  7136. SKDataIndex = 0;
  7137. } else if(uVirtKey >= 0x30 && uVirtKey <= 0x39) {
  7138. SKDataIndex = uVirtKey - 0x30 + 1;
  7139. } else if (uVirtKey >= 0x41 && uVirtKey <= 0x5a) {
  7140. SKDataIndex = uVirtKey - 0x41 + 0x0b;
  7141. } else if (uVirtKey >= 0xba && uVirtKey <= 0xbf) {
  7142. SKDataIndex = uVirtKey - 0xba + 0x25;
  7143. } else if (uVirtKey >= 0xdb && uVirtKey <= 0xde) {
  7144. SKDataIndex = uVirtKey - 0xdb + 0x2c;
  7145. } else if (uVirtKey == 0xc0) {
  7146. SKDataIndex = 0x2b;
  7147. } else {
  7148. SKDataIndex = 0;
  7149. }
  7150. //
  7151. if (lpbKeyState[VK_SHIFT] & 0x80) {
  7152. CHIByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
  7153. CLOByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
  7154. } else {
  7155. CHIByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
  7156. CLOByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
  7157. }
  7158. wSymbolCharCode = (CHIByte << 8) | CLOByte;
  7159. if(wSymbolCharCode == 0x2020) {
  7160. MessageBeep((UINT) -1);
  7161. uNumMsg = 0;
  7162. } else {
  7163. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode);
  7164. }
  7165. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  7166. ImmUnlockIMCC(lpIMC->hPrivate);
  7167. ImmUnlockIMC(hIMC);
  7168. return (uNumMsg);
  7169. }
  7170. sImeG.KeepKey = 0;
  7171. if(wCharZl=KeyFilter(/*wCharCode*/uVirtKey,uVirtKey,uScanCode,lpImcP , lpbKeyState )){
  7172. if(wCharZl<0x100)
  7173. wCharZl = wCharCode;
  7174. CharProc(wCharZl,/*wCharCode*/uVirtKey,uScanCode,hIMC,lpIMC,lpImcP);
  7175. }
  7176. if(TypeOfOutMsg){
  7177. uNumMsg = TransAbcMsg(lpTransBuf, lpImcP,lpIMC,uVirtKey,uScanCode, wCharCode);
  7178. }else {
  7179. uNumMsg = TranslateImeMessage(lpTransBuf, lpIMC, lpImcP);
  7180. }
  7181. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
  7182. ImmUnlockIMCC(lpIMC->hPrivate);
  7183. ImmUnlockIMC(hIMC);
  7184. return (uNumMsg);
  7185. }
  7186. /**********************************************************************/
  7187. /* CancelCompCandWindow() */
  7188. /**********************************************************************/
  7189. void PASCAL CancelCompCandWindow( // destroy composition window
  7190. HWND hUIWnd)
  7191. {
  7192. HGLOBAL hUIPrivate;
  7193. LPUIPRIV lpUIPrivate;
  7194. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  7195. if (!hUIPrivate) return ;
  7196. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  7197. if (!lpUIPrivate) return;
  7198. if (lpUIPrivate->hCompWnd) {
  7199. // DestroyWindow(lpUIPrivate->hCompWnd);
  7200. ShowWindow(lpUIPrivate->hCompWnd,SW_HIDE);
  7201. }
  7202. if (lpUIPrivate->hCandWnd) {
  7203. DestroyWindow(lpUIPrivate->hCandWnd);
  7204. // ShowWindow(lpUIPrivate->hCandWnd,SW_HIDE);
  7205. }
  7206. GlobalUnlock(hUIPrivate);
  7207. // SendMessage(hUIWnd,WM_IME_ENDCOMPOSITION,0,0L);
  7208. return;
  7209. }
  7210. int DoPropertySheet(HWND hwndOwner,HWND hWnd)
  7211. {
  7212. PROPSHEETPAGE psp[3];
  7213. PROPSHEETHEADER psh;
  7214. BYTE KbType;
  7215. BYTE cp_ajust_flag;
  7216. BYTE auto_mode ;
  7217. BYTE cbx_flag;
  7218. BYTE tune_flag;
  7219. BYTE auto_cvt_flag;
  7220. BYTE SdOpenFlag ;
  7221. WORD wImeStyle ;
  7222. HIMC hIMC;
  7223. HWND hUIWnd;
  7224. if (sImeG.Prop) return 0;
  7225. //Fill out the PROPSHEETPAGE data structure for the Background Color
  7226. //sheet
  7227. sImeG.Prop = 1;
  7228. if(hWnd){
  7229. hUIWnd = GetWindow(hWnd,GW_OWNER);
  7230. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  7231. }else
  7232. hIMC = 0;
  7233. wImeStyle = lpImeL->wImeStyle;
  7234. KbType = sImeG.KbType;
  7235. cp_ajust_flag=sImeG.cp_ajust_flag;
  7236. auto_mode=sImeG.auto_mode;
  7237. cbx_flag=sImeG.cbx_flag;
  7238. tune_flag=sImeG.tune_flag;
  7239. auto_cvt_flag=sImeG.auto_cvt_flag;
  7240. SdOpenFlag=sImeG.SdOpenFlag;
  7241. sImeG.unchanged = 0;
  7242. if(hIMC)
  7243. ImmSetOpenStatus(hIMC,FALSE);
  7244. if(hIMC)
  7245. {
  7246. LPINPUTCONTEXT lpIMC;
  7247. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  7248. if (!lpIMC) { // Oh! Oh!
  7249. return (0L);
  7250. }
  7251. DialogBox(hInst,(LPCTSTR)ImeStyleDlg, lpIMC->hWnd, ImeStyleProc);
  7252. ImmUnlockIMC(hIMC);
  7253. }else{
  7254. DialogBox(hInst,(LPCTSTR)ImeStyleDlg, hwndOwner, ImeStyleProc);
  7255. }
  7256. if(hIMC)
  7257. ImmSetOpenStatus(hIMC,TRUE);
  7258. if (sImeG.unchanged){
  7259. lpImeL->wImeStyle = wImeStyle ;
  7260. sImeG.KbType = KbType;
  7261. sImeG.cp_ajust_flag = cp_ajust_flag;
  7262. sImeG.auto_mode = auto_mode;
  7263. sImeG.cbx_flag = cbx_flag;
  7264. sImeG.tune_flag = tune_flag;
  7265. sImeG.auto_cvt_flag = auto_cvt_flag;
  7266. sImeG.SdOpenFlag = SdOpenFlag;
  7267. }else{
  7268. ChangeUserSetting();
  7269. }
  7270. sImeG.Prop = 0;
  7271. return (!sImeG.unchanged);
  7272. }
  7273. void WINAPI CenterWindow(HWND hWnd)
  7274. {
  7275. RECT WorkArea;
  7276. RECT rcRect;
  7277. int x,y,mx,my;
  7278. SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
  7279. GetWindowRect(hWnd,&rcRect);
  7280. mx = WorkArea.left + (WorkArea.right - WorkArea.left)/2;
  7281. my = WorkArea.top + (WorkArea.bottom - WorkArea.top)/2;
  7282. x = mx - (rcRect.right - rcRect.left)/2;
  7283. y = my - (rcRect.bottom - rcRect.top)/2;
  7284. SetWindowPos (hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  7285. return;
  7286. }
  7287. INT_PTR CALLBACK ImeStyleProc(HWND hdlg,
  7288. UINT uMessage,
  7289. WPARAM wparam,
  7290. LPARAM lparam)
  7291. {
  7292. switch (uMessage) {
  7293. case WM_INITDIALOG: /* message: initialize dialog box */
  7294. hCrtDlg = hdlg;
  7295. CenterWindow(hdlg);
  7296. if (lpImeL->wImeStyle == IME_APRS_FIX)
  7297. SendMessage(GetDlgItem(hdlg, IDC_FIX),
  7298. BM_SETCHECK,
  7299. TRUE,
  7300. 0L);
  7301. else
  7302. SendMessage(GetDlgItem(hdlg, IDC_NEAR),
  7303. BM_SETCHECK,
  7304. TRUE,
  7305. 0L);
  7306. if(sImeG.auto_mode)
  7307. SendMessage(GetDlgItem(hdlg, IDC_CP),
  7308. BM_SETCHECK,
  7309. TRUE,
  7310. 0L);
  7311. if(sImeG.cbx_flag)
  7312. SendMessage(GetDlgItem(hdlg, IDC_CBX),
  7313. BM_SETCHECK,
  7314. TRUE,
  7315. 0L);
  7316. return (TRUE);
  7317. case WM_PAINT:
  7318. {
  7319. RECT Rect;
  7320. HDC hDC;
  7321. PAINTSTRUCT ps;
  7322. GetClientRect(hdlg, &Rect); //get the whole window area
  7323. InvalidateRect(hdlg, &Rect, 1);
  7324. hDC=BeginPaint(hdlg, &ps);
  7325. Rect.left+=10;//5;
  7326. Rect.top+=8;//5;
  7327. Rect.right-=10;//5;
  7328. Rect.bottom-=52;//5;
  7329. DrawEdge(hDC, &Rect, EDGE_RAISED,/*EDGE_SUNKEN,*/ BF_RECT);
  7330. EndPaint(hdlg, &ps);
  7331. break;
  7332. }
  7333. case WM_CLOSE:
  7334. EndDialog(hdlg, FALSE);
  7335. return (TRUE);
  7336. case WM_COMMAND:
  7337. switch (wparam){
  7338. case IDC_BUTTON_OK:
  7339. EndDialog(hdlg, TRUE);
  7340. return (TRUE);
  7341. case IDC_BUTTON_ESC:
  7342. sImeG.unchanged = 1;
  7343. EndDialog(hdlg, TRUE);
  7344. return (TRUE);
  7345. case IDC_NEAR:
  7346. lpImeL->wImeStyle = IME_APRS_AUTO;
  7347. break;
  7348. case IDC_FIX:
  7349. lpImeL->wImeStyle = IME_APRS_FIX;
  7350. break;
  7351. case IDC_CP:
  7352. if (sImeG.auto_mode ==0){
  7353. sImeG.auto_mode = 1;
  7354. break;
  7355. } else
  7356. sImeG.auto_mode = 0;
  7357. break;
  7358. case IDC_CBX:
  7359. if (sImeG.cbx_flag==0)
  7360. sImeG.cbx_flag = 1;
  7361. else
  7362. sImeG.cbx_flag = 0;
  7363. break;
  7364. }
  7365. }
  7366. return (FALSE); /* Didn't process a message */
  7367. }
  7368. INT_PTR CALLBACK KbSelectProc(HWND hdlg,
  7369. UINT uMessage,
  7370. WPARAM wparam,
  7371. LPARAM lparam)
  7372. {
  7373. HWND hWndApp;
  7374. WORD wID;
  7375. LPNMHDR lpnmhdr;
  7376. return FALSE;
  7377. }
  7378. INT_PTR CALLBACK CvtCtrlProc(HWND hdlg,
  7379. UINT uMessage,
  7380. WPARAM wparam,
  7381. LPARAM lparam)
  7382. {
  7383. return FALSE;
  7384. }
  7385. /**********************************************************************/
  7386. /* ContextMenu() */
  7387. /**********************************************************************/
  7388. void PASCAL ContextMenu(
  7389. HWND hStatusWnd,
  7390. int x,
  7391. int y)
  7392. {
  7393. HWND hUIWnd;
  7394. HGLOBAL hUIPrivate;
  7395. LPUIPRIV lpUIPrivate;
  7396. HIMC hIMC;
  7397. LPINPUTCONTEXT lpIMC;
  7398. LPPRIVCONTEXT lpImcP;
  7399. HMENU hMenu, hCMenu;
  7400. POINT ptCursor; //zl #2
  7401. ptCursor.x = x;
  7402. ptCursor.y = y;
  7403. // DebugShow2("ptCursor.x", x, "ptCursor.y" ,y);
  7404. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  7405. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  7406. if (!hIMC) {
  7407. return;
  7408. }
  7409. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  7410. if (!lpIMC) {
  7411. return;
  7412. }
  7413. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  7414. if (!hUIPrivate) {
  7415. goto ContextMenuUnlockIMC;
  7416. }
  7417. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  7418. if (!lpUIPrivate) {
  7419. goto ContextMenuUnlockIMC;
  7420. }
  7421. if (!lpUIPrivate->hCMenuWnd) {
  7422. // this is important to assign owner window, otherwise the focus
  7423. // will be gone
  7424. // When UI terminate, it need to destroy this window
  7425. lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  7426. "Abc95Menu",
  7427. /*lpImeL->szCMenuClassName,*/ "Context Menu",
  7428. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  7429. lpIMC->hWnd, (HMENU)NULL, lpImeL->hInst, NULL);
  7430. if (!lpUIPrivate->hCMenuWnd) {
  7431. goto ContextMenuUnlockIMC;
  7432. }
  7433. }
  7434. ScreenToClient(hStatusWnd , &ptCursor);
  7435. if (PtInRect(&sImeG.rcSKText, ptCursor)){
  7436. hMenu = LoadMenu(hInst,"SKMenu");
  7437. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  7438. if(lpImcP){
  7439. CheckMenuItem(hMenu,lpImeL->dwSKWant+IDM_SKL1,MF_CHECKED);
  7440. ImmUnlockIMCC(lpIMC->hPrivate);
  7441. }
  7442. }
  7443. else hMenu = LoadMenu(hInst,"MMenu");
  7444. hCMenu = GetSubMenu(hMenu, 0);
  7445. if ( lpImeL->fWinLogon == TRUE )
  7446. {
  7447. // In Logon Mode, we don't want to show help and configuration dialog
  7448. EnableMenuItem(hCMenu, 107, MF_BYCOMMAND | MF_GRAYED );
  7449. EnableMenuItem(hCMenu, 110, MF_BYCOMMAND | MF_GRAYED );
  7450. EnableMenuItem(hCMenu, 109, MF_BYCOMMAND | MF_GRAYED );
  7451. }
  7452. SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
  7453. SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
  7454. /*
  7455. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  7456. // EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  7457. // EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
  7458. } else if (lpIMC->fOpen) {
  7459. // can not go into symbol mode
  7460. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  7461. // EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  7462. } else {
  7463. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  7464. // CheckMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_CHECKED);
  7465. }
  7466. }
  7467. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  7468. // CheckMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_CHECKED);
  7469. }
  7470. } else {
  7471. // EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  7472. // EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
  7473. }
  7474. */
  7475. TrackPopupMenu(hCMenu, TPM_LEFTBUTTON,
  7476. lpIMC->ptStatusWndPos.x ,
  7477. lpIMC->ptStatusWndPos.y ,
  7478. 0,
  7479. lpUIPrivate->hCMenuWnd, NULL);
  7480. hMenu = (HMENU)GetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU);
  7481. if (hMenu) {
  7482. SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  7483. DestroyMenu(hMenu);
  7484. }
  7485. GlobalUnlock(hUIPrivate);
  7486. ContextMenuUnlockIMC:
  7487. ImmUnlockIMC(hIMC);
  7488. return;
  7489. }
  7490. /**********************************************************************/
  7491. /* StatusSetCursor() */
  7492. /**********************************************************************/
  7493. void PASCAL StatusSetCursor(
  7494. HWND hStatusWnd,
  7495. LPARAM lParam)
  7496. {
  7497. POINT ptCursor, ptSavCursor;
  7498. RECT rcWnd;
  7499. RECT rcSt;
  7500. rcSt.left = sImeG.rcStatusText.left+3;
  7501. rcSt.top = sImeG.rcStatusText.top + 3;
  7502. rcSt.right = sImeG.rcStatusText.right-3;
  7503. rcSt.bottom = sImeG.rcStatusText.bottom;
  7504. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  7505. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  7506. return;
  7507. }
  7508. GetCursorPos(&ptCursor);
  7509. ptSavCursor = ptCursor;
  7510. ScreenToClient(hStatusWnd, &ptCursor);
  7511. if (PtInRect(&rcSt, ptCursor)) {
  7512. SetCursor(LoadCursor(hInst,szHandCursor ));
  7513. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  7514. SetStatus(hStatusWnd, &ptCursor);
  7515. } else if (HIWORD(lParam) == WM_RBUTTONUP) {
  7516. static BOOL fImeConfigure = FALSE;
  7517. // prevent recursive
  7518. if (fImeConfigure) {
  7519. // configuration already bring up
  7520. return;
  7521. }
  7522. fImeConfigure = TRUE;
  7523. // PopStMenu(hStatusWnd, lpIMC->ptStatusWndPos.x + sImeG.xStatusWi,
  7524. // lpIMC->ptStatusWndPos.y);
  7525. ContextMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  7526. fImeConfigure = FALSE;
  7527. } else {
  7528. }
  7529. return;
  7530. } else {
  7531. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  7532. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  7533. // start drag
  7534. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  7535. } else {
  7536. return;
  7537. }
  7538. }
  7539. SetCapture(hStatusWnd);
  7540. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  7541. MAKELONG(ptSavCursor.x, ptSavCursor.y));
  7542. GetWindowRect(hStatusWnd, &rcWnd);
  7543. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  7544. MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
  7545. DrawDragBorder(hStatusWnd, MAKELONG(ptSavCursor.x, ptSavCursor.y),
  7546. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  7547. return;
  7548. }
  7549. /**********************************************************************/
  7550. /* StatusWndProc() */
  7551. /**********************************************************************/
  7552. //#if defined(UNIIME)
  7553. //LRESULT CALLBACK UniStatusWndProc(
  7554. // LPINSTDATAL lpInstL,
  7555. // LPIMEL lpImeL,
  7556. //#else
  7557. LRESULT CALLBACK StatusWndProc(
  7558. //#endif
  7559. HWND hStatusWnd,
  7560. UINT uMsg,
  7561. WPARAM wParam,
  7562. LPARAM lParam)
  7563. {
  7564. switch (uMsg) {
  7565. case WM_DESTROY:
  7566. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  7567. LONG lTmpCursor, lTmpOffset;
  7568. POINT ptCursor;
  7569. HWND hUIWnd;
  7570. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  7571. // calculate the org by the offset
  7572. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  7573. DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  7574. ReleaseCapture();
  7575. }
  7576. DestroyStatusWindow(hStatusWnd);
  7577. break;
  7578. case WM_SETCURSOR:
  7579. StatusSetCursor(
  7580. hStatusWnd, lParam);
  7581. break;
  7582. case WM_MOUSEMOVE:
  7583. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  7584. POINT ptCursor;
  7585. DrawDragBorder(hStatusWnd,
  7586. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  7587. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  7588. GetCursorPos(&ptCursor);
  7589. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  7590. MAKELONG(ptCursor.x, ptCursor.y));
  7591. DrawDragBorder(hStatusWnd, MAKELONG(ptCursor.x, ptCursor.y),
  7592. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  7593. } else {
  7594. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  7595. }
  7596. break;
  7597. case WM_LBUTTONUP:
  7598. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  7599. LONG lTmpCursor, lTmpOffset;
  7600. POINT ptCursor;
  7601. HWND hUIWnd;
  7602. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  7603. // calculate the org by the offset
  7604. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  7605. DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  7606. ptCursor.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
  7607. ptCursor.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;
  7608. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  7609. ReleaseCapture();
  7610. AdjustStatusBoundary(&ptCursor);
  7611. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  7612. /* SendMessage(GetWindow(hStatusWnd, GW_OWNER), WM_IME_CONTROL,
  7613. IMC_SETSTATUSWINDOWPOS, NULL); */
  7614. ImmSetStatusWindowPos((HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC),
  7615. &ptCursor);
  7616. if (lpImeL->wImeStyle == IME_APRS_FIX){ //003
  7617. ReInitIme(hStatusWnd,lpImeL->wImeStyle); //#@3
  7618. MoveCompCand(GetWindow(hStatusWnd, GW_OWNER));
  7619. }
  7620. } else {
  7621. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  7622. }
  7623. break;
  7624. case WM_IME_NOTIFY:
  7625. if (wParam == IMN_SETSTATUSWINDOWPOS) {
  7626. SetStatusWindowPos(hStatusWnd);
  7627. }
  7628. break;
  7629. case WM_PAINT:
  7630. {
  7631. HDC hDC;
  7632. PAINTSTRUCT ps;
  7633. hDC = BeginPaint(hStatusWnd, &ps);
  7634. PaintStatusWindow(
  7635. hDC,hStatusWnd); //zl
  7636. EndPaint(hStatusWnd, &ps);
  7637. }
  7638. break;
  7639. case WM_MOUSEACTIVATE:
  7640. return (MA_NOACTIVATE);
  7641. default:
  7642. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  7643. }
  7644. return (0L);
  7645. }
  7646. /**********************************************************************/
  7647. /* DrawDragBorder() */
  7648. /**********************************************************************/
  7649. void PASCAL DrawDragBorder(
  7650. HWND hWnd, // window of IME is dragged
  7651. LONG lCursorPos, // the cursor position
  7652. LONG lCursorOffset) // the offset form cursor to window org
  7653. {
  7654. HDC hDC;
  7655. int cxBorder, cyBorder;
  7656. int x, y;
  7657. RECT rcWnd;
  7658. cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
  7659. cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
  7660. // get cursor position
  7661. x = (*(LPPOINTS)&lCursorPos).x;
  7662. y = (*(LPPOINTS)&lCursorPos).y;
  7663. // calculate the org by the offset
  7664. x -= (*(LPPOINTS)&lCursorOffset).x;
  7665. y -= (*(LPPOINTS)&lCursorOffset).y;
  7666. // check for the min boundary of the display
  7667. if (x < sImeG.rcWorkArea.left) {
  7668. x = sImeG.rcWorkArea.left;
  7669. }
  7670. if (y < sImeG.rcWorkArea.top) {
  7671. y = sImeG.rcWorkArea.top;
  7672. }
  7673. // check for the max boundary of the display
  7674. GetWindowRect(hWnd, &rcWnd);
  7675. if (x + rcWnd.right - rcWnd.left > sImeG.rcWorkArea.right) {
  7676. x = sImeG.rcWorkArea.right - (rcWnd.right - rcWnd.left);
  7677. }
  7678. if (y + rcWnd.bottom - rcWnd.top > sImeG.rcWorkArea.bottom) {
  7679. y = sImeG.rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
  7680. }
  7681. // draw the moving track
  7682. hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  7683. if ( hDC == NULL )
  7684. return;
  7685. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  7686. // ->
  7687. PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
  7688. PATINVERT);
  7689. // v
  7690. PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
  7691. cyBorder, PATINVERT);
  7692. // _>
  7693. PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
  7694. rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
  7695. // v
  7696. PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
  7697. - cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
  7698. DeleteDC(hDC);
  7699. return;
  7700. }
  7701. /**********************************************************************/
  7702. /* AdjustStatusBoundary() */
  7703. /**********************************************************************/
  7704. void PASCAL AdjustStatusBoundary(
  7705. LPPOINT lppt)
  7706. {
  7707. // display boundary check
  7708. if (lppt->x < sImeG.rcWorkArea.left) {
  7709. lppt->x = sImeG.rcWorkArea.left;
  7710. } else if (lppt->x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
  7711. lppt->x = (sImeG.rcWorkArea.right - sImeG.xStatusWi);
  7712. }
  7713. if (lppt->y < sImeG.rcWorkArea.top) {
  7714. lppt->y = sImeG.rcWorkArea.top;
  7715. } else if (lppt->y + sImeG.yStatusHi > sImeG.rcWorkArea.bottom) {
  7716. lppt->y = (sImeG.rcWorkArea.bottom - sImeG.yStatusHi);
  7717. }
  7718. return;
  7719. }
  7720. /**********************************************************************/
  7721. /* ContextMenuWndProc() */
  7722. /**********************************************************************/
  7723. LRESULT CALLBACK ContextMenuWndProc(
  7724. HWND hCMenuWnd,
  7725. UINT uMsg,
  7726. WPARAM wParam,
  7727. LPARAM lParam)
  7728. {
  7729. switch (uMsg) {
  7730. case WM_DESTROY:
  7731. {
  7732. HWND hUIWnd;
  7733. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  7734. if (hUIWnd) {
  7735. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  7736. IMN_PRIVATE_CMENUDESTROYED);
  7737. }
  7738. break;
  7739. }
  7740. case WM_USER_DESTROY:
  7741. {
  7742. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  7743. DestroyWindow(hCMenuWnd);
  7744. break;
  7745. }
  7746. case WM_COMMAND:
  7747. {
  7748. HWND hUIWnd;
  7749. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  7750. CommandProc(wParam , GetStatusWnd(hUIWnd));
  7751. break;
  7752. }
  7753. // switch (wParam) {
  7754. /*
  7755. case IDM_SOFTKBD:
  7756. case IDM_SYMBOL:
  7757. {
  7758. HWND hUIWnd;
  7759. HIMC hIMC;
  7760. DWORD fdwConversion;
  7761. DWORD fdwSentence;
  7762. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  7763. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  7764. ImmGetConversionStatus(hIMC, &fdwConversion,
  7765. &fdwSentence);
  7766. if (wParam == IDM_SOFTKBD) {
  7767. ImmSetConversionStatus(hIMC, fdwConversion ^
  7768. IME_CMODE_SOFTKBD, fdwSentence);
  7769. }
  7770. if (wParam == IDM_SYMBOL) {
  7771. ImmSetConversionStatus(hIMC, fdwConversion ^
  7772. IME_CMODE_SYMBOL, fdwSentence);
  7773. }
  7774. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  7775. }
  7776. break;
  7777. case IDM_PROPERTIES:
  7778. ImeConfigure(GetKeyboardLayout(0), hCMenuWnd,
  7779. IME_CONFIG_GENERAL, NULL);
  7780. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  7781. break; */
  7782. // default:
  7783. // return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  7784. // }
  7785. // break;
  7786. case WM_CLOSE:
  7787. {
  7788. HMENU hMenu;
  7789. GetMenu(hCMenuWnd);
  7790. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  7791. if (hMenu) {
  7792. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  7793. DestroyMenu(hMenu);
  7794. }
  7795. }
  7796. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  7797. default:
  7798. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  7799. }
  7800. return (0L);
  7801. }
  7802. /**********************************************************************/
  7803. /* DestroyUIWindow() */
  7804. /**********************************************************************/
  7805. void PASCAL DestroyUIWindow( // destroy composition window
  7806. HWND hUIWnd)
  7807. {
  7808. HGLOBAL hUIPrivate;
  7809. LPUIPRIV lpUIPrivate;
  7810. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  7811. if (!hUIPrivate) { // Oh! Oh!
  7812. return;
  7813. }
  7814. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  7815. if (!lpUIPrivate) { // Oh! Oh!
  7816. return;
  7817. }
  7818. if (lpUIPrivate->hCMenuWnd) {
  7819. SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND,(LONG_PTR)0);
  7820. PostMessage(lpUIPrivate->hCMenuWnd, WM_USER_DESTROY, 0, 0);
  7821. }
  7822. // composition window need to be destroyed
  7823. if (lpUIPrivate->hCompWnd) {
  7824. DestroyWindow(lpUIPrivate->hCompWnd);
  7825. }
  7826. // candidate window need to be destroyed
  7827. if (lpUIPrivate->hCandWnd) {
  7828. DestroyWindow(lpUIPrivate->hCandWnd);
  7829. }
  7830. // status window need to be destroyed
  7831. if (lpUIPrivate->hStatusWnd) {
  7832. DestroyWindow(lpUIPrivate->hStatusWnd);
  7833. }
  7834. // soft keyboard window need to be destroyed
  7835. if (lpUIPrivate->hSoftKbdWnd) {
  7836. ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
  7837. }
  7838. GlobalUnlock(hUIPrivate);
  7839. // free storage for UI settings
  7840. GlobalFree(hUIPrivate);
  7841. return;
  7842. }
  7843. /**********************************************************************/
  7844. /* CMenuDestryed() */
  7845. /**********************************************************************/
  7846. void PASCAL CMenuDestroyed( // context menu window
  7847. // already destroyed
  7848. HWND hUIWnd)
  7849. {
  7850. HGLOBAL hUIPrivate;
  7851. LPUIPRIV lpUIPrivate;
  7852. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  7853. if (!hUIPrivate) { // Oh! Oh!
  7854. return;
  7855. }
  7856. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  7857. if (!lpUIPrivate) { // Oh! Oh!
  7858. return;
  7859. }
  7860. lpUIPrivate->hCMenuWnd = NULL;
  7861. GlobalUnlock(hUIPrivate);
  7862. }