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.

1451 lines
46 KiB

  1. /****************************************************************************
  2. UI.CPP
  3. Owner: cslim
  4. Copyright (c) 1997-1999 Microsoft Corporation
  5. UI functions
  6. History:
  7. 14-JUL-1999 cslim Copied from IME98 source tree
  8. *****************************************************************************/
  9. #include "precomp.h"
  10. #include "apientry.h"
  11. #include "ui.h"
  12. #include "imedefs.h"
  13. #include "names.h"
  14. #include "config.h"
  15. #include "debug.h"
  16. #include "shellapi.h"
  17. #include "winex.h"
  18. #include "imcsub.h"
  19. #include "cpadsvr.h"
  20. #include "pad.h"
  21. #include "cicero.h"
  22. #include "toolbar.h"
  23. #include "resource.h"
  24. //////////////////////////////////////////////////////////////////////////////
  25. PRIVATE LRESULT CALLBACK UIWndProc(HWND hUIWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
  26. PRIVATE BOOL HandlePrivateMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plRet);
  27. PRIVATE LRESULT PASCAL NotifyUI(HWND hUIWnd, WPARAM wParam, LPARAM lParam);
  28. PRIVATE VOID PASCAL StatusWndMsg(HWND hUIWnd, BOOL fOn);
  29. PRIVATE HWND PASCAL GetStatusWnd(HWND hUIWnd);
  30. PRIVATE VOID PASCAL ShowUI(HWND hUIWnd, int nShowCmd);
  31. PRIVATE VOID PASCAL OnImeSetContext(HWND hUIWnd, BOOL fOn, LPARAM lShowUI);
  32. PRIVATE VOID PASCAL OnImeSelect(HWND hUIWnd, BOOL fOn);
  33. PRIVATE HWND PASCAL GetCandWnd(HWND hUIWnd);
  34. PRIVATE HWND PASCAL GetCompWnd(HWND hUIWnd);
  35. PRIVATE LRESULT PASCAL GetCandPos(HWND hUIWnd, LPCANDIDATEFORM lpCandForm);
  36. PRIVATE LRESULT PASCAL GetCompPos(HWND hUIWnd, LPCOMPOSITIONFORM lpCompForm);
  37. PRIVATE VOID PASCAL UIWndOnCommand(HWND hUIWnd, int id, HWND hWndCtl, UINT codeNotify);
  38. // Commented out SetIndicator because #199
  39. PRIVATE BOOL PASCAL SetIndicator(PCIMECtx pImeCtx);
  40. __inline
  41. BOOL PASCAL SetIndicator(HIMC hIMC)
  42. {
  43. PCIMECtx pImeCtx;
  44. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  45. return fFalse;
  46. else
  47. return SetIndicator(pImeCtx);
  48. }
  49. //////////////////////////////////////////////////////////////////////////////
  50. // TLS
  51. #define UNDEF_TLSINDEX -1
  52. DWORD vdwTLSIndex = UNDEF_TLSINDEX; // Thread Local Strage initial value.
  53. //////////////////////////////////////////////////////////////////////////////
  54. // Private UI messages
  55. UINT WM_MSIME_PROPERTY = 0; // Invoke property DLG
  56. UINT WM_MSIME_UPDATETOOLBAR = 0; // Redraw status window(Toolbar)
  57. UINT WM_MSIME_OPENMENU = 0; // Pop up status window context menu
  58. UINT WM_MSIME_IMEPAD = 0; // Boot up IME Pad
  59. // Message string
  60. #define RWM_PROPERTY "MSIMEProperty"
  61. #define RWM_UPDATETOOLBAR "MSIMEUpdateToolbar"
  62. #define RWM_OPENMENU "MSIMEOpenMenu"
  63. #define RWM_IMEPAD "MSIMEIMEPAD"
  64. /*----------------------------------------------------------------------------
  65. InitPrivateUIMsg
  66. Register all IME private UI messages
  67. ----------------------------------------------------------------------------*/
  68. BOOL InitPrivateUIMsg()
  69. {
  70. WM_MSIME_PROPERTY = RegisterWindowMessageA(RWM_PROPERTY);
  71. WM_MSIME_UPDATETOOLBAR = RegisterWindowMessageA(RWM_UPDATETOOLBAR);
  72. WM_MSIME_OPENMENU = RegisterWindowMessageA(RWM_OPENMENU);
  73. WM_MSIME_IMEPAD = RegisterWindowMessageA(RWM_IMEPAD);
  74. return fTrue;
  75. }
  76. /*----------------------------------------------------------------------------
  77. RegisterImeUIClass
  78. Register all IME UI calsses
  79. ----------------------------------------------------------------------------*/
  80. BOOL RegisterImeUIClass(HANDLE hInstance)
  81. {
  82. WNDCLASSEXA wc;
  83. HANDLE hMod;
  84. BOOL fRet = fTrue;
  85. // Init wc zero
  86. ZeroMemory(&wc, sizeof(WNDCLASSEXA));
  87. wc.cbSize = sizeof(WNDCLASSEXW);
  88. wc.cbClsExtra = 0;
  89. wc.cbWndExtra = sizeof(LONG_PTR) * 2; // for IMMGWLP_IMC and IMMGWLP_PRIVATE
  90. // and for move offset of Status window
  91. wc.hIcon = NULL;
  92. wc.hInstance = (HINSTANCE)hInstance;
  93. wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  94. wc.lpszMenuName = NULL;
  95. wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
  96. wc.hIconSm = NULL;
  97. // Assumption
  98. DbgAssert(sizeof(WNDCLASSEXA) == sizeof(WNDCLASSEXW));
  99. ///////////////////////////////////////////////////////////////////////////
  100. // IME UI server class
  101. wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
  102. wc.lpfnWndProc = UIWndProc;
  103. // Create Unicode window when NT
  104. if (IsWinNT())
  105. {
  106. LPWNDCLASSEXW pwcW = (LPWNDCLASSEXW)&wc;
  107. // IME UI class UNICODE name
  108. pwcW->lpszClassName = wszUIClassName;
  109. if ((fRet = RegisterClassExW(pwcW)) == fFalse)
  110. goto RegisterImeUIClassExit;
  111. }
  112. else
  113. {
  114. // IME UI class ANSI name
  115. wc.lpszClassName = szUIClassName;
  116. if ((fRet = RegisterClassEx(&wc)) == fFalse)
  117. goto RegisterImeUIClassExit;
  118. }
  119. ///////////////////////////////////////////////////////////////////////////
  120. // IME status class
  121. wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
  122. wc.lpfnWndProc = StatusWndProc;
  123. wc.lpszClassName = szStatusClassName;
  124. if ((fRet = RegisterClassEx(&wc)) == fFalse)
  125. goto RegisterImeUIClassExit;
  126. // Cand and composition wnd do not need extra wnd bytes
  127. wc.cbWndExtra = 0;
  128. ///////////////////////////////////////////////////////////////////////////
  129. // IME candidate class
  130. wc.lpfnWndProc = CandWndProc;
  131. wc.lpszClassName = szCandClassName;
  132. if ((fRet = RegisterClassEx(&wc)) == fFalse)
  133. goto RegisterImeUIClassExit;
  134. ///////////////////////////////////////////////////////////////////////////
  135. // IME composition class
  136. wc.lpfnWndProc = CompWndProc;
  137. wc.lpszClassName = szCompClassName;
  138. if ((fRet = RegisterClassEx(&wc)) == fFalse)
  139. goto RegisterImeUIClassExit;
  140. ///////////////////////////////////////////////////////////////////////////
  141. // Register Our Tooltip class
  142. hMod = GetModuleHandle("comctl32.dll");
  143. DbgAssert(hMod != 0);
  144. // If NT, register W class for Unicode text display on tooltip
  145. if (IsWinNT())
  146. {
  147. WNDCLASSEXW wcw;
  148. // Init wcw
  149. ZeroMemory(&wcw, sizeof(WNDCLASSEXW));
  150. wcw.cbSize = sizeof(WNDCLASSEXW);
  151. if (!GetClassInfoExW(NULL, wszTooltipClassName, &wcw))
  152. {
  153. GetClassInfoExW(NULL, TOOLTIPS_CLASSW, &wcw);
  154. wcw.cbSize = sizeof(WNDCLASSEXW);
  155. wcw.style |= CS_IME;
  156. wcw.hInstance = (HINSTANCE)hMod;
  157. wcw.lpszClassName = wszTooltipClassName;
  158. if ((fRet = RegisterClassExW(&wcw)) == fFalse)
  159. goto RegisterImeUIClassExit;
  160. }
  161. }
  162. else
  163. {
  164. wc.cbSize = sizeof(WNDCLASSEX);
  165. if (!GetClassInfoEx(NULL, szTooltipClassName, &wc))
  166. {
  167. GetClassInfoEx(NULL, TOOLTIPS_CLASS, &wc);
  168. wc.cbSize = sizeof(WNDCLASSEX);
  169. wc.style |= CS_IME;
  170. wc.hInstance = (HINSTANCE)hMod;
  171. wc.lpszClassName = szTooltipClassName;
  172. if ((fRet = RegisterClassEx(&wc)) == fFalse)
  173. goto RegisterImeUIClassExit;
  174. }
  175. }
  176. RegisterImeUIClassExit:
  177. #ifdef DEBUG
  178. OutputDebugString("RegisterImeUIClass() : return\r\n");
  179. #endif
  180. DbgAssert(fRet);
  181. return fRet;
  182. }
  183. BOOL UnregisterImeUIClass(HANDLE hInstance)
  184. {
  185. BOOL fRet = fTrue;
  186. // Unregister Status window class
  187. UnregisterClass(szStatusClassName, (HINSTANCE)hInstance);
  188. // Unregister Candidate window class
  189. UnregisterClass(szCandClassName, (HINSTANCE)hInstance);
  190. // Unregister Composition window class
  191. UnregisterClass(szCompClassName, (HINSTANCE)hInstance);
  192. // Unregister Tooltip window class
  193. UnregisterClass(szTooltipClassName, (HINSTANCE)hInstance);
  194. // Unregister UI class window class
  195. UnregisterClass(szUIClassName, (HINSTANCE)hInstance);
  196. return fRet;
  197. }
  198. /*----------------------------------------------------------------------------
  199. UIWndProc
  200. IME UI wnd messgae proc
  201. ----------------------------------------------------------------------------*/
  202. LRESULT CALLBACK UIWndProc(HWND hUIWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  203. {
  204. HGLOBAL hUIPrivate;
  205. LPUIPRIV lpUIPrivate;
  206. LRESULT lRet;
  207. LRESULT lResult = 0;
  208. Dbg(DBGID_UI, TEXT("UIWndProc():uMessage = 0x%08lX, wParam = 0x%04X, lParam = 0x%08lX"), uMessage, wParam, lParam);
  209. switch (uMessage)
  210. {
  211. HANDLE_MSG(hUIWnd, WM_COMMAND, UIWndOnCommand);
  212. case WM_CREATE:
  213. Dbg(DBGID_UI, TEXT("UIWndProc(): WM_CREATE- UI window Created"));
  214. // create storage for UI setting
  215. hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
  216. if (!hUIPrivate)
  217. {
  218. DbgAssert(0);
  219. return 1L;
  220. }
  221. if ((lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate))==0)
  222. return 1L;
  223. // Set UI show default value.
  224. lpUIPrivate->uiShowParam = ISC_SHOWUIALL;
  225. SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);
  226. // set the default position for UI window, it is hide now
  227. //SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);
  228. //ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);
  229. // Chcek if this is Winlogon process in Win9x
  230. if (!IsWinNT())
  231. {
  232. if (IsExplorerProcess() == fFalse && IsExplorer() == fFalse)
  233. vpInstData->dwSystemInfoFlags |= IME_SYSINFO_WINLOGON;
  234. }
  235. // Init Cicero service
  236. CiceroInitialize();
  237. DbgAssert(lpUIPrivate->m_pCicToolbar == NULL);
  238. if (IsCicero())
  239. lpUIPrivate->m_pCicToolbar = new CToolBar();
  240. GlobalUnlock(hUIPrivate);
  241. return 0;
  242. case WM_DESTROY:
  243. Dbg(DBGID_UI, TEXT("UIWndProc(): WM_DESTROY- UI window destroyed"));
  244. // Destroy IME Pad if exist
  245. CImePadSvr::DestroyCImePadSvr();
  246. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  247. if (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate))
  248. {
  249. Dbg(DBGID_UI, TEXT(" - WM_DESTROY Destroy all UI windows"));
  250. if (lpUIPrivate->hStatusTTWnd)
  251. DestroyWindow(lpUIPrivate->hCandTTWnd);
  252. if (lpUIPrivate->hStatusWnd)
  253. DestroyWindow(lpUIPrivate->hStatusWnd);
  254. if (lpUIPrivate->hCandTTWnd)
  255. DestroyWindow(lpUIPrivate->hCandTTWnd);
  256. if (lpUIPrivate->hCandWnd)
  257. DestroyWindow(lpUIPrivate->hCandWnd);
  258. if (lpUIPrivate->hCompWnd)
  259. DestroyWindow(lpUIPrivate->hCompWnd);
  260. // Terminate Cicero service
  261. if (IsCicero())
  262. {
  263. if (lpUIPrivate->m_pCicToolbar)
  264. {
  265. lpUIPrivate->m_pCicToolbar->Terminate();
  266. delete lpUIPrivate->m_pCicToolbar;
  267. lpUIPrivate->m_pCicToolbar = NULL;
  268. }
  269. // Issue: This call causes AV on Win9x
  270. // CiceroTerminate();
  271. }
  272. GlobalUnlock(hUIPrivate);
  273. GlobalFree(hUIPrivate);
  274. SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)0L);
  275. }
  276. return 0;
  277. case WM_IME_NOTIFY:
  278. return NotifyUI(hUIWnd, wParam, lParam);
  279. case WM_IME_SETCONTEXT:
  280. Dbg(DBGID_UI, TEXT(" - WM_IME_SETCONTEXT"));
  281. OnImeSetContext(hUIWnd, (BOOL)wParam, lParam);
  282. return 0;
  283. // WM_IME_CONTROL: Return Non-zero means failure otherwise 0
  284. case WM_IME_CONTROL:
  285. Dbg(DBGID_UI, TEXT(" - WM_IME_CONTROL"));
  286. switch (wParam)
  287. {
  288. case IMC_GETCANDIDATEPOS:
  289. return GetCandPos(hUIWnd, (LPCANDIDATEFORM)lParam);
  290. case IMC_GETCOMPOSITIONWINDOW:
  291. return GetCompPos(hUIWnd, (LPCOMPOSITIONFORM)lParam);
  292. case IMC_GETSTATUSWINDOWPOS:
  293. {
  294. HWND hStatusWnd;
  295. RECT rcStatusWnd;
  296. Dbg(DBGID_UI, TEXT("UIWndProc() - WM_IME_CONTROL - IMC_GETSTATUSWINDOWPOS"));
  297. hStatusWnd = GetStatusWnd(hUIWnd);
  298. if (!hStatusWnd)
  299. return (1L);
  300. if (!GetWindowRect(hStatusWnd, &rcStatusWnd))
  301. return (1L);
  302. return (MAKELRESULT(rcStatusWnd.left, rcStatusWnd.top));
  303. }
  304. break;
  305. case IMC_GETCOMPOSITIONFONT:
  306. {
  307. HFONT hFontFix;
  308. LPLOGFONT lpLogFont;
  309. LOGFONT lfFont;
  310. hFontFix = CreateFont(-16,0,0,0,0,0,0,0,129,OUT_DEFAULT_PRECIS,
  311. CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, szIMECompFont);
  312. lpLogFont = (LPLOGFONT)lParam;
  313. if (GetObject(hFontFix, sizeof(lfFont), (LPVOID)&lfFont))
  314. *lpLogFont = lfFont;
  315. DeleteObject(hFontFix);
  316. }
  317. break;
  318. default:
  319. return (1L);
  320. }
  321. return 0;
  322. //
  323. case WM_IME_STARTCOMPOSITION:
  324. OpenComp(hUIWnd);
  325. return 0;
  326. case WM_IME_COMPOSITION:
  327. HWND hCompWnd;
  328. hCompWnd = GetCompWnd(hUIWnd);
  329. if (hCompWnd) // Do not use Update() !
  330. {
  331. ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
  332. InvalidateRect(hCompWnd, NULL, fTrue);
  333. }
  334. return 0;
  335. case WM_IME_ENDCOMPOSITION:
  336. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  337. if (hUIPrivate && (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)))
  338. {
  339. // if comp wnd exist, destroy it.
  340. if (lpUIPrivate->hCompWnd)
  341. {
  342. ShowComp(hUIWnd, SW_HIDE);
  343. DestroyWindow(lpUIPrivate->hCompWnd);
  344. lpUIPrivate->hCompWnd = 0;
  345. }
  346. GlobalUnlock(hUIPrivate);
  347. }
  348. return 0;
  349. case WM_IME_SELECT:
  350. Dbg(DBGID_UI, TEXT(" - WM_IME_SELECT"));
  351. OnImeSelect(hUIWnd, (BOOL)wParam);
  352. return 0;
  353. case WM_DISPLAYCHANGE:
  354. {
  355. CIMEData ImeData(CIMEData::SMReadWrite);
  356. Dbg(DBGID_UI, TEXT(" - WM_DISPLAYCHANGE"));
  357. SystemParametersInfo(SPI_GETWORKAREA, 0, &ImeData->rcWorkArea, 0);
  358. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  359. if ( lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate) )
  360. {
  361. StatusDisplayChange(hUIWnd);
  362. GlobalUnlock(hUIPrivate);
  363. }
  364. return 0;
  365. }
  366. default:
  367. if (vfUnicode == fTrue && IsWinNT() == fTrue)
  368. lResult = DefWindowProcW(hUIWnd, uMessage, wParam, lParam);
  369. else
  370. lResult = DefWindowProc(hUIWnd, uMessage, wParam, lParam);
  371. }
  372. // if Private msg
  373. if (uMessage >= 0xC000)
  374. {
  375. // if private msg proccessed return value
  376. if (HandlePrivateMessage(hUIWnd, uMessage, wParam, lParam, &lRet))
  377. return lRet;
  378. }
  379. return lResult;
  380. }
  381. /*----------------------------------------------------------------------------
  382. HandlePrivateMessage
  383. IME UI private messgae handler
  384. ----------------------------------------------------------------------------*/
  385. PRIVATE BOOL HandlePrivateMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plRet)
  386. {
  387. HIMC hIMC;
  388. PCIMECtx pImeCtx;
  389. LRESULT lRet = 0;
  390. BOOL fProcessed = fFalse;
  391. if (msg == WM_MSIME_PROPERTY)
  392. {
  393. fProcessed = fTrue;
  394. hIMC = GethImcFromHwnd(hWnd);
  395. if (pImeCtx = GetIMECtx(hIMC))
  396. ImeConfigure(NULL, pImeCtx->GetAppWnd(), (DWORD)lParam, NULL);
  397. DbgAssert(pImeCtx != NULL);
  398. }
  399. else
  400. if (msg == WM_MSIME_UPDATETOOLBAR)
  401. {
  402. HWND hStatusWnd;
  403. fProcessed = fTrue;
  404. hStatusWnd = GetStatusWnd(hWnd);
  405. if (hStatusWnd)
  406. {
  407. CIMEData ImeData;
  408. InvalidateRect(hStatusWnd, &ImeData->rcButtonArea, fFalse);
  409. }
  410. }
  411. else
  412. if (msg == WM_MSIME_OPENMENU)
  413. {
  414. fProcessed = fTrue;
  415. UIPopupMenu(hWnd);
  416. }
  417. else
  418. if (msg == WM_MSIME_IMEPAD)
  419. {
  420. if ((vpInstData->dwSystemInfoFlags & IME_SYSINFO_WINLOGON) == 0)
  421. {
  422. hIMC = GethImcFromHwnd(hWnd);
  423. if (pImeCtx = GetIMECtx(hIMC))
  424. SetForegroundWindow(pImeCtx->GetAppWnd()); // trick
  425. DbgAssert(pImeCtx != NULL);
  426. // Boot Pad
  427. BootPad(hWnd, (UINT)wParam, lParam);
  428. }
  429. }
  430. *plRet = lRet;
  431. return fProcessed;
  432. }
  433. //////////////////////////////////////////////////////////////////////////////
  434. LRESULT PASCAL NotifyUI(HWND hUIWnd, WPARAM wParam, LPARAM lParam)
  435. {
  436. HWND hWnd;
  437. HGLOBAL hUIPrivate;
  438. LPUIPRIV lpUIPrivate;
  439. LONG lRet = 0;
  440. Dbg(DBGID_UI, TEXT("NotifyUI(): hUIWnd = 0x%X wParam = 0x%04X, lParam = 0x%08lX"), hUIWnd, wParam, lParam);
  441. switch (wParam)
  442. {
  443. case IMN_OPENSTATUSWINDOW:
  444. Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_OPENSTATUSWINDOW"));
  445. StatusWndMsg(hUIWnd, fTrue);
  446. break;
  447. case IMN_CLOSESTATUSWINDOW:
  448. Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_CLOSESTATUSWINDOW"));
  449. StatusWndMsg(hUIWnd, fFalse);
  450. break;
  451. case IMN_SETSTATUSWINDOWPOS:
  452. Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_SETSTATUSWINDOWPOS"));
  453. if (!IsCicero())
  454. {
  455. fSetStatusWindowPos(GetStatusWnd(hUIWnd), NULL);
  456. fSetCompWindowPos(GetCompWnd(hUIWnd));
  457. }
  458. break;
  459. // IMN_SETCOMPOSITIONWINDOW called for all user key press
  460. case IMN_SETCOMPOSITIONWINDOW:
  461. hWnd = GetCompWnd(hUIWnd);
  462. if (hWnd)
  463. fSetCompWindowPos(hWnd);
  464. break;
  465. case IMN_OPENCANDIDATE:
  466. Dbg(DBGID_UI, TEXT(" - IMN_OPENCANDIDATE"));
  467. OpenCand(hUIWnd);
  468. break;
  469. case IMN_CLOSECANDIDATE:
  470. Dbg(DBGID_UI, TEXT(" - IMN_CLOSECANDIDATE"));
  471. if (lParam & 0x00000001)
  472. {
  473. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  474. if (hUIPrivate && (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)))
  475. {
  476. if (lpUIPrivate->hCandWnd)
  477. {
  478. ShowCand(hUIWnd, SW_HIDE);
  479. DestroyWindow(lpUIPrivate->hCandWnd);
  480. lpUIPrivate->hCandWnd = 0;
  481. }
  482. if (lpUIPrivate->hCandTTWnd)
  483. {
  484. DestroyWindow(lpUIPrivate->hCandTTWnd);
  485. lpUIPrivate->hCandTTWnd = 0;
  486. }
  487. GlobalUnlock(hUIPrivate);
  488. }
  489. }
  490. break;
  491. case IMN_SETCANDIDATEPOS:
  492. hWnd = GetCandWnd(hUIWnd);
  493. if (hWnd)
  494. fSetCandWindowPos(hWnd);
  495. break;
  496. case IMN_CHANGECANDIDATE:
  497. Dbg(DBGID_UI, TEXT(" - Redraw cand window"));
  498. hWnd = GetCandWnd(hUIWnd);
  499. //RedrawWindow(hStatusWnd, &ImeData->rcButtonArea, NULL, RDW_INVALIDATE);
  500. InvalidateRect(hWnd, NULL, fFalse);
  501. break;
  502. case IMN_SETOPENSTATUS:
  503. SetIndicator(GethImcFromHwnd(hUIWnd));
  504. break;
  505. case IMN_SETCONVERSIONMODE:
  506. hWnd = GetStatusWnd(hUIWnd);
  507. if (hWnd)
  508. {
  509. CIMEData ImeData(CIMEData::SMReadWrite);
  510. Dbg(DBGID_UI, TEXT(" - Redraw status window"));
  511. //RedrawWindow(hWnd, &ImeData->rcButtonArea, NULL, RDW_INVALIDATE);
  512. InvalidateRect(hWnd, &ImeData->rcButtonArea, fFalse);
  513. }
  514. SetIndicator(GethImcFromHwnd(hUIWnd));
  515. // Update Cicero buttons
  516. if (IsCicero() && (hUIPrivate = GethUIPrivateFromHwnd(hUIWnd)) &&
  517. (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) != NULL)
  518. {
  519. lpUIPrivate->m_pCicToolbar->Update(UPDTTB_CMODE|UPDTTB_FHMODE);
  520. GlobalUnlock(hUIPrivate);
  521. }
  522. break;
  523. default:
  524. Dbg(DBGID_UI, TEXT("NotifyUI(): Unhandled IMN = 0x%04X"), wParam);
  525. lRet = fTrue;
  526. }
  527. return lRet;
  528. }
  529. ///////////////////////////////////////////////////////////////////////////////
  530. // Called when IMN_OPENSTATUSWINDOW/IMN_CLOSESTATUSWINDOW occurs
  531. // set the show hide state and
  532. // show/hide the status window
  533. void PASCAL StatusWndMsg(HWND hUIWnd, BOOL fOn)
  534. {
  535. HGLOBAL hUIPrivate;
  536. HIMC hIMC;
  537. register LPUIPRIV lpUIPrivate;
  538. Dbg(DBGID_UI, TEXT("StatusWndMsg(): hUIWnd = 0x%X, fOn = %d"), hUIWnd, fOn);
  539. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  540. if (!hUIPrivate)
  541. {
  542. DbgAssert(0);
  543. return;
  544. }
  545. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  546. if (!lpUIPrivate)
  547. {
  548. DbgAssert(0);
  549. return;
  550. }
  551. hIMC = GethImcFromHwnd(hUIWnd);
  552. // if Cicero enabled, Init/Terminate Cicero toolbar.
  553. // Office 10 #249973: I moved init position to here from OnImeSetContext.
  554. // But make sure all user's "HKEY_CURRENT_USER\Control Panel\Input Method\Show Status" shuold be "1"
  555. // Setup will do this by enumerating HKEY_USERS
  556. if (IsCicero())
  557. {
  558. if (fOn)
  559. {
  560. if (lpUIPrivate->m_pCicToolbar)
  561. lpUIPrivate->m_pCicToolbar->Initialize();
  562. }
  563. else
  564. {
  565. if (lpUIPrivate->m_pCicToolbar)
  566. lpUIPrivate->m_pCicToolbar->Terminate();
  567. }
  568. }
  569. else
  570. {
  571. if (fOn)
  572. {
  573. InitButtonState(); // b#159
  574. OpenStatus(hUIWnd);
  575. }
  576. if (lpUIPrivate->hStatusWnd == 0)
  577. {
  578. Dbg(DBGID_UI, TEXT("StatusWndMsg(): Null Status window handle"));
  579. GlobalUnlock(hUIPrivate);
  580. return;
  581. }
  582. if (fOn)
  583. {
  584. if (hIMC)
  585. ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
  586. else
  587. {
  588. ShowStatus(hUIWnd, SW_HIDE);
  589. Dbg(DBGID_UI, TEXT("StatusWndMsg(): hIMC == 0, Call ShowStatus(HIDE)"));
  590. }
  591. }
  592. else
  593. {
  594. DestroyWindow(lpUIPrivate->hStatusWnd);
  595. Dbg(DBGID_UI, TEXT("StatusWndMsg(): Call ShowStatus(HIDE)"));
  596. }
  597. }
  598. // Unlock UI private handle
  599. GlobalUnlock(hUIPrivate);
  600. }
  601. /*----------------------------------------------------------------------------
  602. OnUIProcessAttach
  603. ----------------------------------------------------------------------------*/
  604. BOOL OnUIProcessAttach()
  605. {
  606. DbgAssert(vdwTLSIndex == UNDEF_TLSINDEX);
  607. if (vdwTLSIndex == UNDEF_TLSINDEX)
  608. {
  609. vdwTLSIndex = ::TlsAlloc(); //Get new TLS index.
  610. if (vdwTLSIndex == UNDEF_TLSINDEX)
  611. {
  612. Dbg(DBGID_UI, "-->SetActiveUIWnd ::TlsAlloc Error ret [%d]\n", GetLastError());
  613. return fFalse;
  614. }
  615. }
  616. return fTrue;
  617. }
  618. /*----------------------------------------------------------------------------
  619. OnUIProcessDetach
  620. ----------------------------------------------------------------------------*/
  621. BOOL OnUIProcessDetach()
  622. {
  623. if (TlsFree(vdwTLSIndex) == 0)
  624. {
  625. Dbg(DBGID_UI, "-->::TlsFree Error [%d]\n", GetLastError());
  626. return fFalse;
  627. }
  628. vdwTLSIndex = UNDEF_TLSINDEX;
  629. return fTrue;
  630. }
  631. /*----------------------------------------------------------------------------
  632. OnUIThreadDetach
  633. ----------------------------------------------------------------------------*/
  634. BOOL OnUIThreadDetach()
  635. {
  636. if (vdwTLSIndex != UNDEF_TLSINDEX)
  637. TlsSetValue(vdwTLSIndex, NULL);
  638. return fTrue;
  639. }
  640. /*----------------------------------------------------------------------------
  641. SetActiveUIWnd
  642. Save current Active UI wnd handle to TLS
  643. ----------------------------------------------------------------------------*/
  644. VOID SetActiveUIWnd(HWND hWnd)
  645. {
  646. Dbg(DBGID_UI, "SetActiveUIWnd(hWnd=%lx) \r\n", hWnd);
  647. if (IsWin(hWnd) == fFalse)
  648. {
  649. Dbg(DBGID_UI, "SetActiveUIWnd( hWnd=%lx ) - no window\r\n", hWnd );
  650. return;
  651. }
  652. if (TlsSetValue(vdwTLSIndex, (LPVOID)hWnd) == 0)
  653. {
  654. Dbg(DBGID_UI, "-->LoadCImePadSvr() TlsSetValue Failed [%d]\n", GetLastError());
  655. TlsSetValue(vdwTLSIndex, NULL);
  656. return;
  657. }
  658. }
  659. /*----------------------------------------------------------------------------
  660. GetActiveUIWnd
  661. Retrieve current Active UI wnd handle from TLS
  662. ----------------------------------------------------------------------------*/
  663. HWND GetActiveUIWnd()
  664. {
  665. return (HWND)TlsGetValue(vdwTLSIndex);
  666. }
  667. // Called by OnImeSetContext() and OnImeSelect()
  668. void PASCAL ShowUI(HWND hUIWnd, int nShowCmd)
  669. {
  670. HIMC hIMC;
  671. PCIMECtx pImeCtx;
  672. HGLOBAL hUIPrivate;
  673. LPUIPRIV lpUIPrivate;
  674. Dbg(DBGID_UI, TEXT("ShowUI() : nShowCmd=%d"), nShowCmd);
  675. #if 0
  676. if (nShowCmd != SW_HIDE)
  677. {
  678. // Check if hIMC and hPrivate is valid
  679. // If not valid hide all UI windows.
  680. hIMC = GethImcFromHwnd(hUIWnd);
  681. lpIMC = (LPINPUTCONTEXT)OurImmLockIMC(hIMC);
  682. lpImcP = (LPIMCPRIVATE)GetPrivateBuffer(hIMC);
  683. if (!(hIMC && lpIMC && lpImcP))
  684. nShowCmd = SW_HIDE;
  685. }
  686. #else
  687. hIMC = GethImcFromHwnd(hUIWnd);
  688. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  689. nShowCmd = SW_HIDE;
  690. #endif
  691. ///////////////////////////////////////////////////////////////////////////
  692. // Lock hUIPrivate
  693. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  694. // can not draw status window
  695. if (!hUIPrivate)
  696. return;
  697. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  698. // can not draw status window
  699. if (!lpUIPrivate)
  700. return;
  701. // Hide all UI window and return immediately
  702. if (nShowCmd == SW_HIDE)
  703. {
  704. Dbg(DBGID_UI, TEXT("ShowUI() : hiding all UI"));
  705. ShowStatus(hUIWnd, SW_HIDE);
  706. ShowComp(hUIWnd, SW_HIDE);
  707. ShowCand(hUIWnd, SW_HIDE);
  708. // FIXED : if (nShowCmd == SW_HIDE) hIMC and lpIMC->hPrivate not Locked
  709. // So you need not Unlock
  710. goto ShowUIUnlockUIPrivate;
  711. }
  712. //////////////////
  713. // Status window
  714. if (lpUIPrivate->hStatusWnd)
  715. {
  716. // if currently hide, show it.
  717. if (lpUIPrivate->nShowStatusCmd == SW_HIDE)
  718. ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
  719. else
  720. {
  721. // sometime the WM_ERASEBKGND is eaten by the app
  722. RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
  723. RDW_FRAME|RDW_INVALIDATE/*|RDW_ERASE*/);
  724. }
  725. }
  726. /*
  727. //////////////////////
  728. // Composition window
  729. if (lpUIPrivate->hCompWnd)
  730. {
  731. if (lpUIPrivate->nShowCompCmd == SW_HIDE)
  732. ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
  733. else
  734. {
  735. // sometime the WM_ERASEBKGND is eaten by the app
  736. RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
  737. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  738. }
  739. }
  740. ////////////////////
  741. // Candidate window
  742. if (lpUIPrivate->hCandWnd)
  743. {
  744. if (lpUIPrivate->nShowCandCmd == SW_HIDE)
  745. ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
  746. else
  747. {
  748. // some time the WM_ERASEBKGND is eaten by the app
  749. RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
  750. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  751. }
  752. fSetCandWindowPos(lpUIPrivate->hCandWnd);
  753. }
  754. */
  755. ShowUIUnlockUIPrivate:
  756. GlobalUnlock(hUIPrivate);
  757. return;
  758. }
  759. ////////////////////////////////////////////////////////////////////////
  760. // WM_IME_SETCONTEXT sent whenever user activated/deactivated a window
  761. void PASCAL OnImeSetContext(HWND hUIWnd, BOOL fOn, LPARAM lShowUI)
  762. {
  763. HGLOBAL hUIPrivate;
  764. LPUIPRIV lpUIPrivate;
  765. HWND hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
  766. HIMC hIMC = NULL;
  767. PCIMECtx pImeCtx;
  768. Dbg(DBGID_UI, TEXT("OnImeSetContext(): hUIWnd = 0x%X fOn = %d"), hUIWnd, fOn);
  769. // Get UI private memory
  770. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  771. if (hUIPrivate == 0 || (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) == 0)
  772. {
  773. ShowUI(hUIWnd, SW_HIDE);
  774. // Set disabled Pen Icon
  775. if (fOn)
  776. SetIndicator((PCIMECtx)NULL);
  777. goto LOnImeSetContextExit;
  778. }
  779. // Init Cicero service
  780. CiceroInitialize();
  781. // If Cicero enabled, init toolbar
  782. if (IsCicero())
  783. {
  784. // Create Toolbar object and store it to private memory
  785. if (lpUIPrivate->m_pCicToolbar == NULL)
  786. lpUIPrivate->m_pCicToolbar = new CToolBar();
  787. DbgAssert(lpUIPrivate->m_pCicToolbar != NULL);
  788. }
  789. hIMC = GethImcFromHwnd(hUIWnd);
  790. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  791. {
  792. ShowUI(hUIWnd, SW_HIDE);
  793. // Set disabled Pen Icon
  794. if (fOn)
  795. SetIndicator((PCIMECtx)NULL);
  796. // Disable cicero buttons
  797. if (IsCicero() && lpUIPrivate->m_pCicToolbar)
  798. lpUIPrivate->m_pCicToolbar->SetCurrentIC(NULL);
  799. goto LOnImeSetContextExit2;
  800. }
  801. if (fOn)
  802. {
  803. // Store UI Window handle to TLS
  804. SetActiveUIWnd(hUIWnd);
  805. // Keep lParam
  806. lpUIPrivate->uiShowParam = lShowUI;
  807. if (pImeCtx->GetCandidateFormIndex(0) != 0)
  808. pImeCtx->SetCandidateFormIndex(CFS_DEFAULT, 0);
  809. // Remove right Help menu item on Pen Icon
  810. if (hwndIndicator)
  811. {
  812. PostMessage(hwndIndicator,
  813. INDICM_REMOVEDEFAULTMENUITEMS ,
  814. RDMI_RIGHT,
  815. (LPARAM)GetKeyboardLayout(NULL));
  816. // Set Pen Icon
  817. SetIndicator(pImeCtx);
  818. }
  819. // For display Status window.
  820. ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
  821. if (IsCicero() && lpUIPrivate->m_pCicToolbar)
  822. lpUIPrivate->m_pCicToolbar->SetCurrentIC(pImeCtx);
  823. }
  824. LOnImeSetContextExit2:
  825. GlobalUnlock(hUIPrivate);
  826. LOnImeSetContextExit:
  827. LPCImePadSvr lpCImePadSvr = CImePadSvr::GetCImePadSvr();
  828. if(lpCImePadSvr)
  829. {
  830. BOOL fAct = (BOOL)(fOn && hIMC);
  831. if (fAct)
  832. {
  833. IImeIPoint1* pIP = GetImeIPoint(hIMC);
  834. //HWND hWnd = GetStatusWnd(hUIWnd);
  835. //ImePadSetCurrentIPoint(hWnd, pIp);
  836. lpCImePadSvr->SetIUnkIImeIPoint((IUnknown *)pIP);
  837. //UpdatePadButton(pUI->GetWnd());
  838. // Don't need to repaint. StatusOnPaint will do it
  839. //if (hWnd)
  840. // InvalidateRect(hWnd, NULL, fFalse);
  841. }
  842. lpCImePadSvr->Notify(IMEPADNOTIFY_ACTIVATECONTEXT, fAct, 0);
  843. }
  844. return;
  845. }
  846. ///////////////////////////////////////////////////////////////////////////////
  847. // WM_IME_SELECT sent when user change IME
  848. void PASCAL OnImeSelect(HWND hUIWnd, BOOL fOn)
  849. {
  850. HGLOBAL hUIPrivate;
  851. LPUIPRIV lpUIPrivate;
  852. HWND hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
  853. HIMC hIMC;
  854. PCIMECtx pImeCtx;
  855. Dbg(DBGID_UI, TEXT("OnImeSelect(): hUIWnd = 0x%Xm fOn = %d"), hUIWnd, fOn);
  856. // Get UI private memory
  857. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  858. if (hUIPrivate == 0 || (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) == 0)
  859. {
  860. ShowUI(hUIWnd, SW_HIDE);
  861. // Set disabled Pen Icon
  862. SetIndicator((PCIMECtx)NULL);
  863. return;
  864. }
  865. // Init Cicero service
  866. CiceroInitialize();
  867. // If Cicero enabled, init toolbar
  868. if (IsCicero())
  869. {
  870. // Create Toolbar object and store it to private memory
  871. if (lpUIPrivate->m_pCicToolbar == NULL)
  872. lpUIPrivate->m_pCicToolbar = new CToolBar();
  873. DbgAssert(lpUIPrivate->m_pCicToolbar != NULL);
  874. }
  875. hIMC = GethImcFromHwnd(hUIWnd);
  876. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  877. {
  878. ShowUI(hUIWnd, SW_HIDE);
  879. // Set disabled Pen Icon
  880. SetIndicator((PCIMECtx)NULL);
  881. // Disable cicero buttons
  882. if (IsCicero() && lpUIPrivate->m_pCicToolbar)
  883. lpUIPrivate->m_pCicToolbar->SetCurrentIC(NULL);
  884. return;
  885. }
  886. if (fOn)
  887. {
  888. // Store UI Window handle to TLS. Sometimes when user switch IME only WM_IME_SELECT sent. No WM_IME_SETCONTEXT msg.
  889. SetActiveUIWnd(hUIWnd);
  890. if (pImeCtx->GetCandidateFormIndex(0) != 0)
  891. pImeCtx->SetCandidateFormIndex(CFS_DEFAULT, 0);
  892. // Remove right Help menu item on Pen Icon
  893. if (hwndIndicator)
  894. {
  895. Dbg(DBGID_UI, TEXT("OnImeSelect(): Post indicator message"), hUIWnd, fOn);
  896. PostMessage(hwndIndicator,
  897. INDICM_REMOVEDEFAULTMENUITEMS ,
  898. RDMI_RIGHT,
  899. (LPARAM)GetKeyboardLayout(NULL));
  900. // Set Pen Icon
  901. SetIndicator(pImeCtx);
  902. }
  903. // If Cicero enabled, init toolbar
  904. if (IsCicero() && lpUIPrivate->m_pCicToolbar)
  905. lpUIPrivate->m_pCicToolbar->SetCurrentIC(pImeCtx);
  906. }
  907. // IME PAD
  908. LPCImePadSvr lpCImePadSvr = CImePadSvr::GetCImePadSvr();
  909. if(lpCImePadSvr)
  910. {
  911. BOOL fAct = (BOOL)(fOn && hIMC);
  912. if (fAct)
  913. {
  914. IImeIPoint1* pIP = GetImeIPoint(hIMC);
  915. lpCImePadSvr->SetIUnkIImeIPoint((IUnknown *)pIP);
  916. }
  917. lpCImePadSvr->Notify(IMEPADNOTIFY_ACTIVATECONTEXT, fAct, 0);
  918. }
  919. // Close input sontext here
  920. // Because ImeSelect has not called from IMM on WIN95.
  921. if (fOn == fFalse)
  922. {
  923. DWORD dwCMode = 0, dwSent = 0;
  924. // If Hanja conversion mode when uninit, cancel it.
  925. OurImmGetConversionStatus(hIMC, &dwCMode, &dwSent);
  926. if (dwCMode & IME_CMODE_HANJACONVERT)
  927. OurImmSetConversionStatus(hIMC, dwCMode & ~IME_CMODE_HANJACONVERT, dwSent);
  928. // if interim state, make complete current comp string
  929. // But IMM sends CPS_CANCEL when user change layout
  930. if (pImeCtx->GetCompBufLen())
  931. {
  932. pImeCtx->FinalizeCurCompositionChar();
  933. pImeCtx->GenerateMessage();
  934. }
  935. CloseInputContext(hIMC);
  936. }
  937. GlobalUnlock(hUIPrivate);
  938. }
  939. HWND PASCAL GetStatusWnd(HWND hUIWnd)
  940. {
  941. HGLOBAL hUIPrivate;
  942. LPUIPRIV lpUIPrivate;
  943. HWND hStatusWnd;
  944. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  945. if (!hUIPrivate) // can not darw status window
  946. return (HWND)NULL;
  947. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  948. if (!lpUIPrivate) // can not draw status window
  949. return (HWND)NULL;
  950. hStatusWnd = lpUIPrivate->hStatusWnd;
  951. GlobalUnlock(hUIPrivate);
  952. return (hStatusWnd);
  953. }
  954. HWND PASCAL GetCandWnd(HWND hUIWnd) // UI window
  955. {
  956. HGLOBAL hUIPrivate;
  957. LPUIPRIV lpUIPrivate;
  958. HWND hCandWnd;
  959. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  960. if (!hUIPrivate) // can not darw candidate window
  961. return (HWND)NULL;
  962. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  963. if (!lpUIPrivate) // can not draw candidate window
  964. return (HWND)NULL;
  965. hCandWnd = lpUIPrivate->hCandWnd;
  966. GlobalUnlock(hUIPrivate);
  967. return (hCandWnd);
  968. }
  969. HWND PASCAL GetCompWnd(HWND hUIWnd) // UI window
  970. {
  971. HGLOBAL hUIPrivate;
  972. LPUIPRIV lpUIPrivate;
  973. HWND hCompWnd;
  974. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  975. if (!hUIPrivate) // can not draw comp window
  976. return (HWND)NULL;
  977. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  978. if (!lpUIPrivate) // can not draw comp window
  979. return (HWND)NULL;
  980. hCompWnd = lpUIPrivate->hCompWnd;
  981. GlobalUnlock(hUIPrivate);
  982. return (hCompWnd);
  983. }
  984. LRESULT PASCAL GetCandPos(HWND hUIWnd, LPCANDIDATEFORM lpCandForm)
  985. {
  986. HWND hCandWnd;
  987. RECT rcCandWnd;
  988. HIMC hIMC;
  989. PCIMECtx pImeCtx;
  990. if (lpCandForm->dwIndex != 0)
  991. return (1L);
  992. hCandWnd = GetCandWnd(hUIWnd);
  993. if (!hCandWnd)
  994. return (1L);
  995. if (!GetWindowRect(hCandWnd, &rcCandWnd))
  996. return (1L);
  997. hIMC = GethImcFromHwnd(hUIWnd);
  998. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  999. return (1L);
  1000. //*lpCandForm = lpIMC->cfCandForm[0];
  1001. lpCandForm->dwIndex = pImeCtx->GetCandidateFormIndex(0);
  1002. lpCandForm->dwStyle = pImeCtx->GetCandidateFormStyle(0);
  1003. pImeCtx->GetCandidateForm(&lpCandForm->rcArea, 0);
  1004. lpCandForm->ptCurrentPos = *(LPPOINT)&rcCandWnd;
  1005. return (0L);
  1006. }
  1007. LRESULT PASCAL GetCompPos(HWND hUIWnd, LPCOMPOSITIONFORM lpCompForm)
  1008. {
  1009. HWND hCompWnd;
  1010. RECT rcCompWnd;
  1011. HIMC hIMC;
  1012. PCIMECtx pImeCtx;
  1013. hCompWnd = GetCompWnd(hUIWnd);
  1014. if (!hCompWnd)
  1015. return (1L);
  1016. if (!GetWindowRect(hCompWnd, &rcCompWnd))
  1017. return (1L);
  1018. hIMC = GethImcFromHwnd(hUIWnd);
  1019. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  1020. return (1L);
  1021. lpCompForm->dwStyle = pImeCtx->GetCompositionFormStyle();
  1022. pImeCtx->GetCompositionForm(&lpCompForm->ptCurrentPos);
  1023. pImeCtx->GetCompositionForm(&lpCompForm->rcArea);
  1024. return (0L);
  1025. }
  1026. ///////////////////////////////////////////////////////////////////////////////
  1027. // Popup menu message handler
  1028. void PASCAL UIWndOnCommand(HWND hUIWnd, INT id, HWND hWndCtl, UINT codeNotify)
  1029. {
  1030. HIMC hIMC;
  1031. PCIMECtx pImeCtx;
  1032. CHAR szBuffer[256];
  1033. CIMEData ImeData(CIMEData::SMReadWrite);
  1034. szBuffer[0] = '\0';
  1035. hIMC = GethImcFromHwnd(hUIWnd);
  1036. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  1037. return;
  1038. switch (id)
  1039. {
  1040. case ID_CONFIG:
  1041. ImeConfigure(0, pImeCtx->GetAppWnd(), IME_CONFIG_GENERAL, NULL);
  1042. break;
  1043. case ID_ABOUT:
  1044. OurLoadStringA(vpInstData->hInst, IDS_PROGRAM, szBuffer, sizeof(szBuffer));
  1045. ShellAbout(pImeCtx->GetAppWnd(), szBuffer, NULL, (HICON)LoadImage((HINSTANCE)vpInstData->hInst,
  1046. MAKEINTRESOURCE(IDI_UNIKOR), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR));
  1047. break;
  1048. //////////////////////////////////////////////////////////////////////
  1049. // IME internal Keyboard layout change message
  1050. case ID_2BEOLSIK:
  1051. case ID_3BEOLSIK390:
  1052. case ID_3BEOLSIKFINAL :
  1053. if (ImeData.GetCurrentBeolsik() != (UINT)(id - ID_2BEOLSIK))
  1054. {
  1055. if (pImeCtx->GetAutomata())
  1056. pImeCtx->GetAutomata()->InitState();
  1057. if (pImeCtx->GetGData())
  1058. pImeCtx->GetGData()->SetCurrentBeolsik(id - ID_2BEOLSIK);
  1059. if (pImeCtx->GetAutomata())
  1060. pImeCtx->GetAutomata()->InitState();
  1061. SetRegValues(GETSET_REG_IMEKL);
  1062. }
  1063. break;
  1064. //////////////////////////////////////////////////////////////////////
  1065. // Han/Eng Toggle
  1066. case ID_HANGUL_MODE :
  1067. if (!(pImeCtx->GetConversionMode() & IME_CMODE_HANGUL))
  1068. {
  1069. OurImmSetConversionStatus(hIMC,
  1070. pImeCtx->GetConversionMode() ^ IME_CMODE_HANGUL,
  1071. pImeCtx->GetSentenceMode());
  1072. }
  1073. break;
  1074. case ID_ENGLISH_MODE :
  1075. if (pImeCtx->GetConversionMode() & IME_CMODE_HANGUL)
  1076. {
  1077. OurImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
  1078. OurImmSetConversionStatus(hIMC,
  1079. pImeCtx->GetConversionMode() ^ IME_CMODE_HANGUL,
  1080. pImeCtx->GetSentenceMode());
  1081. }
  1082. break;
  1083. //////////////////////////////////////////////////////////////////////
  1084. // Hangul deletion per jaso or char.
  1085. case ID_JASO_DELETION:
  1086. ImeData.SetJasoDel(!ImeData.GetJasoDel());
  1087. SetRegValues(GETSET_REG_JASODEL);
  1088. break;
  1089. default :
  1090. Dbg(DBGID_UI, TEXT("UIWndOnCommand() - Unknown command"));
  1091. break;
  1092. }
  1093. return;
  1094. }
  1095. void UIPopupMenu(HWND hUIWnd)
  1096. {
  1097. HMENU hMenu, hPopupMenu;
  1098. POINT ptCurrent;
  1099. UINT uiCurSel;
  1100. HIMC hIMC;
  1101. PCIMECtx pImeCtx;
  1102. CIMEData ImeData;
  1103. hIMC = GethImcFromHwnd(hUIWnd);
  1104. if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
  1105. return;
  1106. GetCursorPos(&ptCurrent);
  1107. hMenu = OurLoadMenu(vpInstData->hInst, MAKEINTRESOURCE(IDR_STATUS_POPUP));
  1108. if (hMenu != NULL)
  1109. {
  1110. hPopupMenu = GetSubMenu(hMenu, 0);
  1111. if (hPopupMenu == NULL)
  1112. {
  1113. DestroyMenu(hMenu);
  1114. return;
  1115. }
  1116. // Keyboard type selection radio button
  1117. uiCurSel = ID_2BEOLSIK + ImeData.GetCurrentBeolsik();
  1118. CheckMenuRadioItem(hPopupMenu, ID_2BEOLSIK, ID_3BEOLSIKFINAL, uiCurSel, MF_BYCOMMAND);
  1119. // Han/Eng mode selection radio button
  1120. uiCurSel = ID_HANGUL_MODE + ((pImeCtx->GetConversionMode() & IME_CMODE_HANGUL) ? 0 : 1);
  1121. CheckMenuRadioItem(hPopupMenu, ID_HANGUL_MODE, ID_ENGLISH_MODE, uiCurSel, MF_BYCOMMAND);
  1122. // Hangul jaso deletion
  1123. if (ImeData.GetJasoDel())
  1124. CheckMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_CHECKED);
  1125. else
  1126. CheckMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_UNCHECKED);
  1127. // if Winlogon process, gray all config menu
  1128. if (vpInstData->dwSystemInfoFlags & IME_SYSINFO_WINLOGON)
  1129. {
  1130. EnableMenuItem(hPopupMenu, ID_CONFIG, MF_BYCOMMAND | MF_GRAYED);
  1131. EnableMenuItem(hPopupMenu, ID_2BEOLSIK, MF_BYCOMMAND | MF_GRAYED);
  1132. EnableMenuItem(hPopupMenu, ID_3BEOLSIK390, MF_BYCOMMAND | MF_GRAYED);
  1133. EnableMenuItem(hPopupMenu, ID_3BEOLSIKFINAL, MF_BYCOMMAND | MF_GRAYED);
  1134. EnableMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_GRAYED);
  1135. }
  1136. TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  1137. ptCurrent.x, ptCurrent.y, 0, hUIWnd, NULL);
  1138. DestroyMenu(hMenu);
  1139. }
  1140. }
  1141. BOOL PASCAL SetIndicator(PCIMECtx pImeCtx)
  1142. {
  1143. ATOM atomIndicator;
  1144. CHAR sztooltip[IMEMENUITEM_STRING_SIZE];
  1145. int nIconIndex;
  1146. HWND hwndIndicator;
  1147. Dbg(DBGID_Tray, TEXT("SetIndicator Enter"));
  1148. hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
  1149. if (!hwndIndicator)
  1150. {
  1151. Dbg(DBGID_Tray, TEXT("!!! WARNING !!!: Indicator window not found"));
  1152. return fFalse;
  1153. }
  1154. // init sztooltip
  1155. sztooltip[0] = 0;
  1156. // Default value is disabled.
  1157. OurLoadStringA(vpInstData->hInst, IDS_IME_TT_DISABLE, sztooltip, IMEMENUITEM_STRING_SIZE);
  1158. nIconIndex = 5;
  1159. if (pImeCtx)
  1160. {
  1161. // If IME closed, English half mode
  1162. if (pImeCtx->IsOpen() == fFalse)
  1163. {
  1164. OurLoadStringA(vpInstData->hInst, IDS_IME_TT_ENG_HALF, sztooltip, IMEMENUITEM_STRING_SIZE);
  1165. nIconIndex= 3;
  1166. }
  1167. else
  1168. {
  1169. // If Hangul mode
  1170. if (pImeCtx->GetConversionMode() & IME_CMODE_HANGUL)
  1171. {
  1172. if (pImeCtx->GetConversionMode() & IME_CMODE_FULLSHAPE)
  1173. {
  1174. OurLoadStringA(vpInstData->hInst, IDS_IME_TT_HANGUL_FULL, sztooltip, IMEMENUITEM_STRING_SIZE);
  1175. nIconIndex = 4;
  1176. }
  1177. else
  1178. {
  1179. OurLoadStringA(vpInstData->hInst, IDS_IME_TT_HANGUL_HALF, sztooltip, IMEMENUITEM_STRING_SIZE);
  1180. nIconIndex = 1;
  1181. }
  1182. }
  1183. else
  1184. // Non-Hangul mode
  1185. if (pImeCtx->GetConversionMode() & IME_CMODE_FULLSHAPE)
  1186. {
  1187. OurLoadStringA(vpInstData->hInst, IDS_IME_TT_ENG_FULL, sztooltip, IMEMENUITEM_STRING_SIZE);
  1188. nIconIndex = 2;
  1189. }
  1190. }
  1191. }
  1192. Dbg(DBGID_Tray, TEXT("SetIndicator: PostMessage: nIconIndex=%d"), nIconIndex);
  1193. PostMessage(hwndIndicator, INDICM_SETIMEICON, nIconIndex, (LPARAM)GetKeyboardLayout(NULL));
  1194. // Should use GlobalFindAtom b#57121
  1195. atomIndicator = GlobalFindAtom(sztooltip);
  1196. // If no global atom exist, add it
  1197. if (!atomIndicator)
  1198. atomIndicator = GlobalAddAtom(sztooltip);
  1199. DbgAssert(atomIndicator);
  1200. if (atomIndicator)
  1201. {
  1202. Dbg(DBGID_Tray, TEXT("SetIndicator: PostMessage: atomIndicator=%s"), sztooltip);
  1203. PostMessage(hwndIndicator, INDICM_SETIMETOOLTIPS, atomIndicator, (LPARAM)GetKeyboardLayout(NULL));
  1204. }
  1205. return fTrue;;
  1206. }