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.

803 lines
26 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. editcomp.cpp
  5. Abstract:
  6. This file implements the EditCompositionString Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "editcomp.h"
  13. #include "context.h"
  14. #include "compstr.h"
  15. #include "profile.h"
  16. #include "delay.h"
  17. // static BOOL fHanjaRequested = FALSE; // consider: this is not thread safe
  18. /////////////////////////////////////////////////////////////////////////////
  19. // EditCompositionString
  20. //
  21. // Set (almost) all in composition string
  22. //
  23. HRESULT
  24. EditCompositionString::SetString(
  25. IMCLock& imc,
  26. CicInputContext& CicContext,
  27. CWCompString* CompStr,
  28. CWCompAttribute* CompAttr,
  29. CWCompClause* CompClause,
  30. CWCompCursorPos* CompCursorPos,
  31. CWCompDeltaStart* CompDeltaStart,
  32. CWCompTfGuidAtom* CompGuid,
  33. OUT BOOL* lpbBufferOverflow,
  34. CWCompString* CompReadStr,
  35. CWCompAttribute* CompReadAttr,
  36. CWCompClause* CompReadClause,
  37. CWCompString* ResultStr,
  38. CWCompClause* ResultClause,
  39. CWCompString* ResultReadStr,
  40. CWCompClause* ResultReadClause,
  41. CWInterimString* InterimStr
  42. )
  43. {
  44. HRESULT hr;
  45. #ifdef UNSELECTCHECK
  46. if (!_pAImeContext->m_fSelected)
  47. return S_OK;
  48. #endif UNSELECTCHECK
  49. #if 0
  50. DWORD dwImeCompatFlags = ImmGetAppCompatFlags((HIMC)imc);
  51. #endif
  52. if (CicContext.m_fHanjaReConversion.IsSetFlag() ||
  53. CicContext.m_fInClearDocFeedEditSession.IsSetFlag())
  54. {
  55. #if 0
  56. if ((dwImeCompatFlags & IMECOMPAT_AIMM_TRIDENT55) && CicContext.m_fHanjaReConversion.IsSetFlag())
  57. CicContext.m_fHanjaRequested.SetFlag();
  58. #endif
  59. return S_OK;
  60. }
  61. //
  62. // Clear the contents of candidate list
  63. //
  64. imc.ClearCand();
  65. TRANSMSG msg;
  66. if (InterimStr) {
  67. hr = _MakeInterimData(imc,
  68. InterimStr,
  69. &msg.lParam);
  70. }
  71. else {
  72. hr = _MakeCompositionData(imc,
  73. CompStr, CompAttr, CompClause,
  74. CompCursorPos, CompDeltaStart,
  75. CompGuid,
  76. CompReadStr, CompReadAttr, CompReadClause,
  77. ResultStr, ResultClause,
  78. ResultReadStr, ResultReadClause,
  79. &msg.lParam,
  80. lpbBufferOverflow);
  81. }
  82. if ( hr == S_OK || // In case of valid dwCompSize in the CCompStrFactory::CreateCompositionString
  83. (hr == S_FALSE && CicContext.m_fStartComposition.IsSetFlag())
  84. // In case of empty dwCompSize but still m_fStartComposition
  85. ) {
  86. //
  87. // Is available compstr/attr/clause, compread, result or resultread ?
  88. //
  89. bool fNoCompResultData = false;
  90. if (! (msg.lParam & (GCS_COMP | GCS_COMPREAD | GCS_RESULT | GCS_RESULTREAD))) {
  91. DebugMsg(TF_GENERAL, TEXT("EditCompositionString::SetString: No data in compstr, compread, result or resultread."));
  92. fNoCompResultData = true;
  93. if (CicContext.m_fStartComposition.IsResetFlag()) {
  94. DebugMsg(TF_ERROR, TEXT("EditCompositionString::SetString: No send WM_IME_STARTCOMPOSITION yet."));
  95. return S_FALSE;
  96. }
  97. }
  98. #if 0
  99. //
  100. // New Trident(5.5 & 6.0) had a bug to convert Hanja.
  101. // So _GenerateHanja() funtion try to generate message like as Korean
  102. // legacy IME behavior.
  103. //
  104. // Send WM_IME_ENDCOMPOSITION and then WM_IME_COMPOSITION GCS_RESULT msg.
  105. //
  106. if ((dwImeCompatFlags & IMECOMPAT_AIMM_TRIDENT55) && CicContext.m_fHanjaRequested.IsSetFlag() &&
  107. !fNoCompResultData && (msg.lParam & GCS_RESULT))
  108. {
  109. LANGID langid = LANG_NEUTRAL;
  110. //
  111. // TLS doesn't inherit in edit session.
  112. //
  113. TLS* ptls = TLS::GetTLS();
  114. if (ptls != NULL)
  115. {
  116. CicProfile* _pProfile = ptls->GetCicProfile();
  117. if (_pProfile != NULL)
  118. {
  119. _pProfile->GetLangId(&langid);
  120. }
  121. }
  122. CicContext.m_fHanjaRequested.ResetFlag();
  123. if (PRIMARYLANGID(langid) == LANG_KOREAN)
  124. {
  125. return _GenerateKoreanComposition(imc, CicContext, ResultStr);
  126. }
  127. }
  128. CicContext.m_fHanjaRequested.ResetFlag();
  129. #else
  130. LANGID langid = LANG_NEUTRAL;
  131. //
  132. // TLS doesn't inherit in edit session.
  133. //
  134. TLS* ptls = TLS::GetTLS();
  135. if (ptls != NULL)
  136. {
  137. CicProfile* _pProfile = ptls->GetCicProfile();
  138. if (_pProfile != NULL)
  139. {
  140. _pProfile->GetLangId(&langid);
  141. }
  142. }
  143. if (PRIMARYLANGID(langid) == LANG_KOREAN &&
  144. !fNoCompResultData && (msg.lParam & GCS_RESULT))
  145. {
  146. if (_GenerateKoreanComposition(imc, CicContext, ResultStr) == S_OK)
  147. {
  148. return S_OK;
  149. }
  150. }
  151. #endif
  152. //
  153. // set private input context
  154. //
  155. bool fSetStartComp = false;
  156. if (CicContext.m_fStartComposition.IsResetFlag()) {
  157. CicContext.m_fStartComposition.SetFlag();
  158. TRANSMSG start_msg;
  159. start_msg.message = WM_IME_STARTCOMPOSITION;
  160. start_msg.wParam = (WPARAM) 0;
  161. start_msg.lParam = (LPARAM) 0;
  162. if (CicContext.m_pMessageBuffer) {
  163. CicContext.m_pMessageBuffer->SetData(start_msg);
  164. fSetStartComp = true;
  165. }
  166. }
  167. if (! fNoCompResultData) {
  168. msg.message = WM_IME_COMPOSITION;
  169. IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
  170. if (msg.lParam & GCS_RESULT)
  171. {
  172. msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
  173. if (PRIMARYLANGID(langid) == LANG_KOREAN &&
  174. msg.lParam & GCS_RESULTSTR)
  175. {
  176. TRANSMSG comp_result_msg;
  177. comp_result_msg.message = msg.message;
  178. comp_result_msg.wParam = msg.wParam;
  179. comp_result_msg.lParam = GCS_RESULTSTR;
  180. //
  181. // Only set GCS_RESULTSTR for compatibility(#487046).
  182. //
  183. if (CicContext.m_pMessageBuffer)
  184. CicContext.m_pMessageBuffer->SetData(comp_result_msg);
  185. msg.lParam &= ~GCS_RESULTSTR;
  186. //
  187. // Send another composition string message.
  188. //
  189. if (msg.lParam & GCS_COMPSTR)
  190. msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwCompStrOffset));
  191. }
  192. }
  193. else
  194. {
  195. msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwCompStrOffset));
  196. }
  197. if (CicContext.m_pMessageBuffer) {
  198. CicContext.m_pMessageBuffer->SetData(msg);
  199. //
  200. // Internal notification to UI window
  201. // When receive this msg in UI wnd, then calls QueryCharPos().
  202. //
  203. if (fSetStartComp) {
  204. TRANSMSG notify_msg;
  205. notify_msg.message = WM_IME_NOTIFY;
  206. notify_msg.wParam = (WPARAM)WM_IME_STARTCOMPOSITION;
  207. notify_msg.lParam = 0;
  208. CicContext.m_pMessageBuffer->SetData(notify_msg);
  209. }
  210. }
  211. }
  212. else {
  213. msg.message = WM_IME_COMPOSITION;
  214. if ((PRIMARYLANGID(langid) != LANG_JAPANESE))
  215. {
  216. msg.wParam = (WPARAM)VK_ESCAPE;
  217. msg.lParam = (LPARAM)(GCS_COMPREAD | GCS_COMP | GCS_CURSORPOS | GCS_DELTASTART);
  218. }
  219. else
  220. {
  221. //
  222. // #509247
  223. //
  224. // Some apps don't accept lParam without compstr in hIMC.
  225. //
  226. msg.wParam = 0;
  227. msg.lParam = 0;
  228. }
  229. if (CicContext.m_pMessageBuffer)
  230. CicContext.m_pMessageBuffer->SetData(msg);
  231. }
  232. if ((ResultStr && ResultStr->GetSize() && !(msg.lParam & GCS_COMP))
  233. || fNoCompResultData) {
  234. //
  235. // We're ending the composition
  236. //
  237. CicContext.m_fStartComposition.ResetFlag();
  238. TRANSMSG end_msg;
  239. end_msg.message = WM_IME_ENDCOMPOSITION;
  240. end_msg.wParam = (WPARAM) 0;
  241. end_msg.lParam = (LPARAM) 0;
  242. if (CicContext.m_pMessageBuffer) {
  243. CicContext.m_pMessageBuffer->SetData(end_msg);
  244. //
  245. // Internal notification to UI window
  246. // When receive this msg in UI wnd, then clear QueryCharPos's flag.
  247. //
  248. TRANSMSG notify_msg;
  249. notify_msg.message = WM_IME_NOTIFY;
  250. notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
  251. notify_msg.lParam = 0;
  252. CicContext.m_pMessageBuffer->SetData(notify_msg);
  253. if (CicContext.m_fInProcessKey.IsSetFlag())
  254. CicContext.m_fGeneratedEndComposition.SetFlag();
  255. }
  256. }
  257. #ifdef DEBUG
  258. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  259. #endif
  260. #if 0
  261. // Move to editses.cpp
  262. if (fGenerateMessage) {
  263. CicContext.GenerateMessage(imc);
  264. }
  265. #endif
  266. hr = S_OK;
  267. //
  268. // Update the previous result string cache.
  269. //
  270. CicContext.UpdatePrevResultStr(imc);
  271. }
  272. return hr;
  273. }
  274. //
  275. // Make composition string data in the IMCCLock<_COMPOSITIONSTRING> comp.
  276. //
  277. HRESULT
  278. EditCompositionString::_MakeCompositionData(
  279. IMCLock& imc,
  280. CWCompString* CompStr,
  281. CWCompAttribute* CompAttr,
  282. CWCompClause* CompClause,
  283. CWCompCursorPos* CompCursorPos,
  284. CWCompDeltaStart* CompDeltaStart,
  285. CWCompTfGuidAtom* CompGuid,
  286. CWCompString* CompReadStr,
  287. CWCompAttribute* CompReadAttr,
  288. CWCompClause* CompReadClause,
  289. CWCompString* ResultStr,
  290. CWCompClause* ResultClause,
  291. CWCompString* ResultReadStr,
  292. CWCompClause* ResultReadClause,
  293. OUT LPARAM* lpdwFlag,
  294. OUT BOOL* lpbBufferOverflow
  295. )
  296. {
  297. DebugMsg(TF_FUNC, TEXT("EditCompositionString::MakeCompositionData"));
  298. *lpdwFlag = (LPARAM) 0;
  299. HRESULT hr;
  300. CCompStrFactory compstrfactory(imc->hCompStr);
  301. if (FAILED(hr=compstrfactory.GetResult()))
  302. return hr;
  303. hr = compstrfactory.CreateCompositionString(CompStr,
  304. CompAttr,
  305. CompClause,
  306. CompGuid,
  307. CompReadStr,
  308. CompReadAttr,
  309. CompReadClause,
  310. ResultStr,
  311. ResultClause,
  312. ResultReadStr,
  313. ResultReadClause
  314. );
  315. if (FAILED(hr))
  316. return hr;
  317. //
  318. // Composition string
  319. //
  320. if (lpbBufferOverflow != NULL)
  321. *lpbBufferOverflow = FALSE;
  322. if (CompStr && CompStr->GetSize()) {
  323. #if 0
  324. /*
  325. * If composition string length over the buffer of COMPOSITIONSTRING.compstr[NMAXKEY],
  326. * then we want to finalize this composition string.
  327. */
  328. if ((*comp)->dwCompStrLen >= NMAXKEY) {
  329. if (lpbBufferOverflow != NULL)
  330. *lpbBufferOverflow = TRUE;
  331. //
  332. // Clear compsition string length.
  333. //
  334. (*comp)->dwCompStrLen = 0;
  335. //
  336. // Make result string.
  337. //
  338. (*comp)->dwResultStrLen = NMAXKEY;
  339. CompStr->ReadCompData((*comp)->W.resultstr, ARRAYSIZE((*comp)->W.resultstr));
  340. *lpdwFlag |= (LPARAM) GCS_RESULTSTR;
  341. }
  342. else
  343. #endif
  344. {
  345. hr = compstrfactory.WriteData<CWCompString, WCHAR>(*CompStr,
  346. &compstrfactory->dwCompStrLen,
  347. &compstrfactory->dwCompStrOffset
  348. );
  349. if (SUCCEEDED(hr))
  350. *lpdwFlag |= (LPARAM) GCS_COMPSTR;
  351. else
  352. goto Exit;
  353. }
  354. }
  355. if ((lpbBufferOverflow == NULL) ||
  356. (lpbBufferOverflow != NULL && (! *lpbBufferOverflow))) {
  357. //
  358. // Compoition attribute
  359. //
  360. if (CompAttr && CompAttr->GetSize()) {
  361. hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(*CompAttr,
  362. &compstrfactory->dwCompAttrLen,
  363. &compstrfactory->dwCompAttrOffset
  364. );
  365. if (SUCCEEDED(hr))
  366. *lpdwFlag |= (LPARAM) GCS_COMPATTR;
  367. else
  368. goto Exit;
  369. }
  370. //
  371. // Compoition clause
  372. //
  373. if (CompClause && CompClause->GetSize()) {
  374. hr = compstrfactory.WriteData<CWCompClause, DWORD>(*CompClause,
  375. &compstrfactory->dwCompClauseLen,
  376. &compstrfactory->dwCompClauseOffset
  377. );
  378. compstrfactory->dwCompClauseLen *= sizeof(DWORD);
  379. if (SUCCEEDED(hr))
  380. *lpdwFlag |= (LPARAM) GCS_COMPCLAUSE;
  381. else
  382. goto Exit;
  383. }
  384. //
  385. // Composition Reading string
  386. //
  387. if (CompReadStr && CompReadStr->GetSize()) {
  388. hr = compstrfactory.WriteData<CWCompString, WCHAR>(*CompReadStr,
  389. &compstrfactory->dwCompReadStrLen,
  390. &compstrfactory->dwCompReadStrOffset
  391. );
  392. if (SUCCEEDED(hr))
  393. *lpdwFlag |= (LPARAM) GCS_COMPREADSTR;
  394. else
  395. goto Exit;
  396. }
  397. //
  398. // Compoition Reading attribute
  399. //
  400. if (CompReadAttr && CompReadAttr->GetSize()) {
  401. hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(*CompReadAttr,
  402. &compstrfactory->dwCompReadAttrLen,
  403. &compstrfactory->dwCompReadAttrOffset
  404. );
  405. if (SUCCEEDED(hr))
  406. *lpdwFlag |= (LPARAM) GCS_COMPREADATTR;
  407. else
  408. goto Exit;
  409. }
  410. //
  411. // Composition Reading clause
  412. //
  413. if (CompReadClause && CompReadClause->GetSize()) {
  414. hr = compstrfactory.WriteData<CWCompClause, DWORD>(*CompReadClause,
  415. &compstrfactory->dwCompReadClauseLen,
  416. &compstrfactory->dwCompReadClauseOffset
  417. );
  418. compstrfactory->dwCompReadClauseLen *= sizeof(DWORD);
  419. if (SUCCEEDED(hr))
  420. *lpdwFlag |= (LPARAM) GCS_COMPREADCLAUSE;
  421. else
  422. goto Exit;
  423. }
  424. //
  425. // Result String
  426. //
  427. if (ResultStr && ResultStr->GetSize()) {
  428. hr = compstrfactory.WriteData<CWCompString, WCHAR>(*ResultStr,
  429. &compstrfactory->dwResultStrLen,
  430. &compstrfactory->dwResultStrOffset
  431. );
  432. if (SUCCEEDED(hr))
  433. *lpdwFlag |= (LPARAM) GCS_RESULTSTR;
  434. else
  435. goto Exit;
  436. }
  437. //
  438. // Result clause
  439. //
  440. if (ResultClause && ResultClause->GetSize()) {
  441. hr = compstrfactory.WriteData<CWCompClause, DWORD>(*ResultClause,
  442. &compstrfactory->dwResultClauseLen,
  443. &compstrfactory->dwResultClauseOffset
  444. );
  445. compstrfactory->dwResultClauseLen *= sizeof(DWORD);
  446. if (SUCCEEDED(hr))
  447. *lpdwFlag |= (LPARAM) GCS_RESULTCLAUSE;
  448. else
  449. goto Exit;
  450. }
  451. //
  452. // Result Reading string
  453. //
  454. if (ResultReadStr && ResultReadStr->GetSize()) {
  455. hr = compstrfactory.WriteData<CWCompString, WCHAR>(*ResultReadStr,
  456. &compstrfactory->dwResultReadStrLen,
  457. &compstrfactory->dwResultReadStrOffset
  458. );
  459. if (SUCCEEDED(hr))
  460. *lpdwFlag |= (LPARAM) GCS_RESULTREADSTR;
  461. else
  462. goto Exit;
  463. }
  464. //
  465. // Result Reading clause
  466. //
  467. if (ResultReadClause && ResultReadClause->GetSize()) {
  468. hr = compstrfactory.WriteData<CWCompClause, DWORD>(*ResultReadClause,
  469. &compstrfactory->dwResultReadClauseLen,
  470. &compstrfactory->dwResultReadClauseOffset
  471. );
  472. compstrfactory->dwResultReadClauseLen *= sizeof(DWORD);
  473. if (SUCCEEDED(hr))
  474. *lpdwFlag |= (LPARAM) GCS_RESULTREADCLAUSE;
  475. else
  476. goto Exit;
  477. }
  478. //
  479. // TfGuidAtom
  480. //
  481. if (CompGuid && CompGuid->GetSize()) {
  482. hr = compstrfactory.MakeGuidMapAttribute(CompGuid, CompAttr);
  483. if (SUCCEEDED(hr))
  484. {
  485. // set INIT_GUID_ATOM flag in the fdwInit.
  486. imc->fdwInit |= INIT_GUID_ATOM;
  487. }
  488. else
  489. goto Exit;
  490. }
  491. }
  492. //
  493. // Composition Cursor Position
  494. //
  495. if (CompCursorPos && CompCursorPos->GetSize()) {
  496. CompCursorPos->ReadCompData(&compstrfactory->dwCursorPos, 1);
  497. *lpdwFlag |= (LPARAM) GCS_CURSORPOS;
  498. }
  499. //
  500. // Delta Start
  501. //
  502. if (CompDeltaStart && CompDeltaStart->GetSize()) {
  503. CompDeltaStart->ReadCompData(&compstrfactory->dwDeltaStart, 1);
  504. *lpdwFlag |= (LPARAM) GCS_DELTASTART;
  505. }
  506. Exit:
  507. //
  508. // Copy back hCompStr to the Input Context
  509. //
  510. imc->hCompStr = compstrfactory.GetHandle();
  511. return hr;
  512. }
  513. //
  514. // Make interim string data in the IMCCLock<_COMPOSITIONSTRING> comp.
  515. //
  516. HRESULT
  517. EditCompositionString::_MakeInterimData(
  518. IMCLock& imc,
  519. CWInterimString* InterimStr,
  520. LPARAM* lpdwFlag
  521. )
  522. {
  523. DebugMsg(TF_FUNC, TEXT("EditCompositionString::MakeInterimData"));
  524. *lpdwFlag = (LPARAM) 0;
  525. //
  526. // Interim character and result string
  527. //
  528. HRESULT hr;
  529. CCompStrFactory compstrfactory(imc->hCompStr);
  530. if (FAILED(hr=compstrfactory.GetResult()))
  531. return hr;
  532. hr = compstrfactory.CreateCompositionString(InterimStr);
  533. if (FAILED(hr))
  534. return hr;
  535. //
  536. // Result string
  537. //
  538. if (InterimStr && InterimStr->GetSize()) {
  539. hr = compstrfactory.WriteData<CWInterimString, WCHAR>(*InterimStr,
  540. &compstrfactory->dwResultStrLen,
  541. &compstrfactory->dwResultStrOffset
  542. );
  543. *lpdwFlag |= (LPARAM) GCS_RESULTSTR;
  544. }
  545. //
  546. // Composition string (Interim character)
  547. // Compoition attribute
  548. //
  549. CWCompString ch;
  550. CWCompAttribute attr;
  551. InterimStr->ReadInterimChar(&ch, &attr);
  552. if (ch.GetSize() && ch.GetAt(0)) {
  553. hr = compstrfactory.WriteData<CWCompString, WCHAR>(ch,
  554. &compstrfactory->dwCompStrLen,
  555. &compstrfactory->dwCompStrOffset
  556. );
  557. *lpdwFlag |= (LPARAM) GCS_COMPSTR;
  558. hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(attr,
  559. &compstrfactory->dwCompAttrLen,
  560. &compstrfactory->dwCompAttrOffset
  561. );
  562. *lpdwFlag |= (LPARAM) GCS_COMPATTR;
  563. *lpdwFlag |= (LPARAM) CS_INSERTCHAR | CS_NOMOVECARET;
  564. }
  565. //
  566. // Copy back hCompStr to the Input Context
  567. //
  568. imc->hCompStr = compstrfactory.GetHandle();
  569. return hr;
  570. }
  571. //
  572. // Generate WM_IME_ENDCOMPOSITION and WM_IME_COMPOSITION message for
  573. // Trident 5.5 version. Since Trident 5.5 always expect WM_IME_ENDCOMPOSITION
  574. // first in case of Hanja conversion.
  575. //
  576. HRESULT
  577. EditCompositionString::_GenerateKoreanComposition(
  578. IMCLock& imc,
  579. CicInputContext& CicContext,
  580. CWCompString* ResultStr)
  581. {
  582. HRESULT hr = S_FALSE;
  583. DWORD dwImeCompatFlags = ImmGetAppCompatFlags(NULL);
  584. BOOL fEndCompFirst = FALSE;
  585. if (!MsimtfIsWindowFiltered(::GetFocus()) ||
  586. (dwImeCompatFlags & IMECOMPAT_AIMM12_TRIDENT))
  587. {
  588. fEndCompFirst = TRUE;
  589. }
  590. if (ResultStr && ResultStr->GetSize())
  591. {
  592. if (fEndCompFirst)
  593. {
  594. //
  595. // We're ending the composition
  596. //
  597. CicContext.m_fStartComposition.ResetFlag();
  598. TRANSMSG end_msg;
  599. end_msg.message = WM_IME_ENDCOMPOSITION;
  600. end_msg.wParam = (WPARAM) 0;
  601. end_msg.lParam = (LPARAM) 0;
  602. if (CicContext.m_pMessageBuffer)
  603. {
  604. CicContext.m_pMessageBuffer->SetData(end_msg);
  605. //
  606. // Internal notification to UI window
  607. // When receive this msg in UI wnd, then clear QueryCharPos's flag.
  608. //
  609. TRANSMSG notify_msg;
  610. notify_msg.message = WM_IME_NOTIFY;
  611. notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
  612. notify_msg.lParam = 0;
  613. CicContext.m_pMessageBuffer->SetData(notify_msg);
  614. if (CicContext.m_fInProcessKey.IsSetFlag())
  615. CicContext.m_fGeneratedEndComposition.SetFlag();
  616. }
  617. TRANSMSG result_msg;
  618. result_msg.message = WM_IME_COMPOSITION;
  619. result_msg.lParam = GCS_RESULTSTR;
  620. IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
  621. result_msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
  622. if (CicContext.m_pMessageBuffer)
  623. {
  624. CicContext.m_pMessageBuffer->SetData(result_msg);
  625. }
  626. }
  627. else
  628. {
  629. //
  630. // Windows Bug 716419
  631. // This is the same behavior with WinXP RTM AIMM1.2 code.
  632. //
  633. if (CicContext.m_fStartComposition.IsResetFlag()) {
  634. CicContext.m_fStartComposition.SetFlag();
  635. TRANSMSG start_msg;
  636. start_msg.message = WM_IME_STARTCOMPOSITION;
  637. start_msg.wParam = (WPARAM) 0;
  638. start_msg.lParam = (LPARAM) 0;
  639. if (CicContext.m_pMessageBuffer) {
  640. CicContext.m_pMessageBuffer->SetData(start_msg);
  641. }
  642. }
  643. TRANSMSG result_msg;
  644. result_msg.message = WM_IME_COMPOSITION;
  645. result_msg.lParam = GCS_RESULTSTR;
  646. IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
  647. result_msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
  648. if (CicContext.m_pMessageBuffer)
  649. {
  650. CicContext.m_pMessageBuffer->SetData(result_msg);
  651. }
  652. //
  653. // We're ending the composition
  654. //
  655. CicContext.m_fStartComposition.ResetFlag();
  656. TRANSMSG end_msg;
  657. end_msg.message = WM_IME_ENDCOMPOSITION;
  658. end_msg.wParam = (WPARAM) 0;
  659. end_msg.lParam = (LPARAM) 0;
  660. if (CicContext.m_pMessageBuffer)
  661. {
  662. CicContext.m_pMessageBuffer->SetData(end_msg);
  663. //
  664. // Internal notification to UI window
  665. // When receive this msg in UI wnd, then clear QueryCharPos's flag.
  666. //
  667. TRANSMSG notify_msg;
  668. notify_msg.message = WM_IME_NOTIFY;
  669. notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
  670. notify_msg.lParam = 0;
  671. CicContext.m_pMessageBuffer->SetData(notify_msg);
  672. if (CicContext.m_fInProcessKey.IsSetFlag())
  673. CicContext.m_fGeneratedEndComposition.SetFlag();
  674. }
  675. }
  676. hr = S_OK;
  677. }
  678. #ifdef DEBUG
  679. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  680. #endif
  681. #if 0
  682. // Move to editses.cpp
  683. if (fGenerateMessage)
  684. {
  685. imc.GenerateMessage();
  686. }
  687. #endif
  688. return hr;
  689. }