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.

276 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. imewnd.cpp
  5. Abstract:
  6. This file implements the Default IME window Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "cdimm.h"
  13. #include "globals.h"
  14. #include "defs.h"
  15. #include "imewnd.h"
  16. #include "imewndhd.h"
  17. BOOL
  18. CDefaultIMEWindow::_CreateDefaultIMEWindow(
  19. HIMC hDefIMC
  20. )
  21. {
  22. #ifndef CICERO_4678
  23. //
  24. // If m_hDefaultIMEWnd's owner is IMM32, then this value always valid hWnd.
  25. // For CICERO_4678, we should remove this code because subclass window hook
  26. // never start after Deactivate() and Activate().
  27. // In Trident and go to another Web page, Trident calls Deactivate() and Activate(),
  28. // first Deactivate() calls CDefaultIMEWindow::Stop() and
  29. // next Activate() calls here, however m_hDefaultIMEWnd already exist, then
  30. // returns immediately. Never calls CDefaultIMEWindow::Start().
  31. // Note: Cicero bug d/b #4678
  32. //
  33. if (m_hDefaultIMEWnd)
  34. /*
  35. * already exist IME window.
  36. */
  37. return TRUE;
  38. #endif
  39. if (IsOnImm()) {
  40. //
  41. // Create dummy default IME window.
  42. //
  43. // When the IsOnImm() is TRUE, this function could get the default IME window handle
  44. // by using imm32.Imm32_GetDefaultIMEWnd() function.
  45. // Imm32's GetDefaultIMEWnd might be return no IME window when no any parent window
  46. // in this thread.
  47. // However, we can assume that GetDefaultIMEWnd must return a valid IME window.
  48. // Because, _CreateIMEWindow() function always create a dummy default IME
  49. // window.
  50. //
  51. if (m_hDummyDefaultIMEWnd == NULL) {
  52. m_hDummyDefaultIMEWnd = _CreateIMEWindow(NULL);
  53. }
  54. #ifdef CICERO_4678
  55. if (m_hDefaultIMEWnd == NULL) {
  56. Imm32_GetDefaultIMEWnd(NULL, &m_hDefaultIMEWnd);
  57. }
  58. #else
  59. Imm32_GetDefaultIMEWnd(NULL, &m_hDefaultIMEWnd);
  60. #endif
  61. if (IsWindow(m_hDefaultIMEWnd) &&
  62. //
  63. // Set subclass window procedure.
  64. //
  65. Start()
  66. ) {
  67. CIMEWindowHandler* pimeui = GetImeWndHandler(m_hDefaultIMEWnd, TRUE);
  68. if (pimeui == NULL)
  69. return FALSE;
  70. pimeui->ImeWndCreateHandler(GetWindowLong(m_hDefaultIMEWnd, GWL_STYLE),
  71. hDefIMC);
  72. }
  73. }
  74. else {
  75. /*
  76. * NT5 have a IME class.
  77. */
  78. if (! IsOnNT5()) {
  79. WNDCLASSEX wcWndCls;
  80. wcWndCls.cbSize = sizeof(WNDCLASSEX);
  81. wcWndCls.cbClsExtra = 0;
  82. wcWndCls.cbWndExtra = 0;
  83. wcWndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  84. wcWndCls.hInstance = g_hInst;
  85. wcWndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
  86. wcWndCls.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
  87. wcWndCls.lpszMenuName = (LPTSTR)NULL;
  88. wcWndCls.hIconSm = NULL;
  89. wcWndCls.style = CS_GLOBALCLASS;
  90. wcWndCls.lpfnWndProc = ImeWndProcA;
  91. wcWndCls.lpszClassName = "IME";
  92. if (! RegisterClassEx(&wcWndCls)) {
  93. return FALSE;
  94. }
  95. m_bMyRegisterClass = TRUE;
  96. }
  97. if (m_hDefaultIMEWnd == NULL) {
  98. m_hDefaultIMEWnd = _CreateIMEWindow(hDefIMC);
  99. if (m_hDefaultIMEWnd)
  100. m_bMyCreateWindow = TRUE;
  101. else
  102. return FALSE;
  103. }
  104. if (IsOnNT5() && IsWindow(m_hDefaultIMEWnd) && ! m_bMyRegisterClass &&
  105. //
  106. // Set subclass window procedure.
  107. //
  108. Start()
  109. ) {
  110. CIMEWindowHandler* pimeui = GetImeWndHandler(m_hDefaultIMEWnd, TRUE);
  111. if (pimeui == NULL)
  112. return FALSE;
  113. pimeui->ImeWndCreateHandler(GetWindowLong(m_hDefaultIMEWnd, GWL_STYLE),
  114. hDefIMC);
  115. }
  116. }
  117. if (m_hDefaultIMEWnd == NULL)
  118. return FALSE;
  119. else
  120. return TRUE;
  121. }
  122. BOOL
  123. CDefaultIMEWindow::_DestroyDefaultIMEWindow(
  124. )
  125. {
  126. Stop();
  127. if (IsWindow(m_hDummyDefaultIMEWnd)) {
  128. DestroyWindow(m_hDummyDefaultIMEWnd);
  129. }
  130. if (m_bMyCreateWindow) {
  131. DestroyWindow(m_hDefaultIMEWnd);
  132. m_bMyCreateWindow = FALSE;
  133. m_hDefaultIMEWnd = NULL;
  134. }
  135. else if (IsWindow(m_hDefaultIMEWnd)) {
  136. //
  137. // This DefaultIMEWnd is owned by IMM32.
  138. // If still exist DefaultIMEWnd, then DIMM12 never receive WM_NCDESTROY message
  139. // in CIMEWindowHandler::ImeWndProcWorker.
  140. // We need clean up memory of CIMEWindowHandler.
  141. //
  142. CIMEWindowHandler* pimeui = GetImeWndHandler(m_hDefaultIMEWnd);
  143. if (pimeui == NULL)
  144. return FALSE;
  145. pimeui->ImeWndFinalDestroyHandler();
  146. }
  147. if (m_bMyRegisterClass) {
  148. UnregisterClass("IME", g_hInst);
  149. m_bMyRegisterClass = FALSE;
  150. }
  151. return TRUE;
  152. };
  153. HWND
  154. CDefaultIMEWindow::_CreateIMEWindow(
  155. HIMC hDefIMC
  156. )
  157. {
  158. return CreateWindow("IME",
  159. "",
  160. WS_DISABLED | WS_POPUP,
  161. 0, 0, 0, 0, // x, y, width, height
  162. NULL, // parent
  163. NULL, // menu
  164. g_hInst,
  165. hDefIMC); // lpParam
  166. }
  167. HRESULT
  168. CDefaultIMEWindow::GetDefaultIMEWnd(
  169. IN HWND hWnd,
  170. OUT HWND *phDefWnd
  171. )
  172. {
  173. if (IsOnImm()) {
  174. Imm32_GetDefaultIMEWnd(hWnd, phDefWnd);
  175. }
  176. else {
  177. if (hWnd == NULL) {
  178. *phDefWnd = m_hDefaultIMEWnd;
  179. }
  180. else {
  181. if (GetWindowThreadProcessId(hWnd, NULL) == GetCurrentThreadId()) {
  182. *phDefWnd = m_hDefaultIMEWnd;
  183. }
  184. else {
  185. return E_FAIL;
  186. }
  187. }
  188. }
  189. return S_OK;
  190. }
  191. LRESULT
  192. CDefaultIMEWindow::CallWindowProc(
  193. HWND hWnd,
  194. UINT uMsg,
  195. WPARAM wParam,
  196. LPARAM lParam
  197. )
  198. {
  199. if (m_SubclassWindowProc != 0) {
  200. switch (uMsg) {
  201. case WM_IME_SETCONTEXT:
  202. case WM_IME_SELECT:
  203. {
  204. WNDPROC pfn = Stop();
  205. LRESULT lRet = ::CallWindowProc(pfn, hWnd, uMsg, wParam, lParam);
  206. Start();
  207. return lRet;
  208. }
  209. }
  210. return ::CallWindowProc((WNDPROC)m_SubclassWindowProc, hWnd, uMsg, wParam, lParam);
  211. }
  212. else {
  213. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  214. }
  215. }
  216. LRESULT
  217. ImeWndProcA(
  218. HWND hwnd,
  219. UINT uMsg,
  220. WPARAM wParam,
  221. LPARAM lParam
  222. )
  223. {
  224. CIMEWindowHandler* pimeui = GetImeWndHandler(hwnd);
  225. if (pimeui == NULL)
  226. return 0L;
  227. return pimeui->ImeWndProcWorker(uMsg, wParam, lParam, FALSE);
  228. }
  229. LRESULT
  230. ImeWndProcW(
  231. HWND hwnd,
  232. UINT uMsg,
  233. WPARAM wParam,
  234. LPARAM lParam
  235. )
  236. {
  237. CIMEWindowHandler* pimeui = GetImeWndHandler(hwnd);
  238. if (pimeui == NULL)
  239. return 0L;
  240. return pimeui->ImeWndProcWorker(uMsg, wParam, lParam);
  241. }