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.

1543 lines
52 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. aime.cpp
  5. Abstract:
  6. This file implements the Active IME (Cicero) Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "context.h"
  13. #include "defs.h"
  14. #include "cdimm.h"
  15. #include "globals.h"
  16. BOOL
  17. CActiveIMM::_CreateActiveIME()
  18. {
  19. //
  20. // do the ImeInquire
  21. //
  22. // Inquire IME's information and UI class name.
  23. _pActiveIME->Inquire(TRUE, &_IMEInfoEx.ImeInfo, _IMEInfoEx.achWndClass, &_IMEInfoEx.dwPrivate);
  24. // Create default input context.
  25. _InputContext._CreateDefaultInputContext(_GetIMEProperty(PROP_PRIVATE_DATA_SIZE),
  26. (_GetIMEProperty(PROP_IME_PROPERTY) & IME_PROP_UNICODE) ? TRUE : FALSE,
  27. TRUE);
  28. //
  29. // Create default IME window.
  30. //
  31. _DefaultIMEWindow._CreateDefaultIMEWindow(_InputContext._GetDefaultHIMC());
  32. return TRUE;
  33. }
  34. BOOL
  35. CActiveIMM::_DestroyActiveIME(
  36. )
  37. {
  38. // Destroy default input context.
  39. _InputContext._DestroyDefaultInputContext();
  40. // shut down our tip
  41. _pActiveIME->Destroy(0);
  42. // Destroy default IME window.
  43. _DefaultIMEWindow._DestroyDefaultIMEWindow();
  44. return TRUE;
  45. }
  46. //+---------------------------------------------------------------------------
  47. //
  48. // _GetCompositionString
  49. //
  50. //----------------------------------------------------------------------------
  51. HRESULT
  52. CActiveIMM::_GetCompositionString(
  53. HIMC hIMC,
  54. DWORD dwIndex,
  55. DWORD dwCompLen,
  56. LONG* lpCopied,
  57. LPVOID lpBuf,
  58. BOOL fUnicode
  59. )
  60. {
  61. HRESULT hr;
  62. DIMM_IMCLock lpIMC(hIMC);
  63. if (FAILED(hr = lpIMC.GetResult()))
  64. return hr;
  65. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  66. if (FAILED(hr = lpCompStr.GetResult()))
  67. return hr;
  68. UINT cp;
  69. _pActiveIME->GetCodePageA(&cp);
  70. BOOL fSwapGuidMapField = FALSE;
  71. DWORD dwSwapLen;
  72. DWORD dwSwapOffset;
  73. if (IsGuidMapEnable(lpIMC->hWnd) && (lpIMC->fdwInit & INIT_GUID_ATOM)) {
  74. //
  75. // Transrate GUID map attribute.
  76. //
  77. lpIMC->m_pContext->MapAttributes((HIMC)lpIMC);
  78. dwSwapLen = lpCompStr->CompStr.dwCompAttrLen;
  79. dwSwapOffset = lpCompStr->CompStr.dwCompAttrOffset;
  80. lpCompStr->CompStr.dwCompAttrLen = lpCompStr->dwGuidMapAttrLen;
  81. lpCompStr->CompStr.dwCompAttrOffset = lpCompStr->dwGuidMapAttrOffset;
  82. fSwapGuidMapField = TRUE;
  83. }
  84. if ((!fUnicode && !lpIMC.IsUnicode()) ||
  85. ( fUnicode && lpIMC.IsUnicode()) ) {
  86. /*
  87. * Composition string in input context is of ANSI style when fUnicode is FALSE.
  88. * Composition string in input context is of Unicode style when fUnicode is TRUE.
  89. */
  90. if (! dwCompLen) {
  91. // query required buffer size. not inculde \0.
  92. if (! fUnicode) {
  93. hr = _InputContext.GetCompositionString(lpCompStr, dwIndex, lpCopied, sizeof(BYTE));
  94. }
  95. else {
  96. switch (dwIndex) {
  97. case GCS_COMPATTR: // ANSI-only
  98. case GCS_COMPREADATTR: // ANSI-only
  99. case GCS_COMPREADCLAUSE: // ANSI-only
  100. case GCS_RESULTCLAUSE: // ANSI-only
  101. case GCS_RESULTREADCLAUSE: // ANSI-only
  102. case GCS_COMPCLAUSE: // ANSI-only
  103. hr = _InputContext.GetCompositionString(lpCompStr, dwIndex, lpCopied, sizeof(BYTE));
  104. break;
  105. default:
  106. hr = _InputContext.GetCompositionString(lpCompStr, dwIndex, lpCopied);
  107. break;
  108. }
  109. }
  110. }
  111. else {
  112. hr = S_OK;
  113. switch (dwIndex) {
  114. case GCS_COMPSTR:
  115. case GCS_COMPREADSTR:
  116. case GCS_RESULTSTR:
  117. case GCS_RESULTREADSTR:
  118. if (! fUnicode) {
  119. CBCompString bstr(cp, lpCompStr, dwIndex);
  120. if (bstr.ReadCompData() != 0) {
  121. *lpCopied = (LONG)bstr.ReadCompData((CHAR*)lpBuf,
  122. dwCompLen / sizeof(CHAR)) * sizeof(CHAR);
  123. }
  124. }
  125. else {
  126. CWCompString wstr(cp, lpCompStr, dwIndex);
  127. if (wstr.ReadCompData() != 0) {
  128. *lpCopied = (LONG)wstr.ReadCompData((WCHAR*)lpBuf,
  129. dwCompLen / sizeof(WCHAR)) * sizeof(WCHAR);
  130. }
  131. }
  132. break;
  133. case GCS_COMPATTR: // ANSI-only
  134. case GCS_COMPREADATTR: // ANSI-only
  135. {
  136. CBCompAttribute battr(cp, lpCompStr, dwIndex);
  137. if (battr.ReadCompData() != 0) {
  138. *lpCopied = (LONG)battr.ReadCompData((BYTE*)lpBuf,
  139. dwCompLen / sizeof(BYTE)) * sizeof(CHAR);
  140. }
  141. }
  142. break;
  143. case GCS_COMPREADCLAUSE: // ANSI-only
  144. case GCS_RESULTCLAUSE: // ANSI-only
  145. case GCS_RESULTREADCLAUSE: // ANSI-only
  146. case GCS_COMPCLAUSE: // ANSI-only
  147. {
  148. CBCompClause bclause(cp, lpCompStr, dwIndex);
  149. if (bclause.ReadCompData() != 0) {
  150. *lpCopied = (LONG)bclause.ReadCompData((DWORD*)lpBuf,
  151. dwCompLen / sizeof(DWORD)) * sizeof(DWORD);
  152. }
  153. }
  154. break;
  155. case GCS_CURSORPOS:
  156. case GCS_DELTASTART:
  157. if (! fUnicode) {
  158. CBCompCursorPos bpos(cp, lpCompStr, dwIndex);
  159. }
  160. else {
  161. CWCompCursorPos wpos(cp, lpCompStr, dwIndex);
  162. }
  163. break;
  164. default:
  165. hr = E_INVALIDARG;
  166. *lpCopied = IMM_ERROR_GENERAL; // ala Win32
  167. break;
  168. }
  169. }
  170. goto _exit;
  171. }
  172. /*
  173. * ANSI caller, Unicode input context/composition string when fUnicode is FALSE.
  174. * Unicode caller, ANSI input context/composition string when fUnicode is TRUE
  175. */
  176. hr = S_OK;
  177. switch (dwIndex) {
  178. case GCS_COMPSTR:
  179. case GCS_COMPREADSTR:
  180. case GCS_RESULTSTR:
  181. case GCS_RESULTREADSTR:
  182. if (! fUnicode) {
  183. /*
  184. * Get ANSI string from Unicode composition string.
  185. */
  186. CWCompString wstr(cp, lpCompStr, dwIndex);
  187. CBCompString bstr(cp, lpCompStr);
  188. if (wstr.ReadCompData() != 0) {
  189. bstr = wstr;
  190. *lpCopied = (LONG)bstr.ReadCompData((CHAR*)lpBuf,
  191. dwCompLen / sizeof(CHAR)) * sizeof(CHAR);
  192. }
  193. }
  194. else {
  195. /*
  196. * Get Unicode string from ANSI composition string.
  197. */
  198. CBCompString bstr(cp, lpCompStr, dwIndex);
  199. CWCompString wstr(cp, lpCompStr);
  200. if (bstr.ReadCompData() != 0) {
  201. wstr = bstr;
  202. *lpCopied = (LONG)wstr.ReadCompData((WCHAR*)lpBuf,
  203. dwCompLen / sizeof(WCHAR)) * sizeof(WCHAR);
  204. }
  205. }
  206. break;
  207. case GCS_COMPATTR:
  208. case GCS_COMPREADATTR:
  209. if (! fUnicode) {
  210. /*
  211. * Get ANSI attribute from Unicode composition attribute.
  212. */
  213. CWCompAttribute wattr(cp, lpCompStr, dwIndex);
  214. CBCompAttribute battr(cp, lpCompStr);
  215. if (wattr.ReadCompData() != 0 &&
  216. wattr.m_wcompstr.ReadCompData() != 0) {
  217. battr = wattr;
  218. *lpCopied = (LONG)battr.ReadCompData((BYTE*)lpBuf,
  219. dwCompLen / sizeof(BYTE)) * sizeof(BYTE);
  220. }
  221. }
  222. else {
  223. /*
  224. * Get Unicode attribute from ANSI composition attribute.
  225. */
  226. CBCompAttribute battr(cp, lpCompStr, dwIndex);
  227. CWCompAttribute wattr(cp, lpCompStr);
  228. if (battr.ReadCompData() != 0 &&
  229. battr.m_bcompstr.ReadCompData() != 0) {
  230. wattr = battr;
  231. *lpCopied = (LONG)wattr.ReadCompData((BYTE*)lpBuf,
  232. dwCompLen / sizeof(BYTE)) * sizeof(BYTE);
  233. }
  234. }
  235. break;
  236. case GCS_COMPREADCLAUSE:
  237. case GCS_RESULTCLAUSE:
  238. case GCS_RESULTREADCLAUSE:
  239. case GCS_COMPCLAUSE:
  240. if (! fUnicode) {
  241. /*
  242. * Get ANSI clause from Unicode composition clause.
  243. */
  244. CWCompClause wclause(cp, lpCompStr, dwIndex);
  245. CBCompClause bclause(cp, lpCompStr);
  246. if (wclause.ReadCompData() != 0 &&
  247. wclause.m_wcompstr.ReadCompData() != 0) {
  248. bclause = wclause;
  249. *lpCopied = (LONG)bclause.ReadCompData((DWORD*)lpBuf,
  250. dwCompLen / sizeof(DWORD)) * sizeof(DWORD);
  251. }
  252. }
  253. else {
  254. /*
  255. * Get Unicode clause from ANSI composition clause.
  256. */
  257. CBCompClause bclause(cp, lpCompStr, dwIndex);
  258. CWCompClause wclause(cp, lpCompStr);
  259. if (bclause.ReadCompData() != 0 &&
  260. bclause.m_bcompstr.ReadCompData() != 0) {
  261. wclause = bclause;
  262. *lpCopied = (LONG)wclause.ReadCompData((DWORD*)lpBuf,
  263. dwCompLen / sizeof(DWORD)) * sizeof(DWORD);
  264. }
  265. }
  266. break;
  267. case GCS_CURSORPOS:
  268. case GCS_DELTASTART:
  269. if (! fUnicode) {
  270. /*
  271. * Get ANSI cursor/delta start position from Unicode composition string.
  272. */
  273. CWCompCursorPos wpos(cp, lpCompStr, dwIndex);
  274. CBCompCursorPos bpos(cp, lpCompStr);
  275. if (wpos.ReadCompData() != 0 &&
  276. wpos.m_wcompstr.ReadCompData() != 0) {
  277. bpos = wpos;
  278. *lpCopied = bpos.GetAt(0);
  279. }
  280. }
  281. else {
  282. /*
  283. * Get Unicode cursor/delta start position from ANSI composition string.
  284. */
  285. CBCompCursorPos bpos(cp, lpCompStr, dwIndex);
  286. CWCompCursorPos wpos(cp, lpCompStr);
  287. if (bpos.ReadCompData() != 0 &&
  288. bpos.m_bcompstr.ReadCompData() != 0) {
  289. wpos = bpos;
  290. *lpCopied = wpos.GetAt(0);
  291. }
  292. }
  293. break;
  294. default:
  295. hr = E_INVALIDARG;
  296. *lpCopied = IMM_ERROR_GENERAL; // ala Win32
  297. break;
  298. }
  299. _exit:
  300. if (fSwapGuidMapField) {
  301. lpCompStr->CompStr.dwCompAttrLen = dwSwapLen;
  302. lpCompStr->CompStr.dwCompAttrOffset = dwSwapOffset;
  303. }
  304. return hr;
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // _Internal_SetCompositionString
  309. //
  310. //----------------------------------------------------------------------------
  311. HRESULT
  312. CActiveIMM::_Internal_SetCompositionString(
  313. HIMC hIMC,
  314. DWORD dwIndex,
  315. LPVOID lpComp,
  316. DWORD dwCompLen,
  317. LPVOID lpRead,
  318. DWORD dwReadLen,
  319. BOOL fUnicode,
  320. BOOL fNeedAWConversion
  321. )
  322. {
  323. HRESULT hr;
  324. UINT cp;
  325. _pActiveIME->GetCodePageA(&cp);
  326. if (! fUnicode) {
  327. CBCompString bCompStr(cp, hIMC, (CHAR*)lpComp, dwCompLen);
  328. CBCompString bCompReadStr(cp, hIMC, (CHAR*)lpRead, dwReadLen);
  329. if (! fNeedAWConversion) {
  330. /*
  331. * Composition string in input context is of ANSI style.
  332. */
  333. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  334. lpComp, dwCompLen,
  335. lpRead, dwReadLen);
  336. }
  337. else {
  338. /*
  339. * ANSI caller, Unicode input context/composition string.
  340. */
  341. CWCompString wCompStr(cp, hIMC);
  342. if (dwCompLen)
  343. wCompStr = bCompStr;
  344. CWCompString wCompReadStr(cp, hIMC);
  345. if (dwReadLen)
  346. wCompReadStr = bCompReadStr;
  347. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  348. wCompStr, (DWORD)(wCompStr.GetSize()),
  349. wCompReadStr, (DWORD)(wCompReadStr.GetSize()));
  350. }
  351. }
  352. else {
  353. CWCompString wCompStr(cp, hIMC, (WCHAR*)lpComp, dwCompLen);
  354. CWCompString wCompReadStr(cp, hIMC, (WCHAR*)lpRead, dwReadLen);
  355. if (! fNeedAWConversion) {
  356. /*
  357. * Composition string in input context is of Unicode style.
  358. */
  359. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  360. lpComp, dwCompLen,
  361. lpRead, dwReadLen);
  362. }
  363. else {
  364. /*
  365. * Unicode caller, ANSI input context/composition string.
  366. */
  367. CBCompString bCompStr(cp, hIMC);
  368. if (dwCompLen)
  369. bCompStr = wCompStr;
  370. CBCompString bCompReadStr(cp, hIMC);
  371. if (dwReadLen)
  372. bCompReadStr = wCompReadStr;
  373. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  374. bCompStr, (DWORD)(bCompStr.GetSize()),
  375. bCompReadStr, (DWORD)(bCompReadStr.GetSize()));
  376. }
  377. }
  378. return hr;
  379. }
  380. //+---------------------------------------------------------------------------
  381. //
  382. // _Internal_SetCompositionAttribute
  383. //
  384. //----------------------------------------------------------------------------
  385. HRESULT
  386. CActiveIMM::_Internal_SetCompositionAttribute(
  387. HIMC hIMC,
  388. DWORD dwIndex,
  389. LPVOID lpComp,
  390. DWORD dwCompLen,
  391. LPVOID lpRead,
  392. DWORD dwReadLen,
  393. BOOL fUnicode,
  394. BOOL fNeedAWConversion
  395. )
  396. {
  397. HRESULT hr;
  398. UINT cp;
  399. _pActiveIME->GetCodePageA(&cp);
  400. if (! fUnicode) {
  401. CBCompAttribute bCompAttr(cp, hIMC, (BYTE*)lpComp, dwCompLen);
  402. CBCompAttribute bCompReadAttr(cp, hIMC, (BYTE*)lpRead, dwReadLen);
  403. if (! fNeedAWConversion) {
  404. /*
  405. * Composition string in input context is of ANSI style.
  406. */
  407. {
  408. DIMM_IMCLock lpIMC(hIMC);
  409. if (FAILED(hr = lpIMC.GetResult()))
  410. return hr;
  411. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  412. if (FAILED(hr = lpCompStr.GetResult()))
  413. return hr;
  414. CBCompAttribute himc_battr(cp, lpCompStr, GCS_COMPATTR);
  415. CBCompClause himc_bclause(cp, lpCompStr, GCS_COMPCLAUSE);
  416. if (FAILED(hr=CheckAttribute(bCompAttr, himc_battr, himc_bclause)))
  417. return hr;
  418. CBCompAttribute himc_breadattr(cp, lpCompStr, GCS_COMPREADATTR);
  419. CBCompClause himc_breadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  420. if (FAILED(hr=CheckAttribute(bCompReadAttr, himc_breadattr, himc_breadclause)))
  421. return hr;
  422. }
  423. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  424. bCompAttr, (DWORD)(bCompAttr.GetSize()),
  425. bCompReadAttr, (DWORD)(bCompReadAttr.GetSize()));
  426. }
  427. else {
  428. /*
  429. * ANSI caller, Unicode input context/composition string.
  430. */
  431. CWCompAttribute wCompAttr(cp, hIMC);
  432. CWCompAttribute wCompReadAttr(cp, hIMC);
  433. {
  434. DIMM_IMCLock lpIMC(hIMC);
  435. if (FAILED(hr = lpIMC.GetResult()))
  436. return hr;
  437. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  438. if (FAILED(hr = lpCompStr.GetResult()))
  439. return hr;
  440. if (dwCompLen) {
  441. wCompAttr = bCompAttr;
  442. CWCompAttribute himc_wattr(cp, lpCompStr, GCS_COMPATTR);
  443. CWCompClause himc_wclause(cp, lpCompStr, GCS_COMPCLAUSE);
  444. if (FAILED(hr=CheckAttribute(wCompAttr, himc_wattr, himc_wclause)))
  445. return hr;
  446. }
  447. if (dwReadLen) {
  448. wCompReadAttr = bCompReadAttr;
  449. CWCompAttribute himc_wreadattr(cp, lpCompStr, GCS_COMPREADATTR);
  450. CWCompClause himc_wreadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  451. if (FAILED(hr=CheckAttribute(wCompReadAttr, himc_wreadattr, himc_wreadclause)))
  452. return hr;
  453. }
  454. }
  455. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  456. wCompAttr, (DWORD)(wCompAttr.GetSize()),
  457. wCompReadAttr, (DWORD)(wCompReadAttr.GetSize()));
  458. }
  459. }
  460. else {
  461. CWCompAttribute wCompAttr(cp, hIMC, (BYTE*)lpComp, dwCompLen);
  462. CWCompAttribute wCompReadAttr(cp, hIMC, (BYTE*)lpRead, dwReadLen);
  463. if (! fNeedAWConversion) {
  464. /*
  465. * Composition string in input context is of Unicode style.
  466. */
  467. {
  468. DIMM_IMCLock lpIMC(hIMC);
  469. if (FAILED(hr = lpIMC.GetResult()))
  470. return hr;
  471. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  472. if (FAILED(hr = lpCompStr.GetResult()))
  473. return hr;
  474. CWCompAttribute himc_wattr(cp, lpCompStr, GCS_COMPATTR);
  475. CWCompClause himc_wclause(cp, lpCompStr, GCS_COMPCLAUSE);
  476. if (FAILED(hr=CheckAttribute(wCompAttr, himc_wattr, himc_wclause)))
  477. return hr;
  478. CWCompAttribute himc_wreadattr(cp, lpCompStr, GCS_COMPREADATTR);
  479. CWCompClause himc_wreadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  480. if (FAILED(hr=CheckAttribute(wCompReadAttr, himc_wreadattr, himc_wreadclause)))
  481. return hr;
  482. }
  483. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  484. wCompAttr, (DWORD)(wCompAttr.GetSize()),
  485. wCompReadAttr, (DWORD)(wCompReadAttr.GetSize()));
  486. }
  487. else {
  488. /*
  489. * Unicode caller, ANSI input context/composition string.
  490. */
  491. CBCompAttribute bCompAttr(cp, hIMC);
  492. CBCompAttribute bCompReadAttr(cp, hIMC);
  493. {
  494. DIMM_IMCLock lpIMC(hIMC);
  495. if (FAILED(hr = lpIMC.GetResult()))
  496. return hr;
  497. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  498. if (FAILED(hr = lpCompStr.GetResult()))
  499. return hr;
  500. if (dwCompLen) {
  501. bCompAttr = wCompAttr;
  502. CBCompAttribute himc_battr(cp, lpCompStr, GCS_COMPATTR);
  503. CBCompClause himc_bclause(cp, lpCompStr, GCS_COMPCLAUSE);
  504. if (FAILED(hr=CheckAttribute(bCompAttr, himc_battr, himc_bclause)))
  505. return hr;
  506. }
  507. if (dwReadLen) {
  508. bCompReadAttr = wCompReadAttr;
  509. CBCompAttribute himc_breadattr(cp, lpCompStr, GCS_COMPREADATTR);
  510. CBCompClause himc_breadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  511. if (FAILED(hr=CheckAttribute(bCompReadAttr, himc_breadattr, himc_breadclause)))
  512. return hr;
  513. }
  514. }
  515. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  516. bCompAttr, (DWORD)(bCompAttr.GetSize()),
  517. bCompReadAttr, (DWORD)(bCompReadAttr.GetSize()));
  518. }
  519. }
  520. return hr;
  521. }
  522. //+---------------------------------------------------------------------------
  523. //
  524. // _Internal_SetCompositionClause
  525. //
  526. //----------------------------------------------------------------------------
  527. HRESULT
  528. CActiveIMM::_Internal_SetCompositionClause(
  529. IN HIMC hIMC,
  530. IN DWORD dwIndex,
  531. IN LPVOID lpComp,
  532. IN DWORD dwCompLen,
  533. IN LPVOID lpRead,
  534. IN DWORD dwReadLen,
  535. IN BOOL fUnicode,
  536. IN BOOL fNeedAWConversion
  537. )
  538. {
  539. HRESULT hr;
  540. UINT cp;
  541. _pActiveIME->GetCodePageA(&cp);
  542. if (! fUnicode) {
  543. CBCompClause bCompClause(cp, hIMC, (DWORD*)lpComp, dwCompLen);
  544. CBCompClause bCompReadClause(cp, hIMC, (DWORD*)lpRead, dwReadLen);
  545. if (! fNeedAWConversion) {
  546. /*
  547. * Composition string in input context is of ANSI style.
  548. */
  549. {
  550. DIMM_IMCLock lpIMC(hIMC);
  551. if (FAILED(hr = lpIMC.GetResult()))
  552. return hr;
  553. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  554. if (FAILED(hr = lpCompStr.GetResult()))
  555. return hr;
  556. CBCompClause himc_bclause(cp, lpCompStr, GCS_COMPCLAUSE);
  557. if (FAILED(hr=CheckClause(bCompClause, himc_bclause)))
  558. return hr;
  559. CBCompClause himc_breadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  560. if (FAILED(hr=CheckClause(bCompReadClause, himc_breadclause)))
  561. return hr;
  562. }
  563. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  564. bCompClause, (DWORD)(bCompClause.GetSize()),
  565. bCompReadClause, (DWORD)(bCompReadClause.GetSize()));
  566. }
  567. else {
  568. /*
  569. * ANSI caller, Unicode input context/composition string.
  570. */
  571. CWCompClause wCompClause(cp, hIMC);
  572. CWCompClause wCompReadClause(cp, hIMC);
  573. {
  574. DIMM_IMCLock lpIMC(hIMC);
  575. if (FAILED(hr = lpIMC.GetResult()))
  576. return hr;
  577. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  578. if (FAILED(hr = lpCompStr.GetResult()))
  579. return hr;
  580. if (dwCompLen) {
  581. wCompClause = bCompClause;
  582. CWCompClause himc_wclause(cp, lpCompStr, GCS_COMPCLAUSE);
  583. if (FAILED(hr=CheckClause(wCompClause, himc_wclause)))
  584. return hr;
  585. }
  586. if (dwReadLen) {
  587. wCompReadClause = bCompReadClause;
  588. CWCompClause himc_wclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  589. if (FAILED(hr=CheckClause(wCompReadClause, himc_wclause)))
  590. return hr;
  591. }
  592. }
  593. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  594. wCompClause, (DWORD)(wCompClause.GetSize()),
  595. wCompReadClause, (DWORD)(wCompReadClause.GetSize()));
  596. }
  597. }
  598. else {
  599. CWCompClause wCompClause(cp, hIMC, (DWORD*)lpComp, dwCompLen);
  600. CWCompClause wCompReadClause(cp, hIMC, (DWORD*)lpRead, dwReadLen);
  601. if (! fNeedAWConversion) {
  602. /*
  603. * Composition string in input context is of Unicode style.
  604. */
  605. {
  606. DIMM_IMCLock lpIMC(hIMC);
  607. if (FAILED(hr = lpIMC.GetResult()))
  608. return hr;
  609. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  610. if (FAILED(hr = lpCompStr.GetResult()))
  611. return hr;
  612. CWCompClause himc_wclause(cp, lpCompStr, GCS_COMPCLAUSE);
  613. if (FAILED(CheckClause(wCompClause, himc_wclause)))
  614. return E_FAIL;
  615. CWCompClause himc_wreadclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  616. if (FAILED(CheckClause(wCompReadClause, himc_wreadclause)))
  617. return E_FAIL;
  618. }
  619. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  620. wCompClause, (DWORD)(wCompClause.GetSize()),
  621. wCompReadClause, (DWORD)(wCompReadClause.GetSize()));
  622. }
  623. else {
  624. /*
  625. * Unicode caller, ANSI input context/composition string.
  626. */
  627. CBCompClause bCompClause(cp, hIMC);
  628. CBCompClause bCompReadClause(cp, hIMC);
  629. {
  630. DIMM_IMCLock lpIMC(hIMC);
  631. if (FAILED(hr = lpIMC.GetResult()))
  632. return hr;
  633. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  634. if (FAILED(hr = lpCompStr.GetResult()))
  635. return hr;
  636. if (dwCompLen) {
  637. bCompClause = wCompClause;
  638. CBCompClause himc_bclause(cp, lpCompStr, GCS_COMPCLAUSE);
  639. if (FAILED(hr=CheckClause(bCompClause, himc_bclause)))
  640. return hr;
  641. }
  642. if (dwReadLen) {
  643. bCompReadClause = wCompReadClause;
  644. CBCompClause himc_bclause(cp, lpCompStr, GCS_COMPREADCLAUSE);
  645. if (FAILED(hr=CheckClause(bCompReadClause, himc_bclause)))
  646. return hr;
  647. }
  648. }
  649. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  650. bCompClause, (DWORD)(bCompClause.GetSize()),
  651. bCompReadClause, (DWORD)(bCompReadClause.GetSize()));
  652. }
  653. }
  654. return hr;
  655. }
  656. HRESULT
  657. CActiveIMM::_Internal_ReconvertString(
  658. IN HIMC hIMC,
  659. IN DWORD dwIndex,
  660. IN LPVOID lpComp,
  661. IN DWORD dwCompLen,
  662. IN LPVOID lpRead,
  663. IN DWORD dwReadLen,
  664. IN BOOL fUnicode,
  665. IN BOOL fNeedAWConversion,
  666. OUT LRESULT* plResult // = NULL
  667. )
  668. {
  669. HRESULT hr;
  670. LPVOID lpOrgComp = lpComp;
  671. LPVOID lpOrgRead = lpRead;
  672. UINT cp;
  673. _pActiveIME->GetCodePageA(&cp);
  674. HWND hWnd = NULL;
  675. if (dwIndex == IMR_CONFIRMRECONVERTSTRING ||
  676. dwIndex == IMR_RECONVERTSTRING ||
  677. dwIndex == IMR_DOCUMENTFEED) {
  678. DIMM_IMCLock imc(hIMC);
  679. if (FAILED(hr = imc.GetResult()))
  680. return hr;
  681. hWnd = imc->hWnd;
  682. }
  683. if (! fUnicode) {
  684. if (! fNeedAWConversion) {
  685. /*
  686. * Composition string in input context is of ANSI style.
  687. */
  688. if (dwIndex != IMR_CONFIRMRECONVERTSTRING &&
  689. dwIndex != IMR_RECONVERTSTRING &&
  690. dwIndex != IMR_DOCUMENTFEED) {
  691. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  692. lpComp, dwCompLen,
  693. lpRead, dwReadLen);
  694. }
  695. else {
  696. *plResult = ::SendMessageA(hWnd,
  697. WM_IME_REQUEST,
  698. dwIndex, (LPARAM)lpComp);
  699. }
  700. }
  701. else {
  702. /*
  703. * ANSI caller, Unicode input context/composition string.
  704. */
  705. CBReconvertString bReconvStr(cp, hIMC, (LPRECONVERTSTRING)lpComp, dwCompLen);
  706. CWReconvertString wReconvStr(cp, hIMC);
  707. if (bReconvStr.m_bcompstr.ReadCompData()) {
  708. wReconvStr = bReconvStr;
  709. }
  710. CBReconvertString bReconvReadStr(cp, hIMC, (LPRECONVERTSTRING)lpRead, dwReadLen);
  711. CWReconvertString wReconvReadStr(cp, hIMC);
  712. if (bReconvReadStr.m_bcompstr.ReadCompData()) {
  713. wReconvReadStr = bReconvReadStr;
  714. }
  715. BOOL fCompMem = FALSE, fReadMem = FALSE;
  716. LPRECONVERTSTRING _lpComp = NULL;
  717. DWORD _dwCompLen = wReconvStr.ReadCompData();
  718. if (_dwCompLen) {
  719. _lpComp = (LPRECONVERTSTRING) new BYTE[ _dwCompLen ];
  720. if (_lpComp) {
  721. fCompMem = TRUE;
  722. wReconvStr.ReadCompData(_lpComp, _dwCompLen);
  723. }
  724. }
  725. LPRECONVERTSTRING _lpRead = NULL;
  726. DWORD _dwReadLen = wReconvReadStr.ReadCompData();
  727. if (_dwReadLen) {
  728. _lpRead = (LPRECONVERTSTRING) new BYTE[ _dwReadLen ];
  729. if (_lpRead) {
  730. fReadMem = TRUE;
  731. wReconvStr.ReadCompData(_lpRead, _dwReadLen);
  732. }
  733. }
  734. if (dwIndex != IMR_CONFIRMRECONVERTSTRING &&
  735. dwIndex != IMR_RECONVERTSTRING &&
  736. dwIndex != IMR_DOCUMENTFEED) {
  737. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  738. _lpComp, _dwCompLen,
  739. _lpRead, _dwReadLen);
  740. }
  741. else {
  742. *plResult = ::SendMessageA(hWnd,
  743. WM_IME_REQUEST,
  744. dwIndex, (LPARAM)_lpComp);
  745. }
  746. if (fCompMem)
  747. delete [] _lpComp;
  748. if (fReadMem)
  749. delete [] _lpRead;
  750. }
  751. }
  752. else {
  753. if (! fNeedAWConversion) {
  754. /*
  755. * Composition string in input context is of Unicode style.
  756. */
  757. if (dwIndex != IMR_CONFIRMRECONVERTSTRING &&
  758. dwIndex != IMR_RECONVERTSTRING &&
  759. dwIndex != IMR_DOCUMENTFEED) {
  760. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  761. lpComp, dwCompLen,
  762. lpRead, dwReadLen);
  763. }
  764. else {
  765. *plResult = ::SendMessageW(hWnd,
  766. WM_IME_REQUEST,
  767. dwIndex, (LPARAM)lpComp);
  768. }
  769. }
  770. else {
  771. /*
  772. * Unicode caller, ANSI input context/composition string.
  773. */
  774. CWReconvertString wReconvStr(cp, hIMC, (LPRECONVERTSTRING)lpComp, dwCompLen);
  775. CBReconvertString bReconvStr(cp, hIMC);
  776. if (wReconvStr.m_wcompstr.ReadCompData()) {
  777. bReconvStr = wReconvStr;
  778. }
  779. CWReconvertString wReconvReadStr(cp, hIMC, (LPRECONVERTSTRING)lpRead, dwReadLen);
  780. CBReconvertString bReconvReadStr(cp, hIMC);
  781. if (wReconvReadStr.m_wcompstr.ReadCompData()) {
  782. bReconvReadStr = wReconvReadStr;
  783. }
  784. BOOL fCompMem = FALSE, fReadMem = FALSE;
  785. LPRECONVERTSTRING _lpComp = NULL;
  786. DWORD _dwCompLen = bReconvStr.ReadCompData();
  787. if (_dwCompLen) {
  788. _lpComp = (LPRECONVERTSTRING) new BYTE[ _dwCompLen ];
  789. if (_lpComp) {
  790. fCompMem = TRUE;
  791. bReconvStr.ReadCompData(_lpComp, _dwCompLen);
  792. }
  793. }
  794. LPRECONVERTSTRING _lpRead = NULL;
  795. DWORD _dwReadLen = bReconvReadStr.ReadCompData();
  796. if (_dwReadLen) {
  797. _lpRead = (LPRECONVERTSTRING) new BYTE[ _dwReadLen ];
  798. if (_lpRead) {
  799. fReadMem = TRUE;
  800. bReconvStr.ReadCompData(_lpRead, _dwReadLen);
  801. }
  802. }
  803. if (dwIndex != IMR_CONFIRMRECONVERTSTRING &&
  804. dwIndex != IMR_RECONVERTSTRING &&
  805. dwIndex != IMR_DOCUMENTFEED) {
  806. hr = _pActiveIME->SetCompositionString(hIMC,dwIndex,
  807. _lpComp, _dwCompLen,
  808. _lpRead, _dwReadLen);
  809. }
  810. else {
  811. *plResult = ::SendMessageW(hWnd,
  812. WM_IME_REQUEST,
  813. dwIndex, (LPARAM)_lpComp);
  814. }
  815. if (fCompMem)
  816. delete [] _lpComp;
  817. if (fReadMem)
  818. delete [] _lpRead;
  819. }
  820. }
  821. /*
  822. * Check if need ANSI/Unicode back conversion
  823. */
  824. if (fNeedAWConversion) {
  825. switch (dwIndex) {
  826. case SCS_QUERYRECONVERTSTRING:
  827. case IMR_RECONVERTSTRING:
  828. case IMR_DOCUMENTFEED:
  829. if (lpOrgComp) {
  830. if (! fUnicode) {
  831. CWReconvertString wReconvStr(cp, hIMC, (LPRECONVERTSTRING)lpComp, dwCompLen);
  832. CBReconvertString bReconvStr(cp, hIMC);
  833. if (wReconvStr.m_wcompstr.ReadCompData()) {
  834. bReconvStr = wReconvStr;
  835. bReconvStr.m_bcompstr.ReadCompData((CHAR*)lpOrgComp, (DWORD)bReconvStr.m_bcompstr.ReadCompData());
  836. }
  837. }
  838. else {
  839. CBReconvertString bReconvStr(cp, hIMC, (LPRECONVERTSTRING)lpComp, dwCompLen);
  840. CWReconvertString wReconvStr(cp, hIMC);
  841. if (bReconvStr.m_bcompstr.ReadCompData()) {
  842. wReconvStr = bReconvStr;
  843. wReconvStr.m_wcompstr.ReadCompData((WCHAR*)lpOrgComp, (DWORD)wReconvStr.m_wcompstr.ReadCompData());
  844. }
  845. }
  846. }
  847. if (lpOrgRead) {
  848. if (! fUnicode) {
  849. CWReconvertString wReconvReadStr(cp, hIMC, (LPRECONVERTSTRING)lpRead, dwReadLen);
  850. CBReconvertString bReconvReadStr(cp, hIMC);
  851. if (wReconvReadStr.m_wcompstr.ReadCompData()) {
  852. bReconvReadStr = wReconvReadStr;
  853. bReconvReadStr.m_bcompstr.ReadCompData((CHAR*)lpOrgComp, (DWORD)bReconvReadStr.m_bcompstr.ReadCompData());
  854. }
  855. }
  856. else {
  857. CBReconvertString bReconvReadStr(cp, hIMC, (LPRECONVERTSTRING)lpRead, dwReadLen);
  858. CWReconvertString wReconvReadStr(cp, hIMC);
  859. if (bReconvReadStr.m_bcompstr.ReadCompData()) {
  860. wReconvReadStr = bReconvReadStr;
  861. wReconvReadStr.m_wcompstr.ReadCompData((WCHAR*)lpOrgComp, (DWORD)wReconvReadStr.m_wcompstr.ReadCompData());
  862. }
  863. }
  864. }
  865. break;
  866. }
  867. }
  868. return hr;
  869. }
  870. HRESULT
  871. CActiveIMM::_Internal_CompositionFont(
  872. DIMM_IMCLock& imc,
  873. WPARAM wParam,
  874. LPARAM lParam,
  875. BOOL fUnicode,
  876. BOOL fNeedAWConversion,
  877. LRESULT* plResult
  878. )
  879. {
  880. UINT cp;
  881. _pActiveIME->GetCodePageA(&cp);
  882. if (! fUnicode) {
  883. if (! fNeedAWConversion) {
  884. /*
  885. * Composition string in input context is of ANSI style.
  886. */
  887. *plResult = ::SendMessageA(imc->hWnd,
  888. WM_IME_REQUEST,
  889. wParam, lParam);
  890. }
  891. else {
  892. /*
  893. * ANSI caller, Unicode input context/composition string.
  894. */
  895. LOGFONTA LogFontA;
  896. *plResult = ::SendMessageA(imc->hWnd,
  897. WM_IME_REQUEST,
  898. wParam, (LPARAM)&LogFontA);
  899. LFontAtoLFontW(&LogFontA, (LOGFONTW*)lParam, cp);
  900. }
  901. }
  902. else {
  903. if (! fNeedAWConversion) {
  904. /*
  905. * Composition string in input context is of Unicode style.
  906. */
  907. *plResult = ::SendMessageW(imc->hWnd,
  908. WM_IME_REQUEST,
  909. wParam, lParam);
  910. }
  911. else {
  912. /*
  913. * Unicode caller, ANSI input context/composition string.
  914. */
  915. LOGFONTW LogFontW;
  916. *plResult = ::SendMessageW(imc->hWnd,
  917. WM_IME_REQUEST,
  918. wParam, (LPARAM)&LogFontW);
  919. LFontWtoLFontA(&LogFontW, (LOGFONTA*)lParam, cp);
  920. }
  921. }
  922. return S_OK;
  923. }
  924. HRESULT
  925. CActiveIMM::_Internal_QueryCharPosition(
  926. DIMM_IMCLock& imc,
  927. WPARAM wParam,
  928. LPARAM lParam,
  929. BOOL fUnicode,
  930. BOOL fNeedAWConversion,
  931. LRESULT* plResult
  932. )
  933. {
  934. if (! fUnicode) {
  935. if (! fNeedAWConversion) {
  936. /*
  937. * Composition string in input context is of ANSI style.
  938. */
  939. *plResult = ::SendMessageA(imc->hWnd,
  940. WM_IME_REQUEST,
  941. wParam, lParam);
  942. }
  943. else {
  944. /*
  945. * ANSI caller, Receiver Unicode application.
  946. */
  947. IMECHARPOSITION* ipA = (IMECHARPOSITION*)lParam;
  948. DWORD dwSaveCharPos = ipA->dwCharPos;
  949. _GetCompositionString((HIMC)imc, GCS_CURSORPOS, 0, (LONG*)&ipA->dwCharPos, NULL, TRUE);
  950. *plResult = ::SendMessageA(imc->hWnd,
  951. WM_IME_REQUEST,
  952. wParam, (LPARAM)ipA);
  953. ipA->dwCharPos = dwSaveCharPos;
  954. }
  955. }
  956. else {
  957. if (! fNeedAWConversion) {
  958. /*
  959. * Composition string in input context is of Unicode style.
  960. */
  961. *plResult = ::SendMessageW(imc->hWnd,
  962. WM_IME_REQUEST,
  963. wParam, lParam);
  964. }
  965. else {
  966. /*
  967. * Unicode caller, Receiver ANSI application.
  968. */
  969. IMECHARPOSITION* ipW = (IMECHARPOSITION*)lParam;
  970. DWORD dwSaveCharPos = ipW->dwCharPos;
  971. _GetCompositionString((HIMC)imc, GCS_CURSORPOS, 0, (LONG*)&ipW->dwCharPos, NULL, FALSE);
  972. *plResult = ::SendMessageW(imc->hWnd,
  973. WM_IME_REQUEST,
  974. wParam, (LPARAM)ipW);
  975. ipW->dwCharPos = dwSaveCharPos;
  976. }
  977. }
  978. return S_OK;
  979. }
  980. //+---------------------------------------------------------------------------
  981. //
  982. // _SetCompositionString
  983. //
  984. //----------------------------------------------------------------------------
  985. HRESULT
  986. CActiveIMM::_SetCompositionString(
  987. HIMC hIMC,
  988. DWORD dwIndex,
  989. LPVOID lpComp,
  990. DWORD dwCompLen,
  991. LPVOID lpRead,
  992. DWORD dwReadLen,
  993. BOOL fUnicode
  994. )
  995. {
  996. HRESULT hr;
  997. BOOL fNeedAWConversion;
  998. BOOL fIMCUnicode;
  999. IMTLS *ptls = IMTLS_GetOrAlloc();
  1000. TraceMsg(TF_API, "CActiveIMM::SetCompositionString");
  1001. {
  1002. DIMM_IMCLock lpIMC(hIMC);
  1003. if (FAILED(hr = lpIMC.GetResult()))
  1004. return hr;
  1005. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  1006. if (FAILED(hr = lpCompStr.GetResult()))
  1007. return hr;
  1008. if (lpCompStr->CompStr.dwSize < sizeof(COMPOSITIONSTRING))
  1009. return E_FAIL;
  1010. fIMCUnicode = lpIMC.IsUnicode();
  1011. }
  1012. /*
  1013. * Check if we need Unicode conversion
  1014. */
  1015. if ((!fUnicode && !fIMCUnicode) ||
  1016. ( fUnicode && fIMCUnicode) ) {
  1017. /*
  1018. * No ANSI conversion needed when fUnicode is FALSE.
  1019. * No Unicode conversion needed when fUnicode is TRUE.
  1020. */
  1021. fNeedAWConversion = FALSE;
  1022. }
  1023. else {
  1024. fNeedAWConversion = TRUE;
  1025. }
  1026. switch (dwIndex) {
  1027. case SCS_SETSTR:
  1028. hr = _Internal_SetCompositionString(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, fUnicode, fNeedAWConversion);
  1029. break;
  1030. case SCS_CHANGEATTR:
  1031. hr = _Internal_SetCompositionAttribute(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, fUnicode, fNeedAWConversion);
  1032. break;
  1033. case SCS_CHANGECLAUSE:
  1034. hr = _Internal_SetCompositionClause(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, fUnicode, fNeedAWConversion);
  1035. break;
  1036. case SCS_SETRECONVERTSTRING:
  1037. case SCS_QUERYRECONVERTSTRING:
  1038. if (_GetIMEProperty(PROP_SCS_CAPS) & SCS_CAP_SETRECONVERTSTRING) {
  1039. hr = _Internal_ReconvertString(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, fUnicode, fNeedAWConversion);
  1040. }
  1041. else if (ptls != NULL) {
  1042. LANGID langid;
  1043. ptls->pAImeProfile->GetLangId(&langid);
  1044. if (PRIMARYLANGID(langid) == LANG_KOREAN) {
  1045. hr = _Internal_ReconvertString(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, fUnicode, fNeedAWConversion);
  1046. }
  1047. }
  1048. break;
  1049. default:
  1050. hr = E_INVALIDARG;
  1051. break;
  1052. }
  1053. return hr;
  1054. }
  1055. void
  1056. CActiveIMM::LFontAtoLFontW(
  1057. LPLOGFONTA lpLogFontA,
  1058. LPLOGFONTW lpLogFontW,
  1059. UINT uCodePage
  1060. )
  1061. {
  1062. INT i;
  1063. memcpy(lpLogFontW, lpLogFontA, sizeof(LOGFONTA)-LF_FACESIZE);
  1064. i = MultiByteToWideChar(uCodePage, // hIMC's code page
  1065. MB_PRECOMPOSED,
  1066. lpLogFontA->lfFaceName,
  1067. strlen(lpLogFontA->lfFaceName),
  1068. lpLogFontW->lfFaceName,
  1069. LF_FACESIZE);
  1070. lpLogFontW->lfFaceName[i] = L'\0';
  1071. return;
  1072. }
  1073. void
  1074. CActiveIMM::LFontWtoLFontA(
  1075. LPLOGFONTW lpLogFontW,
  1076. LPLOGFONTA lpLogFontA,
  1077. UINT uCodePage
  1078. )
  1079. {
  1080. INT i;
  1081. memcpy(lpLogFontA, lpLogFontW, sizeof(LOGFONTA)-LF_FACESIZE);
  1082. i = WideCharToMultiByte(uCodePage, // hIMC's code page
  1083. 0,
  1084. lpLogFontW->lfFaceName,
  1085. wcslen(lpLogFontW->lfFaceName),
  1086. lpLogFontA->lfFaceName,
  1087. LF_FACESIZE-1,
  1088. NULL,
  1089. NULL);
  1090. lpLogFontA->lfFaceName[i] = '\0';
  1091. return;
  1092. }
  1093. HRESULT
  1094. CActiveIMM::_GetCompositionFont(
  1095. IN HIMC hIMC,
  1096. IN LOGFONTAW* lplf,
  1097. IN BOOL fUnicode
  1098. )
  1099. /*++
  1100. AIMM Composition Font API Methods
  1101. --*/
  1102. {
  1103. TraceMsg(TF_API, "CActiveIMM::GetCompositionFont");
  1104. DWORD dwProcessId;
  1105. BOOL fImcUnicode;
  1106. UINT uCodePage;
  1107. if (FAILED(_pActiveIME->GetCodePageA(&uCodePage)))
  1108. return E_FAIL;
  1109. if (!_InputContext.ContextLookup(hIMC, &dwProcessId, &fImcUnicode)) {
  1110. TraceMsg(TF_WARNING, "CActiveIMM::_GetCompositionFont: Invalid hIMC %lx", hIMC);
  1111. return E_FAIL;
  1112. }
  1113. if (fUnicode) {
  1114. if (! fImcUnicode) {
  1115. LOGFONTA LogFontA, *pLogFontA;
  1116. pLogFontA = &LogFontA;
  1117. if (SUCCEEDED(_GetCompositionFont(hIMC, (LOGFONTAW*)pLogFontA, FALSE))) {
  1118. LFontAtoLFontW(pLogFontA, &lplf->W, uCodePage);
  1119. return S_OK;
  1120. }
  1121. return E_FAIL;
  1122. }
  1123. }
  1124. else {
  1125. if (fImcUnicode) {
  1126. LOGFONTW LogFontW, *pLogFontW;
  1127. pLogFontW = &LogFontW;
  1128. if (SUCCEEDED(_GetCompositionFont(hIMC, (LOGFONTAW*)pLogFontW, TRUE))) {
  1129. LFontWtoLFontA(pLogFontW, &lplf->A, uCodePage);
  1130. return S_OK;
  1131. }
  1132. return E_FAIL;
  1133. }
  1134. }
  1135. HRESULT hr;
  1136. DIMM_IMCLock lpIMC(hIMC);
  1137. if (FAILED(hr = lpIMC.GetResult()))
  1138. return hr;
  1139. return _InputContext.GetCompositionFont(lpIMC, lplf, fUnicode);
  1140. }
  1141. HRESULT
  1142. CActiveIMM::_SetCompositionFont(
  1143. IN HIMC hIMC,
  1144. IN LOGFONTAW* lplf,
  1145. IN BOOL fUnicode
  1146. )
  1147. /*++
  1148. AIMM Composition Font API Methods
  1149. --*/
  1150. {
  1151. HRESULT hr;
  1152. HWND hWnd;
  1153. TraceMsg(TF_API, "CActiveIMM::SetCompositionFont");
  1154. DWORD dwProcessId;
  1155. BOOL fImcUnicode;
  1156. UINT uCodePage;
  1157. if (FAILED(_pActiveIME->GetCodePageA(&uCodePage)))
  1158. return E_FAIL;
  1159. if (!_InputContext.ContextLookup(hIMC, &dwProcessId, &fImcUnicode)) {
  1160. TraceMsg(TF_WARNING, "CActiveIMM::_SetCompositionFont: Invalid hIMC %lx", hIMC);
  1161. return E_FAIL;
  1162. }
  1163. if (fUnicode) {
  1164. if (! fImcUnicode) {
  1165. LOGFONTA LogFontA, *pLogFontA;
  1166. pLogFontA = &LogFontA;
  1167. LFontWtoLFontA(&lplf->W, pLogFontA, uCodePage);
  1168. return _SetCompositionFont(hIMC, (LOGFONTAW*)pLogFontA, FALSE);
  1169. }
  1170. }
  1171. else {
  1172. if (fImcUnicode) {
  1173. LOGFONTW LogFontW, *pLogFontW;
  1174. pLogFontW = &LogFontW;
  1175. LFontAtoLFontW(&lplf->A, pLogFontW, uCodePage);
  1176. return _SetCompositionFont(hIMC, (LOGFONTAW*)pLogFontW, TRUE);
  1177. }
  1178. }
  1179. {
  1180. DIMM_IMCLock lpIMC(hIMC);
  1181. if (FAILED(hr = lpIMC.GetResult()))
  1182. return hr;
  1183. hr = _InputContext.SetCompositionFont(lpIMC, lplf, fUnicode);
  1184. hWnd = lpIMC->hWnd;
  1185. }
  1186. /*
  1187. * inform IME and Apps Wnd about the change of composition font.
  1188. */
  1189. _SendIMENotify(hIMC, hWnd,
  1190. NI_CONTEXTUPDATED, 0L, IMC_SETCOMPOSITIONFONT,
  1191. IMN_SETCOMPOSITIONFONT, 0L);
  1192. return hr;
  1193. }
  1194. HRESULT
  1195. CActiveIMM::_RequestMessage(
  1196. IN HIMC hIMC,
  1197. IN WPARAM wParam,
  1198. IN LPARAM lParam,
  1199. OUT LRESULT *plResult,
  1200. IN BOOL fUnicode
  1201. )
  1202. /*++
  1203. AIMM Request Message API Methods
  1204. --*/
  1205. {
  1206. TraceMsg(TF_API, "CActiveIMM::RequestMessage");
  1207. HRESULT hr;
  1208. DIMM_IMCLock imc(hIMC);
  1209. if (FAILED(hr = imc.GetResult()))
  1210. return hr;
  1211. //
  1212. // NT4 and Win2K doesn't have thunk routine of WM_IME_REQUEST message.
  1213. // Any string data doesn't convert between ASCII <--> Unicode.
  1214. // Responsibility of string data type have receiver window proc (imc->hWnd) of this message.
  1215. // If ASCII wnd proc, then returns ASCII string.
  1216. // Otherwise if Unicode wnd proc, returns Unicode string.
  1217. //
  1218. BOOL bUnicodeTarget = ::IsWindowUnicode(imc->hWnd);
  1219. BOOL fNeedAWConversion;
  1220. /*
  1221. * Check if we need Unicode conversion
  1222. */
  1223. if ((!fUnicode && !bUnicodeTarget) ||
  1224. ( fUnicode && bUnicodeTarget) ) {
  1225. /*
  1226. * No ANSI conversion needed when fUnicode is FALSE.
  1227. * No Unicode conversion needed when fUnicode is TRUE.
  1228. */
  1229. fNeedAWConversion = FALSE;
  1230. }
  1231. else {
  1232. fNeedAWConversion = TRUE;
  1233. }
  1234. switch (wParam) {
  1235. case IMR_CONFIRMRECONVERTSTRING:
  1236. case IMR_RECONVERTSTRING:
  1237. case IMR_DOCUMENTFEED:
  1238. hr = _Internal_ReconvertString(hIMC,
  1239. (DWORD)wParam,
  1240. (LPVOID)lParam, ((LPRECONVERTSTRING)lParam)->dwSize,
  1241. NULL, 0,
  1242. fUnicode, fNeedAWConversion,
  1243. plResult);
  1244. break;
  1245. case IMR_COMPOSITIONFONT:
  1246. hr = _Internal_CompositionFont(imc,
  1247. wParam, lParam,
  1248. fUnicode, fNeedAWConversion,
  1249. plResult);
  1250. break;
  1251. case IMR_QUERYCHARPOSITION:
  1252. hr = _Internal_QueryCharPosition(imc,
  1253. wParam, lParam,
  1254. fUnicode, fNeedAWConversion,
  1255. plResult);
  1256. break;
  1257. }
  1258. return hr;
  1259. }
  1260. /*
  1261. * EnumInputContext callback
  1262. */
  1263. /* static */
  1264. BOOL CALLBACK CActiveIMM::_SelectContextProc(
  1265. HIMC hIMC,
  1266. LPARAM lParam
  1267. )
  1268. {
  1269. SCE *psce = (SCE *)lParam;
  1270. CActiveIMM *_this = GetTLS(); // consider: put TLS in lParam!
  1271. if (_this == NULL)
  1272. return FALSE;
  1273. BOOL bIsRealIme_SelKL;
  1274. BOOL bIsRealIme_UnSelKL;
  1275. if (bIsRealIme_SelKL = _this->_IsRealIme(psce->hSelKL))
  1276. return FALSE;
  1277. bIsRealIme_UnSelKL = _this->_IsRealIme(psce->hUnSelKL);
  1278. /*
  1279. * Reinitialize the input context for the selected layout.
  1280. */
  1281. DWORD dwPrivateSize = _this->_GetIMEProperty(PROP_PRIVATE_DATA_SIZE);
  1282. _this->_InputContext.UpdateInputContext(hIMC, dwPrivateSize);
  1283. /*
  1284. * Select the input context
  1285. */
  1286. _this->_AImeSelect(hIMC, TRUE, bIsRealIme_SelKL, bIsRealIme_UnSelKL);
  1287. return TRUE;
  1288. }
  1289. /* static */
  1290. BOOL CALLBACK CActiveIMM::_UnSelectContextProc(
  1291. HIMC hIMC,
  1292. LPARAM lParam
  1293. )
  1294. {
  1295. SCE *psce = (SCE *)lParam;
  1296. CActiveIMM *_this = GetTLS(); // consider: put TLS in lParam!
  1297. if (_this == NULL)
  1298. return FALSE;
  1299. BOOL bIsRealIme_SelKL;
  1300. BOOL bIsRealIme_UnSelKL;
  1301. if (bIsRealIme_UnSelKL = _this->_IsRealIme(psce->hUnSelKL))
  1302. return FALSE;
  1303. bIsRealIme_SelKL = _this->_IsRealIme(psce->hSelKL);
  1304. _this->_AImeSelect(hIMC, FALSE, bIsRealIme_SelKL, bIsRealIme_UnSelKL);
  1305. return TRUE;
  1306. }
  1307. /* static */
  1308. BOOL CALLBACK CActiveIMM::_NotifyIMEProc(
  1309. HIMC hIMC,
  1310. LPARAM lParam
  1311. )
  1312. {
  1313. CActiveIMM *_this = GetTLS(); // consider: put TLS in lParam!
  1314. if (_this == NULL)
  1315. return FALSE;
  1316. if (_this->_IsRealIme())
  1317. return FALSE;
  1318. _this->_AImeNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
  1319. return TRUE;
  1320. }
  1321. #ifdef UNSELECTCHECK
  1322. /* static */
  1323. BOOL CALLBACK CActiveIMM::_UnSelectCheckProc(
  1324. HIMC hIMC,
  1325. LPARAM lParam
  1326. )
  1327. {
  1328. CActiveIMM *_this = GetTLS(); // consider: put TLS in lParam!
  1329. if (_this == NULL)
  1330. return FALSE;
  1331. _this->_AImeUnSelectCheck(hIMC);
  1332. return TRUE;
  1333. }
  1334. #endif UNSELECTCHECK
  1335. /* static */
  1336. BOOL CALLBACK CActiveIMM::_EnumContextProc(
  1337. HIMC hIMC,
  1338. LPARAM lParam
  1339. )
  1340. {
  1341. CContextList* _hIMC_List = (CContextList*)lParam;
  1342. if (_hIMC_List) {
  1343. CContextList::CLIENT_IMC_FLAG client_flag = CContextList::IMCF_NONE;
  1344. _hIMC_List->SetAt(hIMC, client_flag);
  1345. }
  1346. return TRUE;
  1347. }