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.

3259 lines
94 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. uicomp.cpp
  5. Abstract:
  6. This file implements the UIComposition Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "resource.h"
  13. #include "cicspres.h"
  14. #include "uicomp.h"
  15. #include "globals.h"
  16. #include "ctxtcomp.h"
  17. #include "cic.h"
  18. #include "profile.h"
  19. #include "cregkey.h"
  20. #include "cresstr.h"
  21. #include "delay.h"
  22. #include "fontlink.h"
  23. const TCHAR c_szCUASDefCompKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\CUAS\\DefaultCompositionWindow");
  24. const TCHAR c_szLeft[] = TEXT("Left");
  25. const TCHAR c_szTop[] = TEXT("Top");
  26. //+---------------------------------------------------------------------------
  27. //
  28. // IsEALang
  29. //
  30. //+---------------------------------------------------------------------------
  31. BOOL IsEALang()
  32. {
  33. TLS* ptls = TLS::GetTLS();
  34. if (ptls)
  35. {
  36. CicProfile* pProfile;
  37. if (pProfile = ptls->GetCicProfile())
  38. {
  39. LANGID langid;
  40. pProfile->GetLangId(&langid);
  41. switch(PRIMARYLANGID(langid))
  42. {
  43. case LANG_JAPANESE:
  44. case LANG_KOREAN:
  45. case LANG_CHINESE:
  46. return TRUE;
  47. }
  48. }
  49. }
  50. return FALSE;
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Internal_PolyTextOutW
  55. //
  56. //+---------------------------------------------------------------------------
  57. BOOL
  58. Internal_PolyTextOutW(
  59. HDC hDC,
  60. CONST POLYTEXTW* pptxt,
  61. int cStrings)
  62. {
  63. for (int i=0; i < cStrings; i++)
  64. {
  65. if (! FLExtTextOutW(hDC,
  66. pptxt[i].x, pptxt[i].y,
  67. pptxt[i].uiFlags,
  68. &pptxt[i].rcl,
  69. pptxt[i].lpstr, pptxt[i].n, pptxt[i].pdx))
  70. return FALSE;
  71. }
  72. return TRUE;
  73. }
  74. //////////////////////////////////////////////////////////////////////////////
  75. //
  76. // CDefCompFrameGripper
  77. //
  78. //////////////////////////////////////////////////////////////////////////////
  79. //+---------------------------------------------------------------------------
  80. //
  81. // CDefCompFrameGripper::ctor
  82. //
  83. //+---------------------------------------------------------------------------
  84. CDefCompFrameGripper::CDefCompFrameGripper(CDefCompFrameWindow *pDefCompFrameWindow, RECT *prc, DWORD dwStyle) : CUIFGripper( pDefCompFrameWindow, prc, dwStyle)
  85. {
  86. m_pDefCompFrameWnd = pDefCompFrameWindow;
  87. }
  88. //////////////////////////////////////////////////////////////////////////////
  89. //
  90. // CCompFinalizeButton
  91. //
  92. //////////////////////////////////////////////////////////////////////////////
  93. //+---------------------------------------------------------------------------
  94. //
  95. // CCompFinalizeButton::ctor
  96. //
  97. //+---------------------------------------------------------------------------
  98. CCompFinalizeButton::CCompFinalizeButton(CCompFrameWindow *pCompFrameWindow, DWORD dwID, RECT *prc, DWORD dwStyle, DWORD dwSBtnStyle, DWORD dwSBtnShowType) : CUIFToolbarButton(pCompFrameWindow, dwID, prc, dwStyle, dwSBtnStyle, dwSBtnShowType)
  99. {
  100. m_pCompFrameWnd = pCompFrameWindow;
  101. }
  102. //+---------------------------------------------------------------------------
  103. //
  104. // CCompFinalizeButton::dtor
  105. //
  106. //+---------------------------------------------------------------------------
  107. CCompFinalizeButton::~CCompFinalizeButton()
  108. {
  109. HICON hIcon = GetIcon();
  110. if (hIcon)
  111. {
  112. DestroyIcon(hIcon);
  113. SetIcon(NULL);
  114. }
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // CCompFinalizeButton::OnLeftClick
  119. //
  120. //+---------------------------------------------------------------------------
  121. void CCompFinalizeButton::OnLeftClick()
  122. {
  123. Assert(m_pCompFrameWnd);
  124. //
  125. // complete string at lbutton click.
  126. //
  127. if (m_pCompFrameWnd->GetIMC())
  128. ImmNotifyIME(m_pCompFrameWnd->GetIMC(),
  129. NI_COMPOSITIONSTR,
  130. CPS_COMPLETE,
  131. 0);
  132. }
  133. //////////////////////////////////////////////////////////////////////////////
  134. //
  135. // CDefCompFrameWindow
  136. //
  137. //////////////////////////////////////////////////////////////////////////////
  138. //+---------------------------------------------------------------------------
  139. //
  140. // CDefCompFrameWindow::CDefCompFrameWindow
  141. //
  142. //+---------------------------------------------------------------------------
  143. CDefCompFrameWindow::CDefCompFrameWindow(HIMC hIMC, DWORD dwStyle) : CCompFrameWindow(hIMC, dwStyle)
  144. {
  145. //
  146. // get the current position from registry
  147. //
  148. LoadPosition();
  149. //
  150. // Set theme
  151. //
  152. SetActiveTheme(L"TASKBAR", TBP_BACKGROUNDBOTTOM, TS_NORMAL );
  153. }
  154. //+---------------------------------------------------------------------------
  155. //
  156. // CDefCompFrameWindow::~CDefCompFrameWindow
  157. //
  158. //+---------------------------------------------------------------------------
  159. CDefCompFrameWindow::~CDefCompFrameWindow()
  160. {
  161. //
  162. // save the current position to registry
  163. //
  164. SavePosition();
  165. }
  166. //+---------------------------------------------------------------------------
  167. //
  168. // CDefCompFrameWindow::OnSetCursor
  169. //
  170. //+---------------------------------------------------------------------------
  171. BOOL CDefCompFrameWindow::OnSetCursor( UINT uMsg, POINT pt )
  172. {
  173. //
  174. // SendMessage(WM_UICOMP_SETCURSOR) will set the cursor if pt is in
  175. // the comp str window.
  176. //
  177. if (IsWindow(m_hwndCompStr))
  178. {
  179. RECT rc;
  180. GetWindowRect(m_hwndCompStr, &rc);
  181. MyScreenToClient(NULL, &rc);
  182. if (PtInRect(&rc, pt))
  183. return TRUE;
  184. }
  185. return FALSE;
  186. }
  187. //+---------------------------------------------------------------------------
  188. //
  189. // CDefCompFrameWindow::HandleMouseMsg
  190. //
  191. //+---------------------------------------------------------------------------
  192. void CDefCompFrameWindow::HandleMouseMsg( UINT uMsg, POINT pt )
  193. {
  194. if (IsWindow(m_hwndCompStr))
  195. {
  196. RECT rc;
  197. GetWindowRect(m_hwndCompStr, &rc);
  198. MyScreenToClient(NULL, &rc);
  199. if (PtInRect(&rc, pt))
  200. SendMessage(m_hwndCompStr, WM_UICOMP_SETCURSOR, 0, 0);
  201. }
  202. CUIFWindow::HandleMouseMsg(uMsg, pt );
  203. }
  204. //+---------------------------------------------------------------------------
  205. //
  206. // CDefCompFrameWindow::Init
  207. //
  208. //+---------------------------------------------------------------------------
  209. void CDefCompFrameWindow::Init()
  210. {
  211. if (!m_pGripper)
  212. {
  213. RECT rc;
  214. ::SetRect(&rc, 0, 0, 0, 0);
  215. m_pGripper = new CDefCompFrameGripper(this, &rc, 0);
  216. m_pGripper->Initialize();
  217. AddUIObj(m_pGripper);
  218. }
  219. if (!m_pEnterButton)
  220. {
  221. RECT rc;
  222. ::SetRect(&rc, 0, 0, 0, 0);
  223. m_pEnterButton = new CCompFinalizeButton(this,
  224. 0,
  225. &rc,
  226. 0,
  227. UITBBUTTON_BUTTON,
  228. 0);
  229. m_pEnterButton->Initialize();
  230. m_pEnterButton->Init();
  231. m_pEnterButton->SetIcon(LoadSmIcon(::GetInstance(),
  232. MAKEINTRESOURCE(IDIC_ENTER_ICON)));
  233. m_pEnterButton->SetToolTip(CRStr2(IDS_ENTER_BTN_TOOLTIP));
  234. AddUIObj(m_pEnterButton);
  235. }
  236. }
  237. //+---------------------------------------------------------------------------
  238. //
  239. // OnCreate
  240. //
  241. //----------------------------------------------------------------------------
  242. void CDefCompFrameWindow::OnCreate(HWND hWnd)
  243. {
  244. //
  245. // Set Window Theme.
  246. //
  247. SetWindowTheme(hWnd, L"TASKBAR", NULL);
  248. //
  249. // Get margins of button theme.
  250. //
  251. CUIFTheme themeBtn;
  252. memset(&_marginsButton, 0, sizeof(_marginsButton));
  253. themeBtn.SetActiveTheme(L"TOOLBAR", TP_BUTTON, 0);
  254. if (SUCCEEDED(themeBtn.OpenThemeData(hWnd)))
  255. {
  256. themeBtn.GetThemeMargins(NULL, TS_NORMAL,
  257. TMT_CONTENTMARGINS,
  258. NULL, &_marginsButton);
  259. }
  260. }
  261. //+---------------------------------------------------------------------------
  262. //
  263. // OnWindowPosChanged
  264. //
  265. //----------------------------------------------------------------------------
  266. LRESULT CDefCompFrameWindow::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  267. {
  268. IMCLock imc(GetIMC());
  269. if (SUCCEEDED(imc.GetResult()))
  270. {
  271. SendMessage(imc->hWnd,
  272. WM_IME_NOTIFY,
  273. IMN_PRIVATE_ONLAYOUTCHANGE,
  274. (LPARAM)GetIMC());
  275. }
  276. return CUIFWindow::OnWindowPosChanged(hWnd, uMsg, wParam, lParam);
  277. }
  278. //+---------------------------------------------------------------------------
  279. //
  280. // CDefCompFrameWindow::SetCompStrRect
  281. //
  282. //+---------------------------------------------------------------------------
  283. void CDefCompFrameWindow::SetCompStrRect(int dx, int dy, BOOL fShow)
  284. {
  285. int x, y;
  286. int nGripperWidth = GetGripperWidth();
  287. RECT rcWnd;
  288. GetWindowRect(GetWnd(), &rcWnd);
  289. Move(rcWnd.left, rcWnd.top, dx + (DEFFRAME_LEFT_MARGIN * 3) + nGripperWidth + DEFFRAME_ENTER_BTN_CX, dy + DEFFRAME_TOP_MARGIN + DEFFRAME_BOTTOM_MARGIN);
  290. if (m_pGripper)
  291. {
  292. RECT rc;
  293. x = DEFFRAME_LEFT_MARGIN;
  294. y = DEFFRAME_TOP_MARGIN;
  295. ::SetRect(&rc,
  296. x,
  297. y,
  298. x + nGripperWidth,
  299. DEFFRAME_TOP_STR_MARGIN + dy);
  300. m_pGripper->SetRect(&rc);
  301. }
  302. if (m_pEnterButton)
  303. {
  304. RECT rc;
  305. x = DEFFRAME_LEFT_MARGIN + nGripperWidth + dx + DEFFRAME_LEFT_MARGIN;
  306. y = DEFFRAME_TOP_MARGIN;
  307. ::SetRect(&rc,
  308. x,
  309. y,
  310. x + DEFFRAME_ENTER_BTN_CX + _marginsButton.cxLeftWidth + _marginsButton.cxRightWidth,
  311. y + DEFFRAME_ENTER_BTN_CY + _marginsButton.cyTopHeight + _marginsButton.cyBottomHeight);
  312. m_pEnterButton->SetRect(&rc);
  313. }
  314. Show(fShow);
  315. x = DEFFRAME_LEFT_MARGIN + nGripperWidth;
  316. y = DEFFRAME_TOP_STR_MARGIN;
  317. ::MoveWindow(m_hwndCompStr, x, y, dx, dy, TRUE);
  318. ::ShowWindow(m_hwndCompStr, fShow ? SW_SHOWNOACTIVATE : SW_HIDE);
  319. }
  320. //+---------------------------------------------------------------------------
  321. //
  322. // GetGripperWidth
  323. //
  324. //----------------------------------------------------------------------------
  325. int CDefCompFrameWindow::GetGripperWidth()
  326. {
  327. if (m_pGripper)
  328. {
  329. if (SUCCEEDED(m_pGripper->EnsureThemeData(GetWnd())))
  330. {
  331. int nRet = -1;
  332. SIZE size;
  333. HDC hdc = GetDC(GetWnd());
  334. if (SUCCEEDED(m_pGripper->GetThemePartSize(hdc,
  335. TS_NORMAL,
  336. NULL,
  337. TS_TRUE,
  338. &size)))
  339. {
  340. nRet = size.cx + CUI_GRIPPER_THEME_MARGIN * 2;
  341. }
  342. ReleaseDC(GetWnd(), hdc);
  343. if (nRet >= 0)
  344. return nRet;
  345. }
  346. }
  347. return 5;
  348. }
  349. //+---------------------------------------------------------------------------
  350. //
  351. // SavePosition
  352. //
  353. //----------------------------------------------------------------------------
  354. void CDefCompFrameWindow::SavePosition()
  355. {
  356. CMyRegKey key;
  357. if (key.Create(HKEY_CURRENT_USER, c_szCUASDefCompKey) == S_OK)
  358. {
  359. key.SetValue((DWORD)_xWnd, c_szLeft);
  360. key.SetValue((DWORD)_yWnd, c_szTop);
  361. }
  362. }
  363. //+---------------------------------------------------------------------------
  364. //
  365. // LoadPosition
  366. //
  367. //----------------------------------------------------------------------------
  368. void CDefCompFrameWindow::LoadPosition()
  369. {
  370. CMyRegKey key;
  371. int x, y;
  372. x = 0;
  373. y = 0;
  374. if (key.Open(HKEY_CURRENT_USER, c_szCUASDefCompKey, KEY_READ) == S_OK)
  375. {
  376. DWORD dw;
  377. if (key.QueryValue(dw, c_szLeft) == S_OK)
  378. x = (int)dw;
  379. if (key.QueryValue(dw, c_szTop) == S_OK)
  380. y = (int)dw;
  381. }
  382. Move(x, y, 0, 0);
  383. }
  384. //////////////////////////////////////////////////////////////////////////////
  385. //
  386. // CCompButtonFrameWindow
  387. //
  388. //////////////////////////////////////////////////////////////////////////////
  389. //+---------------------------------------------------------------------------
  390. //
  391. // CCompButtonFrameWindow::CCompButtonFrameWindow
  392. //
  393. //+---------------------------------------------------------------------------
  394. CCompButtonFrameWindow::CCompButtonFrameWindow(HIMC hIMC, DWORD dwStyle) : CCompFrameWindow(hIMC, dwStyle)
  395. {
  396. #ifdef COMPBUTTON_TOOLBARTHEME
  397. //
  398. // Set theme
  399. //
  400. SetActiveTheme(L"TOOLBAR", TBP_BACKGROUNDBOTTOM, TS_NORMAL );
  401. #endif
  402. }
  403. //+---------------------------------------------------------------------------
  404. //
  405. // CCompButtonFrameWindow::~CCompButtonFrameWindow
  406. //
  407. //+---------------------------------------------------------------------------
  408. CCompButtonFrameWindow::~CCompButtonFrameWindow()
  409. {
  410. }
  411. //+---------------------------------------------------------------------------
  412. //
  413. // OnCreate
  414. //
  415. //----------------------------------------------------------------------------
  416. void CCompButtonFrameWindow::OnCreate(HWND hWnd)
  417. {
  418. //
  419. // Set Window Theme.
  420. //
  421. #ifdef COMPBUTTON_TOOLBARTHEME
  422. SetWindowTheme(hWnd, L"TASKBAR", NULL);
  423. #else
  424. SetWindowTheme(hWnd, L"TOOLBAR", NULL);
  425. #endif
  426. //
  427. // Get margins of button theme.
  428. //
  429. CUIFTheme themeBtn;
  430. memset(&_marginsButton, 0, sizeof(_marginsButton));
  431. themeBtn.SetActiveTheme(L"TOOLBAR", TP_BUTTON, 0);
  432. if (SUCCEEDED(themeBtn.OpenThemeData(hWnd)))
  433. {
  434. themeBtn.GetThemeMargins(NULL, TS_NORMAL,
  435. TMT_CONTENTMARGINS,
  436. NULL, &_marginsButton);
  437. }
  438. }
  439. //+---------------------------------------------------------------------------
  440. //
  441. // CCompButtonFrameWindow::Init
  442. //
  443. //+---------------------------------------------------------------------------
  444. void CCompButtonFrameWindow::Init()
  445. {
  446. if (!m_pEnterButton)
  447. {
  448. RECT rc;
  449. ::SetRect(&rc, 0, 0, 0, 0);
  450. m_pEnterButton = new CCompFinalizeButton(this,
  451. 0,
  452. &rc,
  453. 0,
  454. UITBBUTTON_BUTTON,
  455. 0);
  456. m_pEnterButton->Initialize();
  457. m_pEnterButton->Init();
  458. m_pEnterButton->SetIcon(LoadSmIcon(::GetInstance(),
  459. MAKEINTRESOURCE(IDIC_ENTER_ICON)));
  460. m_pEnterButton->SetToolTip(CRStr2(IDS_ENTER_BTN_TOOLTIP));
  461. AddUIObj(m_pEnterButton);
  462. }
  463. }
  464. //+---------------------------------------------------------------------------
  465. //
  466. // CCompButtonFrameWindow::MoveShow
  467. //
  468. //+---------------------------------------------------------------------------
  469. void CCompButtonFrameWindow::MoveShow(int x, int y, BOOL fShow)
  470. {
  471. RECT rcWnd;
  472. int cx = DEFFRAME_ENTER_BTN_CX + _marginsButton.cxLeftWidth + _marginsButton.cxRightWidth;
  473. int cy = DEFFRAME_ENTER_BTN_CY + _marginsButton.cyTopHeight + _marginsButton.cyBottomHeight;
  474. GetWindowRect(GetWnd(), &rcWnd);
  475. Move(x, y,
  476. ((COMPBTN_LEFT_MARGIN + 1) * 2) + cx,
  477. ((COMPBTN_TOP_MARGIN + 1) * 2) + cy);
  478. if (m_pEnterButton)
  479. {
  480. RECT rc;
  481. x = COMPBTN_LEFT_MARGIN;
  482. y = COMPBTN_TOP_MARGIN;
  483. ::SetRect(&rc, x, y, x + cx, x + cy);
  484. m_pEnterButton->SetRect(&rc);
  485. }
  486. Show(fShow);
  487. }
  488. //////////////////////////////////////////////////////////////////////////////
  489. //
  490. // UIComposition
  491. //
  492. //////////////////////////////////////////////////////////////////////////////
  493. //+---------------------------------------------------------------------------
  494. //
  495. // UIComposition::CompWndProc
  496. //
  497. //+---------------------------------------------------------------------------
  498. /* static */
  499. LRESULT
  500. UIComposition::CompWndProc(
  501. HWND hCompWnd,
  502. UINT uMsg,
  503. WPARAM wParam,
  504. LPARAM lParam)
  505. {
  506. switch (uMsg)
  507. {
  508. case WM_SETCURSOR:
  509. case WM_UICOMP_SETCURSOR:
  510. {
  511. UIComposition* pv = (UIComposition*)GetWindowLongPtr(hCompWnd, GWLP_USERDATA);
  512. HRESULT hr = E_FAIL;
  513. if (pv)
  514. {
  515. HWND hUIWnd = pv->GetUIWnd();
  516. if (IsWindow(hUIWnd))
  517. {
  518. HIMC hImc = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  519. IMCLock imc(hImc);
  520. if (SUCCEEDED(imc.GetResult()))
  521. {
  522. hr = pv->OnSetCursor(imc, wParam, lParam);
  523. }
  524. }
  525. }
  526. if (hr != S_OK)
  527. return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
  528. break;
  529. }
  530. case WM_PAINT:
  531. case WM_TIMER:
  532. {
  533. TLS* ptls = TLS::GetTLS();
  534. if (ptls == NULL)
  535. return 0;
  536. UIComposition* pv = (UIComposition*)GetWindowLongPtr(hCompWnd, GWLP_USERDATA);
  537. if (pv != NULL)
  538. {
  539. switch (uMsg)
  540. {
  541. case WM_PAINT:
  542. {
  543. PAINTSTRUCT ps;
  544. HDC hDC = BeginPaint(hCompWnd, &ps);
  545. HWND hUIWnd = pv->GetUIWnd();
  546. if (IsWindow(hUIWnd))
  547. {
  548. HIMC hImc = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  549. IMCLock imc(hImc);
  550. if (SUCCEEDED(imc.GetResult()))
  551. {
  552. pv->OnPaint(ptls, hCompWnd, hDC, ps, imc);
  553. }
  554. }
  555. EndPaint(hCompWnd, &ps);
  556. }
  557. break;
  558. case WM_TIMER:
  559. pv->OnTimer(hCompWnd);
  560. break;
  561. }
  562. }
  563. }
  564. break;
  565. default:
  566. return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
  567. }
  568. return 0;
  569. }
  570. //+---------------------------------------------------------------------------
  571. //
  572. // UIComposition::ctor
  573. // UIComposition::dtor
  574. //
  575. //+---------------------------------------------------------------------------
  576. UIComposition::UIComposition(HWND hUIWnd)
  577. {
  578. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  579. {
  580. m_CompWnd[i].hCompWnd = NULL;
  581. m_CompWnd[i].fDefaultCompWnd = FALSE;
  582. }
  583. m_DefCompWnd.hCompWnd = NULL;
  584. m_DefCompWnd.fDefaultCompWnd = TRUE;
  585. m_hFontLevel1 = NULL;
  586. m_hFontLevel2 = NULL;
  587. m_isc = 0;
  588. m_hUIWnd = hUIWnd;
  589. m_lpszCompStr = NULL;
  590. m_nCompStr = 0;
  591. m_bTimerCOMPOSITION = FALSE;
  592. }
  593. UIComposition::~UIComposition()
  594. {
  595. DestroyCompositionWindow();
  596. if (m_hFontLevel1)
  597. DeleteObject(m_hFontLevel1);
  598. if (m_hFontLevel2)
  599. DeleteObject(m_hFontLevel2);
  600. m_hFontLevel1 = NULL;
  601. m_hFontLevel2 = NULL;
  602. if (m_lpszCompStr)
  603. {
  604. cicMemFree(m_lpszCompStr);
  605. m_lpszCompStr = NULL;
  606. }
  607. m_nCompStr = 0;
  608. }
  609. //+---------------------------------------------------------------------------
  610. //
  611. // UIComposition::OnCreate
  612. //
  613. //+---------------------------------------------------------------------------
  614. HRESULT
  615. UIComposition::OnCreate()
  616. {
  617. return S_OK;
  618. }
  619. //+---------------------------------------------------------------------------
  620. //
  621. // UIComposition::OnDestroy
  622. //
  623. //+---------------------------------------------------------------------------
  624. HRESULT
  625. UIComposition::OnDestroy()
  626. {
  627. return DestroyCompositionWindow();
  628. }
  629. //+---------------------------------------------------------------------------
  630. //
  631. // UIComposition::OnImeSetContext
  632. //
  633. //+---------------------------------------------------------------------------
  634. HRESULT
  635. UIComposition::OnImeSetContext(
  636. IMCLock& imc,
  637. HWND hUIWnd,
  638. BOOL fActivate,
  639. DWORD isc)
  640. {
  641. HRESULT hr = S_OK;
  642. if (fActivate)
  643. {
  644. if (SUCCEEDED(imc.GetResult()))
  645. {
  646. //
  647. // #598648
  648. //
  649. // Powerpnt XP does not clear ISC_SHOWUICOMPOSITIONWINDOW.
  650. // even though it is AIMM filtered window. It must be Level3.
  651. //
  652. BOOL fFilter = MsimtfIsWindowFiltered(imc->hWnd);
  653. if ((isc & ISC_SHOWUICOMPOSITIONWINDOW) && fFilter)
  654. {
  655. isc &= ~ISC_SHOWUICOMPOSITIONWINDOW;
  656. //
  657. // 616323
  658. //
  659. // Trident can not handle the existing composition string.
  660. //
  661. // if hIMC already has a composition string before the focus
  662. // goes to the trident. We need to clear the comp string.
  663. // Trident can not start the composition string in the middle
  664. // of composing.
  665. //
  666. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  667. if (FAILED(hr=comp.GetResult()))
  668. {
  669. DebugMsg(TF_ERROR, TEXT("UIComposition::OnImeSetContext. comp==NULL"));
  670. return hr;
  671. }
  672. if (comp->dwCompStrLen)
  673. {
  674. DWORD dwImeCompatFlags = ImmGetAppCompatFlags(NULL);
  675. if (dwImeCompatFlags & IMECOMPAT_AIMM12_TRIDENT)
  676. {
  677. IMCCLock<CTFIMECONTEXT> imc_ctfime(imc->hCtfImeContext);
  678. if (FAILED(imc_ctfime.GetResult()))
  679. {
  680. return E_FAIL;
  681. }
  682. CicInputContext* _pCicContext = imc_ctfime->m_pCicContext;
  683. if (_pCicContext == NULL)
  684. {
  685. DebugMsg(TF_ERROR, TEXT("UIComposition::OnImeSetContext. _pCicContext==NULL"));
  686. return E_FAIL;
  687. }
  688. _pCicContext->EscbCompComplete(imc);
  689. }
  690. }
  691. }
  692. }
  693. m_isc = isc;
  694. UpdateShowCompWndFlag(imc, NULL);
  695. }
  696. m_fActive = fActivate;
  697. return hr;
  698. }
  699. //+---------------------------------------------------------------------------
  700. //
  701. // UIComposition::OnImeSetContextAfter
  702. //
  703. //+---------------------------------------------------------------------------
  704. HRESULT
  705. UIComposition::OnImeSetContextAfter(
  706. IMCLock& imc)
  707. {
  708. if ((m_pDefCompFrameWnd && IsWindow(m_pDefCompFrameWnd->GetWnd())) ||
  709. IsWindow(m_CompWnd[FIRST_WINDOW].hCompWnd)
  710. )
  711. {
  712. HRESULT hr;
  713. //
  714. // Validation check of imc.
  715. // Because CIMEUIWindowHandler::ImeUIWndProcWorker doesn't check.
  716. //
  717. hr = imc.GetResult();
  718. //
  719. // we show the def / level2 comp window,
  720. //
  721. // - if imc is valid.
  722. // - if composition window is on Level1 or 2.
  723. // - if it is not level 3,
  724. // (m_isc does not have ISC_SHOWUICOMPOSITIONWINDOW)
  725. // - if it is active.
  726. // - if there is a composition string.
  727. //
  728. IME_UIWND_STATE uiwndState;
  729. if (SUCCEEDED(hr) &&
  730. ((uiwndState = GetLevelFromIMC(imc)) == IME_UIWND_LEVEL1 || uiwndState == IME_UIWND_LEVEL2) &&
  731. (m_isc & ISC_SHOWUICOMPOSITIONWINDOW) &&
  732. m_fActive)
  733. {
  734. DWORD dwCompLen = 0;
  735. UpdateShowCompWndFlag(imc, &dwCompLen);
  736. if (uiwndState == IME_UIWND_LEVEL1)
  737. {
  738. ShowWindow(m_pDefCompFrameWnd->GetWnd(),
  739. m_fShowCompWnd.IsSetFlag() ? SW_SHOWNOACTIVATE : SW_HIDE);
  740. }
  741. else if ((uiwndState == IME_UIWND_LEVEL2) && (m_fShowCompWnd.IsResetFlag()))
  742. {
  743. for (int i = 0; i < sizeof(m_CompWnd)/sizeof(COMPWND) && dwCompLen > 0; i++)
  744. {
  745. m_CompWnd[i].caret.HideCaret();
  746. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  747. }
  748. }
  749. }
  750. else
  751. {
  752. //
  753. // Both Level 1 / Level 2 window hide.
  754. //
  755. ShowWindow(m_pDefCompFrameWnd->GetWnd(), SW_HIDE);
  756. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  757. {
  758. m_CompWnd[i].caret.HideCaret();
  759. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  760. }
  761. }
  762. }
  763. else
  764. {
  765. m_isc &= ~ISC_SHOWUICOMPOSITIONWINDOW;
  766. }
  767. return S_OK;
  768. }
  769. //+---------------------------------------------------------------------------
  770. //
  771. // UIComposition::OnImeSelect
  772. //
  773. //+---------------------------------------------------------------------------
  774. HRESULT
  775. UIComposition::OnImeSelect(
  776. BOOL fSelect)
  777. {
  778. return S_OK;
  779. }
  780. //+---------------------------------------------------------------------------
  781. //
  782. // UIComposition::OnImeStartComposition
  783. //
  784. //+---------------------------------------------------------------------------
  785. HRESULT
  786. UIComposition::OnImeStartComposition(
  787. IMCLock& imc,
  788. HWND hUIWnd)
  789. {
  790. HRESULT hr;
  791. if (SUCCEEDED(hr = UpdateFont(imc)))
  792. {
  793. TEXTMETRIC tm;
  794. HDC hDC;
  795. HFONT hFontOrg;
  796. hDC = GetDC(m_DefCompWnd.hCompWnd);
  797. // get FontHeight for level1.
  798. hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  799. GetTextMetrics(hDC, &tm);
  800. m_tmFontHeightLevel1 = tm.tmHeight;
  801. // get FontHeight for level2.
  802. SelectObject(hDC, m_hFontLevel2);
  803. GetTextMetrics(hDC, &tm);
  804. m_tmFontHeightLevel2 = tm.tmHeight;
  805. SelectObject(hDC, hFontOrg);
  806. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  807. if (!imc.UseVerticalCompWindow())
  808. {
  809. m_caret_size.cx = CARET_WIDTH;
  810. m_caret_size.cy = tm.tmHeight + LINE_BOLD_WIDTH;
  811. }
  812. else
  813. {
  814. m_caret_size.cx = tm.tmHeight + LINE_BOLD_WIDTH;
  815. m_caret_size.cy = CARET_WIDTH;
  816. }
  817. if (SUCCEEDED(hr = CreateCompositionWindow(imc, hUIWnd)))
  818. {
  819. UpdateCompositionRect(imc);
  820. }
  821. }
  822. return hr;
  823. }
  824. //+---------------------------------------------------------------------------
  825. //
  826. // UIComposition::OnImeCompositionUpdate
  827. //
  828. //+---------------------------------------------------------------------------
  829. HRESULT
  830. UIComposition::OnImeCompositionUpdate(IMCLock& imc)
  831. {
  832. m_isc |= ISC_SHOWUICOMPOSITIONWINDOW; // arrive WM_IME_COMPOSITION in IME UI window,
  833. // IME should draw comp wnd.
  834. return UpdateShowCompWndFlag(imc, NULL);
  835. }
  836. //+---------------------------------------------------------------------------
  837. //
  838. // UIComposition::OnImeCompositionUpdateByTimer
  839. //
  840. //+---------------------------------------------------------------------------
  841. HRESULT
  842. UIComposition::OnImeCompositionUpdateByTimer(IMCLock& imc)
  843. {
  844. return UpdateCompositionRect(imc);
  845. }
  846. //+---------------------------------------------------------------------------
  847. //
  848. // UIComposition::OnImeEndComposition
  849. //
  850. //+---------------------------------------------------------------------------
  851. HRESULT
  852. UIComposition::OnImeEndComposition()
  853. {
  854. m_isc = 0;
  855. return DestroyCompositionWindow();
  856. }
  857. //+---------------------------------------------------------------------------
  858. //
  859. // UIComposition::CreateCompositionWindow
  860. //
  861. //+---------------------------------------------------------------------------
  862. HRESULT
  863. UIComposition::CreateCompositionWindow(
  864. IMCLock& imc,
  865. HWND hUIWnd)
  866. {
  867. HRESULT hr;
  868. if (SUCCEEDED(hr=imc.GetResult()) &&
  869. IsWindow(hUIWnd) &&
  870. m_fInitUIComp.IsResetFlag())
  871. {
  872. //
  873. // Create three composition windows
  874. //
  875. // m_CompWnd[0].hCompWnd is first composition window rectangle.
  876. // m_CompWnd[1].hCompWnd is middle composition window rectangle.
  877. // m_CompWnd[2].hCompWnd is last composition window rectangle.
  878. //
  879. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  880. {
  881. Assert(!m_CompWnd[i].hCompWnd);
  882. m_CompWnd[i].hCompWnd = CreateWindowExW(0,
  883. s_szCompClassName,
  884. NULL,
  885. WS_POPUP | WS_DISABLED,
  886. 0, 0, 0, 0,
  887. hUIWnd, // Parent Window Handle.
  888. NULL,
  889. GetInstance(),
  890. NULL);
  891. if (m_CompWnd[i].hCompWnd == NULL)
  892. {
  893. DestroyCompositionWindow();
  894. DebugMsg(TF_ERROR, TEXT("UIComposition::Create. m_CompWnd[].hCompWnd==NULL"));
  895. return E_OUTOFMEMORY;
  896. }
  897. SetWindowLongPtr(m_CompWnd[i].hCompWnd, GWLP_USERDATA, (LONG_PTR)this);
  898. switch (i)
  899. {
  900. case FIRST_WINDOW:
  901. SetWindowLongPtr(m_CompWnd[FIRST_WINDOW].hCompWnd, COMPUI_WINDOW_INDEX, FIRST_WINDOW);
  902. break;
  903. case MIDDLE_WINDOW:
  904. SetWindowLongPtr(m_CompWnd[MIDDLE_WINDOW].hCompWnd, COMPUI_WINDOW_INDEX, MIDDLE_WINDOW);
  905. break;
  906. case LAST_WINDOW:
  907. SetWindowLongPtr(m_CompWnd[LAST_WINDOW].hCompWnd, COMPUI_WINDOW_INDEX, LAST_WINDOW);
  908. break;
  909. }
  910. m_CompWnd[i].caret.CreateCaret(m_CompWnd[i].hCompWnd, m_caret_size);
  911. }
  912. if (FAILED(CreateCompButtonWnd(hUIWnd, (HIMC)imc)))
  913. {
  914. DestroyCompositionWindow();
  915. DebugMsg(TF_ERROR, TEXT("UIComposition::Create. m_pCompButtonFrameWindow==NULL"));
  916. return E_OUTOFMEMORY;
  917. }
  918. if (FAILED(CreateDefFrameWnd(hUIWnd, (HIMC)imc)))
  919. {
  920. DestroyCompositionWindow();
  921. DebugMsg(TF_ERROR, TEXT("UIComposition::Create. m_pDefFrameWindow==NULL"));
  922. return E_OUTOFMEMORY;
  923. }
  924. //
  925. // Create default composition window
  926. //
  927. Assert(!m_DefCompWnd.hCompWnd);
  928. m_DefCompWnd.hCompWnd = CreateWindowExW(WS_EX_CLIENTEDGE,
  929. s_szCompClassName,
  930. NULL,
  931. WS_CHILD | WS_DISABLED,
  932. 0, 0, 0, 0,
  933. m_pDefCompFrameWnd->GetWnd(),
  934. NULL,
  935. GetInstance(),
  936. NULL);
  937. if (m_DefCompWnd.hCompWnd == NULL)
  938. {
  939. DestroyCompositionWindow();
  940. DebugMsg(TF_ERROR, TEXT("UIComposition::Create. m_DefCompWnd.hCompWnd==NULL"));
  941. return E_OUTOFMEMORY;
  942. }
  943. m_pDefCompFrameWnd->SetCompStrWnd(m_DefCompWnd.hCompWnd);
  944. SetWindowLongPtr(m_DefCompWnd.hCompWnd, GWLP_USERDATA, (LONG_PTR)this);
  945. SetWindowLongPtr(m_DefCompWnd.hCompWnd, COMPUI_WINDOW_INDEX, DEFAULT_WINDOW);
  946. m_DefCompWnd.caret.CreateCaret(m_DefCompWnd.hCompWnd, m_caret_size);
  947. //
  948. // Final: set flag
  949. //
  950. m_fInitUIComp.SetFlag();
  951. }
  952. return hr;
  953. }
  954. //+---------------------------------------------------------------------------
  955. //
  956. // UIComposition::DestroyCompositionWindow
  957. //
  958. //+---------------------------------------------------------------------------
  959. HRESULT
  960. UIComposition::DestroyCompositionWindow()
  961. {
  962. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  963. {
  964. m_CompWnd[i].caret.DestroyCaret();
  965. if (IsWindow(m_CompWnd[i].hCompWnd))
  966. {
  967. DestroyWindow(m_CompWnd[i].hCompWnd);
  968. m_CompWnd[i].poly_text.RemoveAll();
  969. }
  970. m_CompWnd[i].hCompWnd = NULL;
  971. }
  972. if (m_pCompButtonFrameWnd)
  973. {
  974. DestroyWindow(m_pCompButtonFrameWnd->GetWnd());
  975. delete m_pCompButtonFrameWnd;
  976. m_pCompButtonFrameWnd = NULL;
  977. }
  978. m_DefCompWnd.caret.DestroyCaret();
  979. if (IsWindow(m_DefCompWnd.hCompWnd))
  980. {
  981. DestroyWindow(m_DefCompWnd.hCompWnd);
  982. m_DefCompWnd.poly_text.RemoveAll();
  983. }
  984. if (m_pDefCompFrameWnd)
  985. {
  986. DestroyWindow(m_pDefCompFrameWnd->GetWnd());
  987. delete m_pDefCompFrameWnd;
  988. m_pDefCompFrameWnd = NULL;
  989. }
  990. m_DefCompWnd.hCompWnd = NULL;
  991. m_fInitUIComp.ResetFlag();
  992. return S_OK;
  993. }
  994. //+---------------------------------------------------------------------------
  995. //
  996. // UIComposition::HideCompositionWindow
  997. //
  998. //+---------------------------------------------------------------------------
  999. HRESULT
  1000. UIComposition::HideCompositionWindow()
  1001. {
  1002. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  1003. {
  1004. if (IsWindow(m_CompWnd[i].hCompWnd))
  1005. {
  1006. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  1007. }
  1008. }
  1009. if (IsWindow(m_DefCompWnd.hCompWnd))
  1010. {
  1011. ShowWindow(m_DefCompWnd.hCompWnd, SW_HIDE);
  1012. }
  1013. if (m_pDefCompFrameWnd)
  1014. m_pDefCompFrameWnd->Show(FALSE);
  1015. if (m_pCompButtonFrameWnd)
  1016. m_pCompButtonFrameWnd->Show(FALSE);
  1017. return S_OK;
  1018. }
  1019. //+---------------------------------------------------------------------------
  1020. //
  1021. // UIComposition::GetSelection
  1022. //
  1023. //+---------------------------------------------------------------------------
  1024. HRESULT
  1025. UIComposition::GetSelection(
  1026. IMCLock& imc,
  1027. LONG *pacpSelStart,
  1028. LONG *pcchSel)
  1029. {
  1030. HRESULT hr;
  1031. IMCCLock<CTFIMECONTEXT> imc_ctfime(imc->hCtfImeContext);
  1032. if (FAILED(hr=imc_ctfime.GetResult()))
  1033. {
  1034. DebugMsg(TF_ERROR, TEXT("UIComposition::OnSetCursor. imc_ctfime==NULL"));
  1035. return hr;
  1036. }
  1037. CicInputContext* _pCicContext = imc_ctfime->m_pCicContext;
  1038. if (_pCicContext == NULL)
  1039. {
  1040. DebugMsg(TF_ERROR, TEXT("UIComposition::OnSetCursor. _pCicContext==NULL"));
  1041. return hr;
  1042. }
  1043. *pacpSelStart = 0;
  1044. *pcchSel = 0;
  1045. Interface<ITfRange> Selection;
  1046. Interface<ITfRangeACP> SelectionACP;
  1047. hr = _pCicContext->EscbGetSelection(imc, &Selection);
  1048. if (hr == S_OK)
  1049. {
  1050. hr = Selection->QueryInterface(IID_ITfRangeACP, (void **)SelectionACP);
  1051. if (hr == S_OK)
  1052. {
  1053. hr = SelectionACP->GetExtent(pacpSelStart, pcchSel);
  1054. }
  1055. }
  1056. //
  1057. // if there is no selection, we don't have to check ReadOnly area.
  1058. //
  1059. if (*pcchSel == 0)
  1060. return hr;
  1061. //
  1062. // find the first non readonly range in the text store.
  1063. //
  1064. // pacpSelSrart is the offset of the composition string,
  1065. // so we need to subtract the range of the readonly area.
  1066. //
  1067. LONG cchRO = 0;
  1068. hr = _pCicContext->EscbReadOnlyPropMargin(imc, &SelectionACP, &cchRO);
  1069. if (hr == S_OK)
  1070. {
  1071. if (cchRO <= *pacpSelStart)
  1072. {
  1073. *pacpSelStart -= cchRO;
  1074. }
  1075. else
  1076. {
  1077. //
  1078. // our selection is overwrapped to Read Only area. Why?
  1079. //
  1080. Assert(0);
  1081. *pacpSelStart = 0;
  1082. *pcchSel = 0;
  1083. }
  1084. }
  1085. return S_OK;
  1086. }
  1087. //+---------------------------------------------------------------------------
  1088. //
  1089. // UIComposition::UpdateShowCompWndFlag
  1090. //
  1091. //+---------------------------------------------------------------------------
  1092. HRESULT
  1093. UIComposition::UpdateShowCompWndFlag(
  1094. IMCLock& imc,
  1095. DWORD* pdwCompStrLen)
  1096. {
  1097. HRESULT hr;
  1098. //
  1099. // Validation check of imc.
  1100. // Because CIMEUIWindowHandler::ImeUIWndProcWorker doesn't check.
  1101. //
  1102. if (FAILED(hr=imc.GetResult()))
  1103. {
  1104. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateShowCompWndFlag. imc==NULL"));
  1105. return hr;
  1106. }
  1107. if (! IsWindow(imc->hWnd))
  1108. {
  1109. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateShowCompWndFlag. imc->hWNd==NULL"));
  1110. return E_FAIL;
  1111. }
  1112. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  1113. if (FAILED(hr=comp.GetResult()))
  1114. {
  1115. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateShowCompWndFlag. comp==NULL"));
  1116. return hr;
  1117. }
  1118. if ((m_isc & ISC_SHOWUICOMPOSITIONWINDOW) && comp->dwCompStrLen)
  1119. {
  1120. m_fShowCompWnd.SetFlag();
  1121. }
  1122. else
  1123. {
  1124. m_fShowCompWnd.ResetFlag();
  1125. }
  1126. if (pdwCompStrLen)
  1127. *pdwCompStrLen = comp->dwCompStrLen;
  1128. return S_OK;
  1129. }
  1130. //+---------------------------------------------------------------------------
  1131. //
  1132. // UIComposition::UpdateCompositionRect
  1133. //
  1134. //+---------------------------------------------------------------------------
  1135. HRESULT
  1136. UIComposition::UpdateCompositionRect(
  1137. IMCLock& imc)
  1138. {
  1139. HRESULT hr;
  1140. //
  1141. // Validation check of imc.
  1142. // Because CIMEUIWindowHandler::ImeUIWndProcWorker doesn't check.
  1143. //
  1144. if (FAILED(hr=imc.GetResult()))
  1145. {
  1146. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateCompositionRect. imc==NULL"));
  1147. return hr;
  1148. }
  1149. if (! IsWindow(imc->hWnd))
  1150. {
  1151. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateCompositionRect. imc->hWNd==NULL"));
  1152. return E_FAIL;
  1153. }
  1154. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  1155. if (FAILED(hr=comp.GetResult()))
  1156. {
  1157. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateCompositionRect. comp==NULL"));
  1158. return hr;
  1159. }
  1160. //
  1161. // Get Selection.
  1162. //
  1163. LONG acpSelStart = 0;
  1164. LONG cchSel = 0;
  1165. GetSelection(imc, &acpSelStart, &cchSel);
  1166. //
  1167. // Update show composition flag
  1168. //
  1169. DWORD dwCompLen = 0;
  1170. UpdateShowCompWndFlag(imc, &dwCompLen);
  1171. //
  1172. // Allocate temp composition string buffer
  1173. //
  1174. LPWSTR lpCompStr;
  1175. lpCompStr = GetCompStrBuffer(comp->dwCompStrLen);
  1176. if (!lpCompStr)
  1177. return E_OUTOFMEMORY;
  1178. //
  1179. // Store composition string in local buffer
  1180. //
  1181. memcpy(lpCompStr,
  1182. comp.GetOffsetPointer(comp->dwCompStrOffset),
  1183. dwCompLen * sizeof(WCHAR));
  1184. UINT fSwpShow = m_fShowCompWnd.IsSetFlag() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
  1185. IME_UIWND_STATE uiwndState = GetLevelFromIMC(imc);
  1186. if (uiwndState == IME_UIWND_LEVEL1)
  1187. {
  1188. //
  1189. // When the style is DEFAULT, show the default composition window.
  1190. //
  1191. if (IsWindow(m_DefCompWnd.hCompWnd))
  1192. {
  1193. POLYTEXTW poly;
  1194. memset(&poly, 0, sizeof(poly));
  1195. poly.n = dwCompLen;
  1196. poly.lpstr = (LPCWSTR)lpCompStr;
  1197. poly.uiFlags = ETO_OPAQUE;
  1198. SIZE size;
  1199. HDC hDC = GetDC(m_DefCompWnd.hCompWnd);
  1200. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  1201. FLGetTextExtentPoint32(hDC, poly.lpstr, poly.n, &size);
  1202. poly.rcl.right = size.cx + 2 * GetSystemMetrics(SM_CXEDGE);
  1203. poly.rcl.bottom = size.cy + 2 * GetSystemMetrics(SM_CYEDGE);
  1204. BOOL fShowCaret = (comp->dwCursorPos <= poly.n ? TRUE : FALSE);
  1205. BOOL fEndCaret = (comp->dwCursorPos == poly.n ? TRUE : FALSE);
  1206. if (m_pDefCompFrameWnd)
  1207. {
  1208. m_pDefCompFrameWnd->SetCompStrRect(poly.rcl.right - poly.rcl.left + (fEndCaret ? m_caret_size.cx * 2: 0),
  1209. poly.rcl.bottom - poly.rcl.top + LINE_BOLD_WIDTH,
  1210. m_fShowCompWnd.IsSetFlag());
  1211. }
  1212. GuidMapAttribute guid_map(GuidMapAttribute::GetData(comp));
  1213. if (guid_map.Valid())
  1214. {
  1215. Assert(poly.n == guid_map->dwGuidMapAttrLen);
  1216. m_DefCompWnd.poly_text.RemoveAll();
  1217. PBYTE lpCompAttr = (PBYTE)guid_map.GetOffsetPointer(guid_map->dwGuidMapAttrOffset);
  1218. CCompClauseStore compclause;
  1219. compclause.Set(comp);
  1220. m_DefCompWnd.poly_text.SplitPolyStringAndAttr(imc, hDC, poly, lpCompAttr, &compclause);
  1221. }
  1222. else
  1223. {
  1224. m_DefCompWnd.poly_text.RemoveAll();
  1225. m_DefCompWnd.poly_text.SplitPolyStringAndAttr(imc, hDC, poly);
  1226. }
  1227. if (fShowCaret)
  1228. {
  1229. SetCaretPos(hDC, m_DefCompWnd.caret,
  1230. 0, 0,
  1231. poly.lpstr, poly.n, comp->dwCursorPos,
  1232. FALSE, fEndCaret);
  1233. }
  1234. //
  1235. // Save Selection acp and cch
  1236. //
  1237. m_DefCompWnd.sel.acpStart = acpSelStart;
  1238. m_DefCompWnd.sel.cch = cchSel;
  1239. SelectObject(hDC, hFontOrg);
  1240. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  1241. InvalidateRect(m_DefCompWnd.hCompWnd, NULL, FALSE);
  1242. }
  1243. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  1244. {
  1245. if (IsWindow(m_CompWnd[i].hCompWnd))
  1246. {
  1247. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  1248. }
  1249. }
  1250. if (m_pCompButtonFrameWnd)
  1251. {
  1252. m_pCompButtonFrameWnd->MoveShow(0, 0, FALSE);
  1253. }
  1254. }
  1255. else if (uiwndState == IME_UIWND_LEVEL2)
  1256. {
  1257. //
  1258. // When the style is not DEFAULT, show the composition window.
  1259. //
  1260. POINT pt = imc->cfCompForm.ptCurrentPos;
  1261. //
  1262. // Set the rectangle for the composition string.
  1263. //
  1264. RECT rect;
  1265. if (imc->cfCompForm.dwStyle & CFS_RECT)
  1266. rect = imc->cfCompForm.rcArea;
  1267. else
  1268. GetClientRect(imc->hWnd, &rect);
  1269. ClientToScreen(imc->hWnd, &pt);
  1270. MapWindowPoints(imc->hWnd, NULL, (LPPOINT)&rect, 2);
  1271. //
  1272. // Check the start position.
  1273. //
  1274. if (! PtInRect(&rect, pt))
  1275. return E_FAIL;
  1276. DWORD dwCursorPos = comp->dwCursorPos;
  1277. CCompClauseStore compclause;
  1278. compclause.Set(comp);
  1279. GuidMapAttribute guid_map(GuidMapAttribute::GetData(comp));
  1280. PBYTE lpCompAttr;
  1281. BOOL fCompAttr = TRUE;
  1282. if (guid_map.Valid())
  1283. {
  1284. lpCompAttr = (PBYTE)guid_map.GetOffsetPointer(guid_map->dwGuidMapAttrOffset);
  1285. Assert(dwCompLen == guid_map->dwGuidMapAttrLen);
  1286. }
  1287. else
  1288. {
  1289. TLS* ptls = TLS::GetTLS();
  1290. if (ptls)
  1291. {
  1292. CicProfile* pProfile;
  1293. if (pProfile = ptls->GetCicProfile())
  1294. {
  1295. LANGID langid;
  1296. pProfile->GetLangId(&langid);
  1297. if (PRIMARYLANGID(langid) == LANG_KOREAN)
  1298. {
  1299. fCompAttr = FALSE;
  1300. }
  1301. }
  1302. }
  1303. if (fCompAttr)
  1304. return E_FAIL;
  1305. }
  1306. {
  1307. //
  1308. // composition window
  1309. //
  1310. POINT compbtn_pos = {0,0};
  1311. BOOL fInitcompbtn_pos = FALSE;
  1312. POINT window_pos;
  1313. window_pos = pt;
  1314. int window_width;
  1315. if (!imc.UseVerticalCompWindow())
  1316. {
  1317. window_width = rect.right - pt.x;
  1318. }
  1319. else
  1320. {
  1321. window_width = rect.bottom - pt.y;
  1322. }
  1323. UINT string_length;
  1324. int i;
  1325. for (i = 0; i < sizeof(m_CompWnd)/sizeof(COMPWND) && dwCompLen > 0; i++)
  1326. {
  1327. m_CompWnd[i].caret.HideCaret();
  1328. m_CompWnd[i].poly_text.RemoveAll();
  1329. //
  1330. // Init Selection acp and cch
  1331. //
  1332. m_CompWnd[i].sel.acpStart = 0;
  1333. m_CompWnd[i].sel.cch = 0;
  1334. SIZE size;
  1335. size.cy = 0;
  1336. if (IsWindow(m_CompWnd[i].hCompWnd))
  1337. {
  1338. HDC hDC = GetDC(m_CompWnd[i].hCompWnd);
  1339. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel2);
  1340. if (i != MIDDLE_WINDOW)
  1341. {
  1342. string_length = CalcSingleTextExtentPoint(imc, hDC, lpCompStr, dwCompLen,
  1343. lpCompAttr,
  1344. fCompAttr,
  1345. &compclause,
  1346. window_width, &size,
  1347. m_CompWnd[i].poly_text, 0);
  1348. }
  1349. else
  1350. {
  1351. string_length = CalcMultiTextExtentPoint(imc, hDC, lpCompStr, dwCompLen,
  1352. lpCompAttr,
  1353. fCompAttr,
  1354. &compclause,
  1355. window_width, &size,
  1356. m_CompWnd[i].poly_text);
  1357. }
  1358. if (string_length)
  1359. {
  1360. BOOL fShowCaret = (dwCursorPos <= string_length ? TRUE : FALSE);
  1361. BOOL fEndCaret = (dwCursorPos == string_length ? TRUE : FALSE);
  1362. int pos_x = window_pos.x;
  1363. int pos_y = window_pos.y;
  1364. int cx;
  1365. int cy;
  1366. if (!imc.UseVerticalCompWindow())
  1367. {
  1368. cx = size.cx + (fEndCaret ? m_caret_size.cx: 0);
  1369. cy = size.cy;
  1370. }
  1371. else
  1372. {
  1373. pos_x -= size.cx;
  1374. cx = size.cx;
  1375. cy = size.cy + (fEndCaret ? m_caret_size.cy: 0);
  1376. }
  1377. SetWindowPos(m_CompWnd[i].hCompWnd, HWND_TOP,
  1378. pos_x, pos_y, cx, cy,
  1379. SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE |
  1380. fSwpShow);
  1381. if (fShowCaret)
  1382. {
  1383. UpdateCaretRect(hDC, i, dwCursorPos, imc.UseVerticalCompWindow(), fEndCaret);
  1384. dwCursorPos = ULONG_MAX;
  1385. }
  1386. else
  1387. {
  1388. dwCursorPos -= string_length;
  1389. }
  1390. //
  1391. // Save Selection acp and cch for this COMPWND
  1392. //
  1393. if (cchSel && (acpSelStart < (LONG)string_length))
  1394. {
  1395. m_CompWnd[i].sel.acpStart = acpSelStart;
  1396. LONG cchSelTemp = cchSel;
  1397. if (acpSelStart + cchSel > (LONG)string_length)
  1398. cchSelTemp = string_length - acpSelStart;
  1399. m_CompWnd[i].sel.cch = cchSelTemp;
  1400. //
  1401. // update cchSel for next COMPWND
  1402. //
  1403. cchSel -= cchSelTemp;
  1404. if (cchSel < 0)
  1405. cchSel = 0;
  1406. }
  1407. //
  1408. // set level2 comp finalizing button position.
  1409. //
  1410. compbtn_pos.x = pos_x + cx;
  1411. compbtn_pos.y = pos_y;
  1412. fInitcompbtn_pos = TRUE;
  1413. //
  1414. // update CompStr, CompAttr, CompClause for next COMPWND
  1415. //
  1416. lpCompStr += string_length;
  1417. dwCompLen -= string_length;
  1418. if (fCompAttr)
  1419. {
  1420. lpCompAttr += string_length;
  1421. compclause.Shift(string_length);
  1422. }
  1423. //
  1424. // update acpSelStart for next COMPWND
  1425. //
  1426. acpSelStart -= string_length;
  1427. if (acpSelStart < 0)
  1428. acpSelStart = 0;
  1429. }
  1430. else
  1431. {
  1432. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  1433. m_CompWnd[i].poly_text.RemoveAll();
  1434. }
  1435. SelectObject(hDC, hFontOrg);
  1436. ReleaseDC(m_CompWnd[i].hCompWnd, hDC);
  1437. InvalidateRect(m_CompWnd[i].hCompWnd, NULL, FALSE);
  1438. }
  1439. if (!imc.UseVerticalCompWindow())
  1440. {
  1441. window_pos.x = rect.left;
  1442. window_pos.y += size.cy;
  1443. window_width = rect.right - rect.left;
  1444. rect.top += size.cy;
  1445. }
  1446. else
  1447. {
  1448. window_pos.x -= size.cx;
  1449. window_pos.y = rect.top;
  1450. window_width = rect.bottom - rect.top;
  1451. rect.left -= size.cx;
  1452. }
  1453. }
  1454. //
  1455. // hide the remaining window.
  1456. //
  1457. for (; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  1458. {
  1459. if (IsWindow(m_CompWnd[i].hCompWnd))
  1460. ShowWindow(m_CompWnd[i].hCompWnd, SW_HIDE);
  1461. m_CompWnd[i].poly_text.RemoveAll();
  1462. }
  1463. if (IsWindow(m_DefCompWnd.hCompWnd))
  1464. {
  1465. ShowWindow(m_DefCompWnd.hCompWnd, SW_HIDE);
  1466. }
  1467. if (m_pDefCompFrameWnd)
  1468. m_pDefCompFrameWnd->Show(FALSE);
  1469. if (m_pCompButtonFrameWnd)
  1470. {
  1471. m_pCompButtonFrameWnd->MoveShow(compbtn_pos.x,
  1472. compbtn_pos.y,
  1473. m_fShowCompWnd.IsSetFlag() && fInitcompbtn_pos);
  1474. }
  1475. }
  1476. }
  1477. return S_OK;
  1478. }
  1479. //+---------------------------------------------------------------------------
  1480. //
  1481. // UIComposition::UpdateFont
  1482. //
  1483. //+---------------------------------------------------------------------------
  1484. HRESULT
  1485. UIComposition::UpdateFont(
  1486. IMCLock& imc)
  1487. {
  1488. HRESULT hr;
  1489. //
  1490. // Validation check of imc.
  1491. // Because CIMEUIWindowHandler::ImeUIWndProcWorker doesn't check.
  1492. //
  1493. if (FAILED(hr=imc.GetResult()))
  1494. {
  1495. DebugMsg(TF_ERROR, TEXT("UIComposition::UpdateFont. imc==NULL"));
  1496. return hr;
  1497. }
  1498. if (m_hFontLevel1)
  1499. DeleteObject(m_hFontLevel1);
  1500. if (m_hFontLevel2)
  1501. DeleteObject(m_hFontLevel2);
  1502. LOGFONTW logfont = imc->lfFont.W;
  1503. m_hFontLevel2 = CreateFontIndirectW(&logfont);
  1504. logfont.lfEscapement = 0;
  1505. logfont.lfOrientation = 0;
  1506. if (logfont.lfFaceName[0] == L'@')
  1507. {
  1508. StringCchCopyW(logfont.lfFaceName, ARRAYSIZE(logfont.lfFaceName), &logfont.lfFaceName[1]);
  1509. }
  1510. m_hFontLevel1 = CreateFontIndirectW(&logfont);
  1511. return S_OK;
  1512. }
  1513. //+---------------------------------------------------------------------------
  1514. //
  1515. // UIComposition::OnPaint
  1516. //
  1517. //+---------------------------------------------------------------------------
  1518. HRESULT
  1519. UIComposition::OnPaint(
  1520. TLS* ptls,
  1521. HWND hCompWnd,
  1522. HDC hDC,
  1523. PAINTSTRUCT& ps,
  1524. IMCLock& imc)
  1525. {
  1526. HRESULT hr = S_OK;
  1527. COMPWNDINDEX index = (COMPWNDINDEX)GetWindowLong(hCompWnd, COMPUI_WINDOW_INDEX);
  1528. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  1529. if (FAILED(hr=comp.GetResult()))
  1530. {
  1531. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPaint. comp==NULL"));
  1532. }
  1533. else
  1534. {
  1535. IME_UIWND_STATE uiwndState = GetLevelFromIMC(imc);
  1536. if ((uiwndState == IME_UIWND_LEVEL1) &&
  1537. (index == DEFAULT_WINDOW))
  1538. {
  1539. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  1540. PolyTextAndAttrOut(ptls,
  1541. hDC,
  1542. FALSE,
  1543. &m_DefCompWnd);
  1544. SelectObject(hDC, hFontOrg);
  1545. }
  1546. else if ((uiwndState == IME_UIWND_LEVEL2) &&
  1547. (index != DEFAULT_WINDOW))
  1548. {
  1549. if (m_CompWnd[index].poly_text.GetPolySize())
  1550. {
  1551. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel2);
  1552. PolyTextAndAttrOut(ptls,
  1553. hDC,
  1554. imc.UseVerticalCompWindow(),
  1555. &m_CompWnd[index]);
  1556. SelectObject(hDC, hFontOrg);
  1557. }
  1558. }
  1559. }
  1560. return hr;
  1561. }
  1562. //+---------------------------------------------------------------------------
  1563. //
  1564. // UIComposition::OnTimer
  1565. //
  1566. //+---------------------------------------------------------------------------
  1567. HRESULT
  1568. UIComposition::OnTimer(
  1569. HWND hCompWnd)
  1570. {
  1571. HRESULT hr = S_OK;
  1572. COMPWNDINDEX index = (COMPWNDINDEX)GetWindowLong(hCompWnd, COMPUI_WINDOW_INDEX);
  1573. if (index == DEFAULT_WINDOW)
  1574. {
  1575. return m_DefCompWnd.caret.OnTimer();
  1576. }
  1577. else
  1578. {
  1579. return m_CompWnd[index].caret.OnTimer();
  1580. }
  1581. }
  1582. //+---------------------------------------------------------------------------
  1583. //
  1584. // UIComposition::OnImeNotifySetCompositionWindow
  1585. //
  1586. //+---------------------------------------------------------------------------
  1587. HRESULT
  1588. UIComposition::OnImeNotifySetCompositionWindow(
  1589. IMCLock& imc)
  1590. {
  1591. return UpdateCompositionRect(imc);
  1592. }
  1593. //+---------------------------------------------------------------------------
  1594. //
  1595. // UIComposition::OnImeNotifySetCompositionFont
  1596. //
  1597. //+---------------------------------------------------------------------------
  1598. HRESULT
  1599. UIComposition::OnImeNotifySetCompositionFont(
  1600. IMCLock& imc)
  1601. {
  1602. HRESULT hr;
  1603. if (FAILED(hr = UpdateFont(imc)))
  1604. return hr;
  1605. return UpdateCompositionRect(imc);
  1606. }
  1607. //+---------------------------------------------------------------------------
  1608. //
  1609. // UIComposition::CalcSingleTextExtentPoint
  1610. //
  1611. //+---------------------------------------------------------------------------
  1612. UINT
  1613. UIComposition::CalcSingleTextExtentPoint(
  1614. IMCLock& imc,
  1615. HDC hDC,
  1616. LPCWSTR lpsz,
  1617. int string_len,
  1618. PBYTE lpAttr,
  1619. BOOL fCompAttr,
  1620. CCompClauseStore* compclause,
  1621. int window_width,
  1622. LPSIZE real_size, // OUTPUT: Total window rectangle
  1623. CPolyText& poly_text,
  1624. int row_index)
  1625. {
  1626. if (string_len == 0 || lpsz == NULL)
  1627. {
  1628. return 0;
  1629. }
  1630. SIZE delta_size;
  1631. delta_size.cx = 0;
  1632. UINT ret_len = 0;
  1633. UINT delta_len = 0;
  1634. SIZE size;
  1635. while ((delta_size.cx < window_width) && string_len)
  1636. {
  1637. ++delta_len;
  1638. --string_len;
  1639. FLGetTextExtentPoint32(hDC, lpsz, delta_len, &size);
  1640. delta_size = size;
  1641. }
  1642. if (delta_size.cx < window_width)
  1643. {
  1644. ret_len = delta_len;
  1645. }
  1646. else
  1647. {
  1648. ret_len = (delta_len > 1 ? delta_len - 1 : 0);
  1649. }
  1650. if (ret_len)
  1651. {
  1652. FLGetTextExtentPoint32(hDC, lpsz, ret_len, real_size);
  1653. }
  1654. else
  1655. {
  1656. //
  1657. // if string length is 0, we should return just the height.
  1658. //
  1659. real_size->cx = 0;
  1660. real_size->cy = delta_size.cy;
  1661. }
  1662. if (!imc.UseVerticalCompWindow())
  1663. {
  1664. if (ret_len > 0)
  1665. {
  1666. real_size->cy += LINE_BOLD_WIDTH;
  1667. POLYTEXTW poly;
  1668. memset(&poly, 0, sizeof(poly));
  1669. poly.y = row_index * real_size->cy;
  1670. poly.n = ret_len;
  1671. poly.lpstr = lpsz;
  1672. poly.uiFlags = ETO_OPAQUE;
  1673. poly.rcl.top = row_index * real_size->cy;
  1674. poly.rcl.right = real_size->cx;
  1675. poly.rcl.bottom = poly.rcl.top + real_size->cy;
  1676. if (fCompAttr)
  1677. poly_text.SplitPolyStringAndAttr(imc, hDC, poly, lpAttr, compclause);
  1678. else
  1679. poly_text.SplitPolyStringAndAttr(imc, hDC, poly);
  1680. }
  1681. }
  1682. else
  1683. {
  1684. RotateSize(real_size);
  1685. if (ret_len > 0)
  1686. {
  1687. real_size->cx += LINE_BOLD_WIDTH;
  1688. //
  1689. // shift prev lines to the right.
  1690. //
  1691. poly_text.ShiftPolyText(real_size->cx, 0);
  1692. POLYTEXTW poly;
  1693. memset(&poly, 0, sizeof(poly));
  1694. poly.x = real_size->cx;
  1695. poly.n = ret_len;
  1696. poly.lpstr = lpsz;
  1697. poly.uiFlags = ETO_OPAQUE;
  1698. poly.rcl.left = 0;
  1699. poly.rcl.right = poly.rcl.left + real_size->cx;
  1700. poly.rcl.bottom = real_size->cy;
  1701. if (fCompAttr)
  1702. poly_text.SplitPolyStringAndAttr(imc, hDC, poly, lpAttr, compclause);
  1703. else
  1704. poly_text.SplitPolyStringAndAttr(imc, hDC, poly);
  1705. }
  1706. }
  1707. //
  1708. // #608684
  1709. //
  1710. // the total size of poly text could be bigger than the result of
  1711. // FLGetTextExtentPoint() with whole string. So we need to
  1712. // adjust the returning size.
  1713. //
  1714. if (ret_len)
  1715. {
  1716. int real_width = 0;
  1717. INT_PTR i;
  1718. INT_PTR nCnt = poly_text.GetPolySize();
  1719. const POLYTEXTW* ppoly = poly_text.GetPolyData();
  1720. if (!imc.UseVerticalCompWindow())
  1721. {
  1722. for (i = 0; i < nCnt; i++)
  1723. {
  1724. if (ppoly->rcl.top == (row_index * real_size->cy))
  1725. real_width += (ppoly->rcl.right - ppoly->rcl.left);
  1726. ppoly++;
  1727. }
  1728. Assert(window_width >= real_width);
  1729. real_size->cx = real_width;
  1730. }
  1731. else
  1732. {
  1733. for (i = 0; i < nCnt; i++)
  1734. {
  1735. if (ppoly->rcl.left == 0)
  1736. real_width += (ppoly->rcl.bottom - ppoly->rcl.top);
  1737. ppoly++;
  1738. }
  1739. Assert(window_width >= real_width);
  1740. real_size->cy = real_width;
  1741. }
  1742. }
  1743. return ret_len;
  1744. }
  1745. //+---------------------------------------------------------------------------
  1746. //
  1747. // UIComposition::CalcMultiTextExtentPoint
  1748. //
  1749. //+---------------------------------------------------------------------------
  1750. UINT
  1751. UIComposition::CalcMultiTextExtentPoint(
  1752. IMCLock& imc,
  1753. HDC hDC,
  1754. LPCWSTR lpsz,
  1755. int string_len,
  1756. PBYTE lpAttr,
  1757. BOOL fCompAttr,
  1758. CCompClauseStore *compclause,
  1759. int window_width,
  1760. LPSIZE real_size, // OUTPUT: Total window rectangle
  1761. CPolyText& poly_text)
  1762. {
  1763. SIZE single_size; // output single window rectangle from CalcSingleTextExtentPoint
  1764. single_size.cy = 0;
  1765. single_size.cx = 0;
  1766. UINT single_len;
  1767. UINT total_string_len = 0;
  1768. SIZE prev_size = {0, 0};
  1769. UINT prev_string_len = 0;
  1770. real_size->cx = 0;
  1771. real_size->cy = 0;
  1772. int row_index = 0;
  1773. CCompClauseStore compclauseTmp;
  1774. compclauseTmp.Copy(compclause);
  1775. if (!imc.UseVerticalCompWindow())
  1776. {
  1777. while ((single_len = CalcSingleTextExtentPoint(imc, hDC, lpsz, string_len, lpAttr, fCompAttr, &compclauseTmp, window_width, &single_size, poly_text, row_index)) > 0)
  1778. {
  1779. string_len -= single_len;
  1780. lpsz += single_len;
  1781. if (fCompAttr)
  1782. {
  1783. lpAttr += single_len;
  1784. compclauseTmp.Shift(single_len);
  1785. }
  1786. real_size->cx = max(real_size->cx, single_size.cx);
  1787. real_size->cy += single_size.cy;
  1788. prev_size = single_size;
  1789. prev_string_len = single_len;
  1790. total_string_len += single_len;
  1791. ++row_index;
  1792. }
  1793. real_size->cy -= prev_size.cy;
  1794. total_string_len -= prev_string_len;
  1795. poly_text.RemoveLastLine(FALSE);
  1796. }
  1797. else
  1798. {
  1799. while ((single_len = CalcSingleTextExtentPoint(imc, hDC, lpsz, string_len, lpAttr, fCompAttr, &compclauseTmp, window_width, &single_size, poly_text, row_index)) > 0)
  1800. {
  1801. string_len -= single_len;
  1802. lpsz += single_len;
  1803. if (fCompAttr)
  1804. {
  1805. lpAttr += single_len;
  1806. compclauseTmp.Shift(single_len);
  1807. }
  1808. real_size->cy = max(real_size->cy, single_size.cy);
  1809. real_size->cx += single_size.cx;
  1810. prev_size = single_size;
  1811. prev_string_len = single_len;
  1812. total_string_len += single_len;
  1813. ++row_index;
  1814. }
  1815. real_size->cx -= prev_size.cx;
  1816. total_string_len -= prev_string_len;
  1817. if (poly_text.RemoveLastLine(TRUE) == S_OK)
  1818. poly_text.ShiftPolyText(-single_size.cx, 0);
  1819. }
  1820. return total_string_len;
  1821. }
  1822. //+---------------------------------------------------------------------------
  1823. //
  1824. // UIComposition::SetCaretPos
  1825. //
  1826. //+---------------------------------------------------------------------------
  1827. HRESULT
  1828. UIComposition::SetCaretPos(
  1829. HDC hDC,
  1830. CCaret& caret,
  1831. int x,
  1832. int y,
  1833. LPCWSTR lpCompStr,
  1834. DWORD string_length,
  1835. DWORD cursor_pos,
  1836. BOOL fVert,
  1837. BOOL fEndCaret)
  1838. {
  1839. if (cursor_pos > string_length)
  1840. return S_FALSE;
  1841. SIZE size;
  1842. FLGetTextExtentPoint32(hDC, lpCompStr, cursor_pos, &size);
  1843. POINT pos;
  1844. if (!fVert)
  1845. {
  1846. pos.x = ((x + size.cx > 1) ? (x + size.cx - (fEndCaret ? 0 : 1)) : 0);
  1847. pos.y = y;
  1848. }
  1849. else
  1850. {
  1851. RotateSize(&size);
  1852. pos.x = x - size.cx - LINE_BOLD_WIDTH;
  1853. pos.y = ((y + size.cy > 1) ? (y + size.cy - (fEndCaret ? 0 : 1)) : 0);
  1854. }
  1855. caret.SetCaretPos(pos);
  1856. caret.ShowCaret();
  1857. return S_OK;
  1858. }
  1859. //+---------------------------------------------------------------------------
  1860. //
  1861. // UIComposition::UpdateCaretRect
  1862. //
  1863. //+---------------------------------------------------------------------------
  1864. HRESULT
  1865. UIComposition::UpdateCaretRect(
  1866. HDC hDC,
  1867. int index,
  1868. DWORD dwCursorPos, // dwCursorPos:: based on m_CompWnd[index].poly_text.lpstr
  1869. BOOL fVert,
  1870. BOOL fEndCaret)
  1871. {
  1872. POLYTEXTW poly;
  1873. DWORD dwCur = dwCursorPos;
  1874. BOOL fFound = FALSE;
  1875. for (int i=0; i < m_CompWnd[index].poly_text.GetPolySize(); i++)
  1876. {
  1877. poly = m_CompWnd[index].poly_text.GetPolyAt(i);
  1878. if (dwCur <= poly.n)
  1879. {
  1880. fFound = TRUE;
  1881. break;
  1882. }
  1883. dwCur -= poly.n;
  1884. }
  1885. if (! fFound)
  1886. {
  1887. return S_FALSE;
  1888. }
  1889. SetCaretPos(hDC, m_CompWnd[index].caret,
  1890. poly.x, poly.y,
  1891. poly.lpstr, poly.n,
  1892. dwCur, fVert, fEndCaret);
  1893. return S_OK;
  1894. }
  1895. //+---------------------------------------------------------------------------
  1896. //
  1897. // UIComposition::PolyTextAndAttrOut
  1898. //
  1899. //+---------------------------------------------------------------------------
  1900. const DWORD s_dwDotStyles[] = {1,2};
  1901. const DWORD s_dwDashStyles[] = {3,2};
  1902. HRESULT
  1903. UIComposition::PolyTextAndAttrOut(
  1904. TLS* ptls,
  1905. HDC hDC,
  1906. BOOL fVert,
  1907. COMPWND* pcompwnd)
  1908. {
  1909. CicBridge* cic = ptls->GetCicBridge();
  1910. if (cic == NULL)
  1911. {
  1912. Internal_PolyTextOutW(hDC, pcompwnd->poly_text.GetPolyData(), (int)pcompwnd->poly_text.GetPolySize());
  1913. DebugMsg(TF_ERROR, TEXT("UIComposition::PolyTextAndAttrOut. cic==NULL"));
  1914. return S_OK;
  1915. }
  1916. if (pcompwnd->poly_text.GetAttrSize() == 0)
  1917. {
  1918. //
  1919. // Korean default composition window.
  1920. //
  1921. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  1922. SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  1923. Internal_PolyTextOutW(hDC, pcompwnd->poly_text.GetPolyData(), (int)pcompwnd->poly_text.GetPolySize());
  1924. return S_OK;
  1925. }
  1926. RECT rect;
  1927. GetClientRect(pcompwnd->hCompWnd, &rect);
  1928. LONG acpStart = 0;
  1929. for (int i = 0; i < pcompwnd->poly_text.GetAttrSize(); i++)
  1930. {
  1931. POLYTEXTW poly = pcompwnd->poly_text.GetPolyAt(i);
  1932. //
  1933. // Check if this is the last in this line.
  1934. //
  1935. BOOL fLastTextInLine = FALSE;
  1936. if (i + 1 < pcompwnd->poly_text.GetAttrSize())
  1937. {
  1938. POLYTEXTW poly_next = pcompwnd->poly_text.GetPolyAt(i+1);
  1939. if (!fVert && (poly_next.x < poly.rcl.right))
  1940. fLastTextInLine = TRUE;
  1941. else if (fVert && (poly_next.y < poly.rcl.bottom))
  1942. fLastTextInLine = TRUE;
  1943. }
  1944. else
  1945. {
  1946. fLastTextInLine = TRUE;
  1947. }
  1948. TF_DISPLAYATTRIBUTE da;
  1949. BOOL fDapNotFound = FALSE;
  1950. if (FAILED(cic->GetDisplayAttributeInfo(pcompwnd->poly_text.GetAttrAt(i), &da)))
  1951. {
  1952. memset(&da, 0, sizeof(da));
  1953. da.lsStyle = TF_LS_DOT;
  1954. da.crLine.type = TF_CT_SYSCOLOR;
  1955. da.crLine.nIndex = COLOR_WINDOWTEXT;
  1956. fDapNotFound= TRUE;
  1957. }
  1958. //
  1959. // Text and Back color.
  1960. //
  1961. switch (da.crText.type)
  1962. {
  1963. case TF_CT_SYSCOLOR: SetTextColor(hDC, GetSysColor(da.crText.nIndex)); break;
  1964. case TF_CT_COLORREF: SetTextColor(hDC, da.crText.cr); break;
  1965. default: SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); break;
  1966. }
  1967. switch (da.crBk.type)
  1968. {
  1969. case TF_CT_SYSCOLOR: SetBkColor(hDC, GetSysColor(da.crBk.nIndex)); break;
  1970. case TF_CT_COLORREF: SetBkColor(hDC, da.crBk.cr); break;
  1971. default: SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); break;
  1972. }
  1973. //
  1974. // Line
  1975. //
  1976. DWORD dwPenStyle = PS_GEOMETRIC | PS_SOLID;
  1977. DWORD dwStyles = 0;
  1978. const DWORD *lpdwStyles = NULL;
  1979. switch (da.lsStyle)
  1980. {
  1981. case TF_LS_NONE:
  1982. dwPenStyle = PS_NULL;
  1983. break;
  1984. case TF_LS_SOLID:
  1985. dwPenStyle = PS_GEOMETRIC | PS_SOLID;
  1986. break;
  1987. case TF_LS_DOT:
  1988. dwPenStyle = PS_GEOMETRIC | PS_USERSTYLE;
  1989. dwStyles = 2;
  1990. lpdwStyles = s_dwDotStyles;
  1991. break;
  1992. case TF_LS_DASH:
  1993. dwPenStyle = PS_GEOMETRIC | PS_USERSTYLE;
  1994. dwStyles = 2;
  1995. lpdwStyles = s_dwDashStyles;
  1996. break;
  1997. case TF_LS_SQUIGGLE:
  1998. dwPenStyle = PS_GEOMETRIC | PS_SOLID;
  1999. break;
  2000. }
  2001. DWORD dwWidth = 1;
  2002. if (da.fBoldLine)
  2003. {
  2004. dwWidth = LINE_BOLD_WIDTH;
  2005. }
  2006. LOGBRUSH lbr;
  2007. lbr.lbStyle = BS_SOLID;
  2008. lbr.lbColor = 0;
  2009. lbr.lbHatch = 0;
  2010. switch (da.crLine.type)
  2011. {
  2012. case TF_CT_SYSCOLOR: lbr.lbColor = GetSysColor(da.crLine.nIndex); break;
  2013. case TF_CT_COLORREF: lbr.lbColor = da.crLine.cr; break;
  2014. case TF_CT_NONE: lbr.lbColor = GetTextColor(hDC); break;
  2015. }
  2016. HPEN hPen = ExtCreatePen(dwPenStyle, dwWidth, &lbr, dwStyles, lpdwStyles);
  2017. if (hPen != NULL)
  2018. {
  2019. HPEN hPenOrg = (HPEN)SelectObject(hDC, hPen);
  2020. Internal_PolyTextOutW(hDC, &poly, 1);
  2021. SIZE size;
  2022. FLGetTextExtentPoint32(hDC, poly.lpstr, poly.n, &size);
  2023. POINT start_pt;
  2024. POINT end_pt;
  2025. if (!fVert)
  2026. {
  2027. start_pt.x = poly.x;
  2028. start_pt.y = poly.y + size.cy;
  2029. //
  2030. // (size.cy / 4) is the gap between clauses.
  2031. //
  2032. end_pt.x = poly.rcl.right;
  2033. if (!fLastTextInLine)
  2034. end_pt.x -= (size.cy / 4);
  2035. end_pt.y = start_pt.y;
  2036. }
  2037. else
  2038. {
  2039. RotateSize(&size);
  2040. start_pt.x = poly.rcl.left + 1;
  2041. start_pt.y = poly.y;
  2042. end_pt.x = poly.rcl.left + 1;
  2043. //
  2044. // (size.cx / 4) is the gap between clauses.
  2045. //
  2046. end_pt.y = poly.rcl.bottom;
  2047. if (!fLastTextInLine)
  2048. end_pt.y -= (size.cx / 4);
  2049. }
  2050. MoveToEx(hDC, start_pt.x, start_pt.y, NULL);
  2051. if (da.lsStyle != TF_LS_SQUIGGLE)
  2052. {
  2053. LineTo(hDC, end_pt.x, end_pt.y);
  2054. }
  2055. else
  2056. {
  2057. CArray<POINT, POINT> squiggle_line;
  2058. MakeSquiggleLine(start_pt, end_pt, LINE_SQUIGGLE_FREQUENCY, LINE_SQUIGGLE_AMPLITUDE, fVert, squiggle_line);
  2059. Polyline(hDC, squiggle_line.GetData(), (int)squiggle_line.GetSize());
  2060. }
  2061. SelectObject(hDC, hPenOrg);
  2062. DeleteObject(hPen);
  2063. }
  2064. else
  2065. {
  2066. Assert(0);
  2067. Internal_PolyTextOutW(hDC, &poly, 1);
  2068. }
  2069. //
  2070. // Draw Selection.
  2071. //
  2072. if (fDapNotFound && pcompwnd->sel.cch &&
  2073. ((acpStart + (LONG)poly.n) > pcompwnd->sel.acpStart) &&
  2074. (acpStart <= pcompwnd->sel.acpStart + pcompwnd->sel.cch))
  2075. {
  2076. LONG acpSelStartTemp;
  2077. LONG cchSelTemp;
  2078. acpSelStartTemp = pcompwnd->sel.acpStart - acpStart;
  2079. if (acpSelStartTemp < 0)
  2080. acpSelStartTemp = 0;
  2081. cchSelTemp = pcompwnd->sel.acpStart + pcompwnd->sel.cch - acpStart - acpSelStartTemp;
  2082. if (cchSelTemp > (LONG)poly.n)
  2083. cchSelTemp = poly.n;
  2084. SIZE sizeStart;
  2085. SIZE sizeEnd;
  2086. if (acpSelStartTemp)
  2087. {
  2088. FLGetTextExtentPoint32(hDC,
  2089. poly.lpstr,
  2090. acpSelStartTemp,
  2091. &sizeStart);
  2092. }
  2093. else
  2094. {
  2095. sizeStart.cx = 0;
  2096. sizeStart.cy = pcompwnd->fDefaultCompWnd ?
  2097. m_tmFontHeightLevel1 : m_tmFontHeightLevel2;
  2098. }
  2099. FLGetTextExtentPoint32(hDC,
  2100. poly.lpstr,
  2101. acpSelStartTemp + cchSelTemp,
  2102. &sizeEnd);
  2103. RECT rcInvert;
  2104. rcInvert = poly.rcl;
  2105. if (!fVert)
  2106. {
  2107. rcInvert.left = poly.rcl.left + sizeStart.cx;
  2108. rcInvert.right = poly.rcl.left + sizeEnd.cx;
  2109. }
  2110. else
  2111. {
  2112. rcInvert.top = poly.rcl.top + sizeStart.cx;
  2113. rcInvert.bottom = poly.rcl.top + sizeEnd.cx;
  2114. }
  2115. BitBlt(hDC,
  2116. rcInvert.left,
  2117. rcInvert.top,
  2118. rcInvert.right - rcInvert.left,
  2119. rcInvert.bottom - rcInvert.top,
  2120. hDC,
  2121. rcInvert.left,
  2122. rcInvert.top,
  2123. DSTINVERT);
  2124. }
  2125. if (fLastTextInLine)
  2126. {
  2127. //
  2128. // if this is the last in this line, we just draw with bk color.
  2129. //
  2130. POLYTEXTW poly_clear;
  2131. memset(&poly_clear, 0, sizeof(poly_clear));
  2132. if (!fVert)
  2133. {
  2134. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  2135. poly_clear.uiFlags = ETO_OPAQUE;
  2136. poly_clear.rcl.top = poly.y;
  2137. poly_clear.rcl.bottom = poly.rcl.bottom;
  2138. poly_clear.rcl.left = poly.rcl.right;
  2139. poly_clear.rcl.right = rect.right;
  2140. Internal_PolyTextOutW(hDC, &poly_clear, 1);
  2141. }
  2142. else
  2143. {
  2144. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  2145. poly_clear.uiFlags = ETO_OPAQUE;
  2146. poly_clear.rcl.top = poly.rcl.bottom;
  2147. poly_clear.rcl.bottom = rect.bottom;
  2148. poly_clear.rcl.left = poly.rcl.left;
  2149. poly_clear.rcl.right = poly.x;
  2150. Internal_PolyTextOutW(hDC, &poly_clear, 1);
  2151. }
  2152. }
  2153. acpStart += poly.n;
  2154. }
  2155. return S_OK;
  2156. }
  2157. //+---------------------------------------------------------------------------
  2158. //
  2159. // UIComposition::MakeSquiggleLine
  2160. //
  2161. //+---------------------------------------------------------------------------
  2162. HRESULT
  2163. UIComposition::MakeSquiggleLine(
  2164. POINT start_pt,
  2165. POINT end_pt,
  2166. int frequency,
  2167. int amplitude,
  2168. BOOL fVert,
  2169. CArray<POINT, POINT>& squiggle_line)
  2170. {
  2171. int nSquiggle = 0;
  2172. int n;
  2173. if (!fVert)
  2174. {
  2175. if (end_pt.x > start_pt.x)
  2176. n = (end_pt.x - start_pt.x) / frequency;
  2177. else
  2178. n = (start_pt.x - end_pt.x) / frequency;
  2179. }
  2180. else
  2181. {
  2182. if (end_pt.y > start_pt.y)
  2183. n = (end_pt.y - start_pt.y) / frequency;
  2184. else
  2185. n = (start_pt.y - end_pt.y) / frequency;
  2186. }
  2187. nSquiggle = n * 2; // control point.
  2188. nSquiggle++; // end point.
  2189. POINT begin_pt = start_pt;
  2190. POINT pt = begin_pt;
  2191. for (int i=1; i < nSquiggle; i++)
  2192. {
  2193. if (!fVert)
  2194. {
  2195. if ((n = i % 2) != 0)
  2196. {
  2197. // control point
  2198. pt.x += frequency / 2;
  2199. pt.y = begin_pt.y - amplitude;
  2200. }
  2201. else
  2202. {
  2203. pt.x = begin_pt.x + frequency;
  2204. pt.y = begin_pt.y;
  2205. begin_pt = pt;
  2206. }
  2207. }
  2208. else
  2209. {
  2210. if ((n = i % 2) != 0)
  2211. {
  2212. // control point
  2213. pt.x = begin_pt.x + amplitude;
  2214. pt.y += frequency / 2;
  2215. }
  2216. else
  2217. {
  2218. pt.x = begin_pt.x;
  2219. pt.y = begin_pt.y + frequency;
  2220. begin_pt = pt;
  2221. }
  2222. }
  2223. squiggle_line.SetAtGrow(i-1, pt);
  2224. }
  2225. return S_OK;
  2226. }
  2227. //+---------------------------------------------------------------------------
  2228. //
  2229. // UIComposition::OnPrivateGetContextFlag
  2230. //
  2231. //+---------------------------------------------------------------------------
  2232. HRESULT
  2233. UIComposition::OnPrivateGetContextFlag(
  2234. IMCLock& imc,
  2235. BOOL fStartComposition,
  2236. IME_UIWND_STATE* uists)
  2237. {
  2238. //
  2239. // Check WM_IME_STARTCOMPOSITION already send ?
  2240. //
  2241. if (fStartComposition)
  2242. {
  2243. WINDOWPLACEMENT wndpl;
  2244. if (IsWindow(m_DefCompWnd.hCompWnd) && IsWindowVisible(m_DefCompWnd.hCompWnd))
  2245. {
  2246. *uists = IME_UIWND_LEVEL1;
  2247. return S_OK;
  2248. }
  2249. else
  2250. {
  2251. for (int i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  2252. {
  2253. if (IsWindow(m_CompWnd[i].hCompWnd) && IsWindowVisible(m_CompWnd[i].hCompWnd))
  2254. {
  2255. *uists = IME_UIWND_LEVEL2;
  2256. return S_OK;
  2257. }
  2258. }
  2259. }
  2260. //
  2261. // If m_fShowCompWnd flag set, already arrived WM_IME_COMPOSITION in this UI Wnd.
  2262. // In this case, IME UI Wnd Level is either Level 1 or Level 2.
  2263. //
  2264. if (m_fShowCompWnd.IsSetFlag())
  2265. {
  2266. *uists = IME_UIWND_LEVEL1_OR_LEVEL2;
  2267. return S_OK;
  2268. }
  2269. if (! (m_isc & ISC_SHOWUICOMPOSITIONWINDOW))
  2270. {
  2271. *uists = IME_UIWND_LEVEL3;
  2272. return S_OK;
  2273. }
  2274. }
  2275. *uists = IME_UIWND_UNKNOWN;
  2276. return S_FALSE;
  2277. }
  2278. //+---------------------------------------------------------------------------
  2279. //
  2280. // UIComposition::OnPrivateGetCandRectFromComposition
  2281. //
  2282. //+---------------------------------------------------------------------------
  2283. HRESULT
  2284. UIComposition::OnPrivateGetCandRectFromComposition(
  2285. IMCLock& imc,
  2286. CandRectFromComposition* pv)
  2287. {
  2288. HRESULT hr;
  2289. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  2290. if (FAILED(hr=comp.GetResult()))
  2291. {
  2292. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPrivateGetCandRectFromComposition. comp==NULL"));
  2293. return hr;
  2294. }
  2295. IME_UIWND_STATE uiwndState = GetLevelFromIMC(imc);
  2296. if (uiwndState == IME_UIWND_LEVEL1)
  2297. {
  2298. LPCWSTR lpstr = (LPCWSTR)comp.GetOffsetPointer(comp->dwCompStrOffset);
  2299. SIZE size;
  2300. if (lpstr && pv->dwCharPos)
  2301. {
  2302. HDC hDC = GetDC(m_DefCompWnd.hCompWnd);
  2303. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  2304. FLGetTextExtentPoint32(hDC, lpstr, pv->dwCharPos, &size);
  2305. SelectObject(hDC, hFontOrg);
  2306. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  2307. }
  2308. else
  2309. {
  2310. size.cx = 0;
  2311. size.cy = m_tmFontHeightLevel1;
  2312. }
  2313. //
  2314. // When the style is DEFAULT, this is the default composition window.
  2315. //
  2316. GetWindowRect(m_DefCompWnd.hCompWnd, pv->out_rcArea);
  2317. POINT pt;
  2318. pt.x = pt.y = 0;
  2319. pv->out_rcArea->left += pt.x + size.cx;
  2320. pv->out_rcArea->right += pt.x + size.cx;
  2321. pv->out_rcArea->top += pt.y;
  2322. pv->out_rcArea->bottom += pt.y;
  2323. }
  2324. else if (uiwndState == IME_UIWND_LEVEL2)
  2325. {
  2326. BOOL fFound = FALSE;
  2327. POLYTEXTW poly;
  2328. DWORD dwCur = pv->dwCharPos;
  2329. int i;
  2330. if (PRIMARYLANGID(pv->langid) == LANG_JAPANESE)
  2331. {
  2332. //
  2333. // In Japanese case, poly_text stored each clause string.
  2334. //
  2335. for (i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND) && ! fFound;)
  2336. {
  2337. for (int j=0; j < m_CompWnd[i].poly_text.GetPolySize(); j++)
  2338. {
  2339. poly = m_CompWnd[i].poly_text.GetPolyAt(j);
  2340. if (dwCur < poly.n)
  2341. {
  2342. fFound = TRUE;
  2343. break;
  2344. }
  2345. dwCur -= poly.n;
  2346. }
  2347. if (! fFound)
  2348. {
  2349. i++;
  2350. }
  2351. }
  2352. }
  2353. else
  2354. {
  2355. //
  2356. // In other language case, poly_text stored plane text. Not clause.
  2357. //
  2358. for (i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND) && ! fFound;)
  2359. {
  2360. for (int j=0; j < m_CompWnd[i].poly_text.GetPolySize(); j++)
  2361. {
  2362. poly = m_CompWnd[i].poly_text.GetPolyAt(j);
  2363. if (dwCur <= poly.n)
  2364. {
  2365. fFound = TRUE;
  2366. poly.n = dwCur;
  2367. break;
  2368. }
  2369. dwCur -= poly.n;
  2370. }
  2371. if (! fFound)
  2372. {
  2373. i++;
  2374. }
  2375. }
  2376. }
  2377. if (! fFound)
  2378. {
  2379. return S_FALSE;
  2380. }
  2381. SIZE size;
  2382. if (poly.lpstr && poly.n)
  2383. {
  2384. HDC hDC = GetDC(m_CompWnd[i].hCompWnd);
  2385. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel2);
  2386. FLGetTextExtentPoint32(hDC, poly.lpstr, poly.n, &size);
  2387. SelectObject(hDC, hFontOrg);
  2388. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  2389. }
  2390. else
  2391. {
  2392. size.cx = 0;
  2393. size.cy = m_tmFontHeightLevel2;
  2394. }
  2395. if (!imc.UseVerticalCompWindow())
  2396. {
  2397. //
  2398. // When the style is not DEFAULT, this is the composition window.
  2399. //
  2400. if (PRIMARYLANGID(pv->langid) == LANG_JAPANESE)
  2401. {
  2402. pv->out_rcArea->left = poly.x;
  2403. }
  2404. else
  2405. {
  2406. pv->out_rcArea->left = poly.x + size.cx;
  2407. }
  2408. pv->out_rcArea->right = poly.x + size.cx;
  2409. pv->out_rcArea->top = poly.y;
  2410. pv->out_rcArea->bottom = poly.y + size.cy + LINE_BOLD_WIDTH;
  2411. }
  2412. else
  2413. {
  2414. RotateSize(&size);
  2415. pv->out_rcArea->left = poly.x - size.cx - LINE_BOLD_WIDTH;
  2416. pv->out_rcArea->right = poly.x;
  2417. pv->out_rcArea->top = poly.y;
  2418. pv->out_rcArea->bottom = poly.y + size.cy;
  2419. }
  2420. //
  2421. // Convert to Screen coordinate.
  2422. //
  2423. POINT pt;
  2424. pt.x = pt.y = 0;
  2425. ClientToScreen(m_CompWnd[i].hCompWnd, &pt);
  2426. pv->out_rcArea->left += pt.x;
  2427. pv->out_rcArea->right += pt.x;
  2428. pv->out_rcArea->top += pt.y;
  2429. pv->out_rcArea->bottom += pt.y;
  2430. }
  2431. return S_OK;
  2432. }
  2433. //+---------------------------------------------------------------------------
  2434. //
  2435. // UIComposition::GetCompStrExtent
  2436. //
  2437. //+---------------------------------------------------------------------------
  2438. HRESULT
  2439. UIComposition::OnSetCursor(IMCLock &imc, WPARAM wParam, LPARAM lParam)
  2440. {
  2441. HRESULT hr = E_FAIL;
  2442. POINT pt;
  2443. ULONG uEdge;
  2444. ULONG uQuadrant;
  2445. IMCCLock<CTFIMECONTEXT> imc_ctfime(imc->hCtfImeContext);
  2446. if (FAILED(hr=imc_ctfime.GetResult()))
  2447. {
  2448. DebugMsg(TF_ERROR, TEXT("UIComposition::OnSetCursor. imc_ctfime==NULL"));
  2449. return hr;
  2450. }
  2451. CicInputContext* _pCicContext = imc_ctfime->m_pCicContext;
  2452. if (_pCicContext == NULL)
  2453. {
  2454. DebugMsg(TF_ERROR, TEXT("UIComposition::OnSetCursor. _pCicContext==NULL"));
  2455. return hr;
  2456. }
  2457. GetCursorPos(&pt);
  2458. GetCompStrExtent(pt, &uEdge, &uQuadrant, imc);
  2459. DWORD dwBtnStatus = 0;
  2460. if (GetKeyState(VK_LBUTTON) < 0)
  2461. {
  2462. dwBtnStatus |= MK_LBUTTON;
  2463. }
  2464. if (GetKeyState(VK_MBUTTON) < 0)
  2465. {
  2466. dwBtnStatus |= MK_MBUTTON;
  2467. }
  2468. if (GetKeyState(VK_RBUTTON) < 0)
  2469. {
  2470. dwBtnStatus |= MK_RBUTTON;
  2471. }
  2472. if (_pCicContext->MsImeMouseHandler(uEdge, uQuadrant, dwBtnStatus, imc) == 1L)
  2473. hr = S_OK;
  2474. return hr;
  2475. }
  2476. //+---------------------------------------------------------------------------
  2477. //
  2478. // UIComposition::GetCompStrExtent
  2479. //
  2480. //+---------------------------------------------------------------------------
  2481. HRESULT
  2482. UIComposition::GetCompStrExtent(
  2483. POINT pt,
  2484. ULONG *puEdge,
  2485. ULONG *puQuadrant,
  2486. IMCLock& imc)
  2487. {
  2488. Assert(puEdge);
  2489. Assert(puQuadrant);
  2490. *puEdge = 0;
  2491. *puQuadrant = 0;
  2492. ULONG uCount;
  2493. HRESULT hr;
  2494. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  2495. if (FAILED(hr=comp.GetResult()))
  2496. {
  2497. DebugMsg(TF_ERROR, TEXT("UIComposition::GetCompStrExtent. comp==NULL"));
  2498. return hr;
  2499. }
  2500. if (!comp.GetOffsetPointer(comp->dwCompStrLen))
  2501. {
  2502. //
  2503. // There is no composition string.
  2504. //
  2505. return S_OK;
  2506. }
  2507. IME_UIWND_STATE uiwndState = GetLevelFromIMC(imc);
  2508. if (uiwndState == IME_UIWND_LEVEL1)
  2509. {
  2510. HDC hDC = GetDC(m_DefCompWnd.hCompWnd);
  2511. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  2512. POINT ptCli = pt;
  2513. ScreenToClient(m_DefCompWnd.hCompWnd, &ptCli);
  2514. hr = m_DefCompWnd.poly_text.GetPolyTextExtent(ptCli,
  2515. hDC,
  2516. FALSE,
  2517. puEdge,
  2518. puQuadrant);
  2519. SelectObject(hDC, hFontOrg);
  2520. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  2521. }
  2522. else if (uiwndState == IME_UIWND_LEVEL2)
  2523. {
  2524. BOOL fVert = imc.UseVerticalCompWindow();
  2525. int i;
  2526. for (i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  2527. {
  2528. HDC hDC = GetDC(m_CompWnd[i].hCompWnd);
  2529. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel2);
  2530. POINT ptCli = pt;
  2531. ScreenToClient(m_CompWnd[i].hCompWnd, &ptCli);
  2532. hr = m_CompWnd[i].poly_text.GetPolyTextExtent(ptCli,
  2533. hDC,
  2534. fVert,
  2535. puEdge,
  2536. puQuadrant);
  2537. SelectObject(hDC, hFontOrg);
  2538. ReleaseDC(m_CompWnd[i].hCompWnd, hDC);
  2539. if (hr == S_OK)
  2540. break;
  2541. }
  2542. }
  2543. return hr;
  2544. }
  2545. //+---------------------------------------------------------------------------
  2546. //
  2547. // UIComposition::CreateDefFrameWnd
  2548. //
  2549. //+---------------------------------------------------------------------------
  2550. HRESULT UIComposition::CreateDefFrameWnd(HWND hwndParent, HIMC hIMC)
  2551. {
  2552. DWORD dwWndStyle = // UIWINDOW_TOPMOST |
  2553. UIWINDOW_HASTOOLTIP |
  2554. UIWINDOW_HABITATINWORKAREA |
  2555. UIWINDOW_WHISTLERLOOK |
  2556. UIWINDOW_TOOLWINDOW;
  2557. if (!m_pDefCompFrameWnd)
  2558. {
  2559. m_pDefCompFrameWnd = new CDefCompFrameWindow(hIMC, dwWndStyle);
  2560. if (!m_pDefCompFrameWnd)
  2561. return E_OUTOFMEMORY;
  2562. if (!m_pDefCompFrameWnd->Initialize())
  2563. {
  2564. delete m_pDefCompFrameWnd;
  2565. m_pDefCompFrameWnd = NULL;
  2566. return E_FAIL;
  2567. }
  2568. m_pDefCompFrameWnd->Init();
  2569. }
  2570. m_pDefCompFrameWnd->CreateWnd(hwndParent);
  2571. return S_OK;
  2572. }
  2573. //+---------------------------------------------------------------------------
  2574. //
  2575. // UIComposition::CreateCompButtonWnd
  2576. //
  2577. //+---------------------------------------------------------------------------
  2578. HRESULT UIComposition::CreateCompButtonWnd(HWND hwndParent, HIMC hIMC)
  2579. {
  2580. //
  2581. // #500698
  2582. //
  2583. // no more level2 comp window in English Speech so we don't need
  2584. // finalizing button on level2.
  2585. //
  2586. TLS * ptls = TLS::GetTLS();
  2587. if (!ptls || !ptls->NonEACompositionEnabled())
  2588. return S_OK;
  2589. //
  2590. // we don't use Level2 Comp Finalizing Button for EA language.
  2591. //
  2592. if (IsEALang())
  2593. {
  2594. if (m_pCompButtonFrameWnd)
  2595. {
  2596. delete m_pCompButtonFrameWnd;
  2597. m_pCompButtonFrameWnd = NULL;
  2598. }
  2599. return S_OK;
  2600. }
  2601. DWORD dwWndStyle = // UIWINDOW_TOPMOST |
  2602. UIWINDOW_HASTOOLTIP |
  2603. UIWINDOW_HABITATINWORKAREA |
  2604. UIWINDOW_WHISTLERLOOK |
  2605. UIWINDOW_TOOLWINDOW |
  2606. UIWINDOW_WSBORDER;
  2607. if (!m_pCompButtonFrameWnd)
  2608. {
  2609. m_pCompButtonFrameWnd = new CCompButtonFrameWindow(hIMC, dwWndStyle);
  2610. if (!m_pCompButtonFrameWnd)
  2611. return E_OUTOFMEMORY;
  2612. if (!m_pCompButtonFrameWnd->Initialize())
  2613. {
  2614. delete m_pCompButtonFrameWnd;
  2615. m_pCompButtonFrameWnd = NULL;
  2616. return E_FAIL;
  2617. }
  2618. m_pCompButtonFrameWnd->Init();
  2619. }
  2620. m_pCompButtonFrameWnd->CreateWnd(hwndParent);
  2621. return S_OK;
  2622. }
  2623. //+---------------------------------------------------------------------------
  2624. //
  2625. // UIComposition::OnPrivateGetTextExtent
  2626. //
  2627. //+---------------------------------------------------------------------------
  2628. HRESULT UIComposition::OnPrivateGetTextExtent(IMCLock& imc, TEXTEXT *ptext_ext)
  2629. {
  2630. ULONG uCount;
  2631. HRESULT hr;
  2632. if (m_bTimerCOMPOSITION == TRUE)
  2633. {
  2634. // UIWnd has already got WM_IME_COMPOSITION with new composition text, and
  2635. // set a timer for it, but the time-out value has not yet elapsed, so the new
  2636. // composition window text is not updated yet.
  2637. // But caller of GetTextExtent may assume the new text has already been in the
  2638. // composition window and try to get extent for the updated range.
  2639. //
  2640. // In this case, we need to call UpdateCompositionRect( ) to update the composition
  2641. // Rect.
  2642. UpdateCompositionRect(imc);
  2643. }
  2644. IMCCLock<CTFIMECONTEXT> imc_ctfime(imc->hCtfImeContext);
  2645. if (FAILED(hr=imc_ctfime.GetResult()))
  2646. {
  2647. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPrivateGetTextExtent. imc_ctfime==NULL"));
  2648. return hr;
  2649. }
  2650. CicInputContext* _pCicContext = imc_ctfime->m_pCicContext;
  2651. if (_pCicContext == NULL)
  2652. {
  2653. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPrivateGetTextExtent. _pCicContext==NULL"));
  2654. return hr;
  2655. }
  2656. LONG cch = 0;
  2657. if (FAILED(_pCicContext->EscbReadOnlyPropMargin(imc, NULL, &cch)))
  2658. {
  2659. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPrivateGetTextExtent. comp==NULL"));
  2660. return hr;
  2661. }
  2662. ptext_ext->acpStart -= cch;
  2663. ptext_ext->acpEnd -= cch;
  2664. if (ptext_ext->prc)
  2665. memset(ptext_ext->prc, 0, sizeof(*ptext_ext->prc));
  2666. if (ptext_ext->pfClipped)
  2667. *ptext_ext->pfClipped = FALSE;
  2668. IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
  2669. if (FAILED(hr=comp.GetResult()))
  2670. {
  2671. DebugMsg(TF_ERROR, TEXT("UIComposition::OnPrivateGetTextExtent. comp==NULL"));
  2672. return hr;
  2673. }
  2674. if (!comp.GetOffsetPointer(comp->dwCompStrLen))
  2675. {
  2676. //
  2677. // There is no composition string.
  2678. //
  2679. return S_OK;
  2680. }
  2681. // If the requested range is beyond the composition window,
  2682. // just return the position based on the real window.
  2683. // this is hack for CHS/CHT TIP's special design.
  2684. if (ptext_ext->acpStart > (LONG)(comp->dwCompStrLen))
  2685. ptext_ext->acpStart = (LONG)(comp->dwCompStrLen);
  2686. if (ptext_ext->acpEnd > (LONG)(comp->dwCompStrLen))
  2687. ptext_ext->acpEnd = (LONG)(comp->dwCompStrLen);
  2688. RECT rcStart = {0};
  2689. RECT rcEnd = {0};
  2690. HRESULT hrStart = S_FALSE;
  2691. HRESULT hrEnd = S_FALSE;
  2692. IME_UIWND_STATE uiwndState = GetLevelFromIMC(imc);
  2693. if (uiwndState == IME_UIWND_LEVEL1)
  2694. {
  2695. HDC hDC = GetDC(m_DefCompWnd.hCompWnd);
  2696. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel1);
  2697. DWORD acpStart = ptext_ext->acpStart;
  2698. DWORD acpEnd = ptext_ext->acpEnd;
  2699. hrStart = m_DefCompWnd.poly_text.GetPolyTextExtentRect(acpStart, hDC, FALSE, TRUE, &rcStart);
  2700. if (hrStart == S_OK)
  2701. m_DefCompWnd._ClientToScreen(&rcStart);
  2702. hrEnd = m_DefCompWnd.poly_text.GetPolyTextExtentRect(acpEnd, hDC, FALSE, TRUE, &rcEnd);
  2703. if (hrEnd == S_OK)
  2704. m_DefCompWnd._ClientToScreen(&rcEnd);
  2705. SelectObject(hDC, hFontOrg);
  2706. ReleaseDC(m_DefCompWnd.hCompWnd, hDC);
  2707. }
  2708. else if (uiwndState == IME_UIWND_LEVEL2)
  2709. {
  2710. DWORD acpStart;
  2711. DWORD acpEnd;
  2712. BOOL fVert;
  2713. BOOL fGetLast = FALSE;
  2714. int i;
  2715. TryWithLast:
  2716. acpStart = ptext_ext->acpStart;
  2717. acpEnd = ptext_ext->acpEnd;
  2718. fVert = imc.UseVerticalCompWindow();
  2719. for (i=0; i < sizeof(m_CompWnd)/sizeof(COMPWND); i++)
  2720. {
  2721. HDC hDC = GetDC(m_CompWnd[i].hCompWnd);
  2722. HFONT hFontOrg = (HFONT)SelectObject(hDC, m_hFontLevel2);
  2723. if (hrStart != S_OK)
  2724. {
  2725. hrStart = m_CompWnd[i].poly_text.GetPolyTextExtentRect(acpStart, hDC, fVert, fGetLast, &rcStart);
  2726. if (hrStart == S_OK)
  2727. m_CompWnd[i]._ClientToScreen(&rcStart);
  2728. }
  2729. if (hrEnd != S_OK)
  2730. {
  2731. hrEnd = m_CompWnd[i].poly_text.GetPolyTextExtentRect(acpEnd, hDC, fVert, fGetLast, &rcEnd);
  2732. if (hrEnd == S_OK)
  2733. m_CompWnd[i]._ClientToScreen(&rcEnd);
  2734. }
  2735. SelectObject(hDC, hFontOrg);
  2736. ReleaseDC(m_CompWnd[i].hCompWnd, hDC);
  2737. if ((hrStart == S_OK) && (hrEnd == S_OK))
  2738. break;
  2739. }
  2740. if (!fGetLast && (hrStart != S_OK))
  2741. {
  2742. fGetLast = TRUE;
  2743. goto TryWithLast;
  2744. }
  2745. }
  2746. if (hrStart == S_OK)
  2747. {
  2748. if (hrEnd == S_OK)
  2749. {
  2750. ptext_ext->prc->left = min(rcStart.left , rcEnd.left);
  2751. ptext_ext->prc->top = min(rcStart.top , rcEnd.top);
  2752. ptext_ext->prc->bottom = max(rcStart.bottom , rcEnd.bottom);
  2753. ptext_ext->prc->right = max(rcStart.right , rcEnd.right);
  2754. }
  2755. else
  2756. {
  2757. ptext_ext->prc->left = rcStart.left;
  2758. ptext_ext->prc->top = rcStart.top;
  2759. ptext_ext->prc->bottom = rcStart.bottom;
  2760. ptext_ext->prc->right = rcStart.right;
  2761. }
  2762. }
  2763. return hrStart;
  2764. }