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.

464 lines
13 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. UISUBS.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #include "imerc.h"
  11. #if defined(UNIIME)
  12. #include "uniime.h"
  13. #endif
  14. /**********************************************************************/
  15. /* DrawDragBorder() */
  16. /**********************************************************************/
  17. void PASCAL DrawDragBorder(
  18. HWND hWnd, // window of IME is dragged
  19. LONG lCursorPos, // the cursor position
  20. LONG lCursorOffset) // the offset form cursor to window org
  21. {
  22. HDC hDC;
  23. int cxBorder, cyBorder;
  24. int x, y;
  25. RECT rcWnd;
  26. cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
  27. cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
  28. // get cursor position
  29. x = (*(LPPOINTS)&lCursorPos).x;
  30. y = (*(LPPOINTS)&lCursorPos).y;
  31. // calculate the org by the offset
  32. x -= (*(LPPOINTS)&lCursorOffset).x;
  33. y -= (*(LPPOINTS)&lCursorOffset).y;
  34. #if 0 // MultiMonitor support
  35. // check for the min boundary of the display
  36. if (x < sImeG.rcWorkArea.left) {
  37. x = sImeG.rcWorkArea.left;
  38. }
  39. if (y < sImeG.rcWorkArea.top) {
  40. y = sImeG.rcWorkArea.top;
  41. }
  42. #endif
  43. // check for the max boundary of the display
  44. GetWindowRect(hWnd, &rcWnd);
  45. #if 0 // MultiMonitor support
  46. if (x + rcWnd.right - rcWnd.left > sImeG.rcWorkArea.right) {
  47. x = sImeG.rcWorkArea.right - (rcWnd.right - rcWnd.left);
  48. }
  49. if (y + rcWnd.bottom - rcWnd.top > sImeG.rcWorkArea.bottom) {
  50. y = sImeG.rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
  51. }
  52. #endif
  53. // draw the moving track
  54. hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  55. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  56. // ->
  57. PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
  58. PATINVERT);
  59. // v
  60. PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
  61. cyBorder, PATINVERT);
  62. // _>
  63. PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
  64. rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
  65. // v
  66. PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
  67. - cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
  68. DeleteDC(hDC);
  69. return;
  70. }
  71. /**********************************************************************/
  72. /* DrawFrameBorder() */
  73. /**********************************************************************/
  74. void PASCAL DrawFrameBorder( // border of IME
  75. HDC hDC,
  76. HWND hWnd) // window of IME
  77. {
  78. RECT rcWnd;
  79. int xWi, yHi;
  80. GetWindowRect(hWnd, &rcWnd);
  81. xWi = rcWnd.right - rcWnd.left;
  82. yHi = rcWnd.bottom - rcWnd.top;
  83. // 1, ->
  84. PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
  85. // 1, v
  86. PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
  87. // 1, _>
  88. PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
  89. // 1, v
  90. PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
  91. xWi -= 2;
  92. yHi -= 2;
  93. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  94. // 2, ->
  95. PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
  96. // 2, v
  97. PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
  98. // 2, v
  99. PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
  100. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  101. // 2, _>
  102. PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
  103. xWi -= 2;
  104. yHi -= 2;
  105. // 3, ->
  106. PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
  107. // 3, v
  108. PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
  109. // 3, v
  110. PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
  111. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  112. // 3, _>
  113. PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
  114. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  115. xWi -= 2;
  116. yHi -= 2;
  117. // 4, ->
  118. PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
  119. // 4, v
  120. PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
  121. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  122. // 4, v
  123. PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
  124. // 4, _>
  125. PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
  126. return;
  127. }
  128. /**********************************************************************/
  129. /* ContextMenuWndProc() */
  130. /**********************************************************************/
  131. #if defined(UNIIME)
  132. LRESULT WINAPI UniContextMenuWndProc(
  133. LPINSTDATAL lpInstL,
  134. LPIMEL lpImeL,
  135. #else
  136. LRESULT CALLBACK ContextMenuWndProc(
  137. #endif
  138. HWND hCMenuWnd,
  139. UINT uMsg,
  140. WPARAM wParam,
  141. LPARAM lParam)
  142. {
  143. switch (uMsg) {
  144. case WM_DESTROY:
  145. {
  146. HWND hUIWnd;
  147. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  148. if (hUIWnd) {
  149. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  150. IMN_PRIVATE_CMENUDESTROYED);
  151. }
  152. }
  153. break;
  154. case WM_USER_DESTROY:
  155. {
  156. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  157. DestroyWindow(hCMenuWnd);
  158. }
  159. break;
  160. case WM_COMMAND:
  161. switch (LOWORD(wParam)) {
  162. case IDM_SOFTKBD:
  163. case IDM_SYMBOL:
  164. {
  165. HWND hUIWnd;
  166. HIMC hIMC;
  167. DWORD fdwConversion=0;
  168. DWORD fdwSentence=0;
  169. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  170. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  171. ImmGetConversionStatus(hIMC, &fdwConversion,
  172. &fdwSentence);
  173. if (LOWORD(wParam) == IDM_SOFTKBD) {
  174. ImmSetConversionStatus(hIMC, fdwConversion ^
  175. IME_CMODE_SOFTKBD, fdwSentence);
  176. }
  177. if (LOWORD(wParam) == IDM_SYMBOL) {
  178. ImmSetConversionStatus(hIMC, fdwConversion ^
  179. IME_CMODE_SYMBOL, fdwSentence);
  180. }
  181. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  182. }
  183. break;
  184. case IDM_PROPERTIES:
  185. #if defined(UNIIME)
  186. UniImeConfigure(lpInstL, lpImeL,
  187. GetKeyboardLayout(0), hCMenuWnd, IME_CONFIG_GENERAL, NULL);
  188. #else
  189. ImeConfigure(GetKeyboardLayout(0), hCMenuWnd,
  190. IME_CONFIG_GENERAL, NULL);
  191. #endif
  192. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  193. break;
  194. default:
  195. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  196. }
  197. break;
  198. case WM_CLOSE:
  199. {
  200. HMENU hMenu;
  201. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  202. if (hMenu) {
  203. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  204. DestroyMenu(hMenu);
  205. }
  206. }
  207. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  208. default:
  209. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  210. }
  211. return (0L);
  212. }
  213. /**********************************************************************/
  214. /* ContextMenu() */
  215. /**********************************************************************/
  216. void PASCAL ContextMenu(
  217. #if defined(UNIIME)
  218. LPINSTDATAL lpInstL,
  219. LPIMEL lpImeL,
  220. #endif
  221. HWND hStatusWnd,
  222. int x,
  223. int y)
  224. {
  225. HWND hUIWnd;
  226. HWND hCMenuWnd;
  227. HGLOBAL hUIPrivate;
  228. LPUIPRIV lpUIPrivate;
  229. HIMC hIMC;
  230. LPINPUTCONTEXT lpIMC;
  231. HMENU hMenu, hCMenu;
  232. RECT rcWorkArea;
  233. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  234. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  235. if (!hIMC) {
  236. return;
  237. }
  238. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  239. if (!lpIMC) {
  240. return;
  241. }
  242. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  243. if (!hUIPrivate) {
  244. goto ContextMenuUnlockIMC;
  245. }
  246. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  247. if (!lpUIPrivate) {
  248. goto ContextMenuUnlockIMC;
  249. }
  250. #if 1 // MultiMonitor support
  251. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  252. #endif
  253. if (lpUIPrivate->hCMenuWnd) {
  254. SetWindowPos(lpUIPrivate->hCMenuWnd, NULL,
  255. rcWorkArea.left, rcWorkArea.top, 0, 0,
  256. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  257. } else {
  258. // this is important to assign owner window, otherwise the focus
  259. // will be gone
  260. // When UI terminate, it need to destroy this window
  261. lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  262. lpImeL->szCMenuClassName, TEXT("Context Menu"),
  263. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  264. lpIMC->hWnd, (HMENU)NULL, lpInstL->hInst, NULL);
  265. }
  266. hCMenuWnd = lpUIPrivate->hCMenuWnd;
  267. // Unlock before we call into TrackPopupMenu().
  268. GlobalUnlock(hUIPrivate);
  269. if (!hCMenuWnd) {
  270. goto ContextMenuUnlockIMC;
  271. }
  272. hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDMN_CONTEXT_MENU));
  273. hCMenu = GetSubMenu(hMenu, 0);
  274. SetWindowLongPtr(hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
  275. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
  276. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  277. EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  278. EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
  279. } else if (lpIMC->fOpen) {
  280. // can not go into symbol mode
  281. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  282. EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  283. } else {
  284. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  285. CheckMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_CHECKED);
  286. }
  287. }
  288. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  289. CheckMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_CHECKED);
  290. }
  291. } else {
  292. EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
  293. EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
  294. }
  295. TrackPopupMenu(hCMenu, TPM_RIGHTBUTTON, x, y, 0,
  296. hCMenuWnd, NULL);
  297. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  298. if (hMenu) {
  299. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  300. DestroyMenu(hMenu);
  301. }
  302. ContextMenuUnlockIMC:
  303. ImmUnlockIMC(hIMC);
  304. return;
  305. }
  306. #if 1 // MultiMonitor support
  307. /**********************************************************************/
  308. /* ImeMonitorWorkAreaFromWindow() */
  309. /**********************************************************************/
  310. RECT PASCAL ImeMonitorWorkAreaFromWindow(
  311. HWND hAppWnd)
  312. {
  313. HMONITOR hMonitor;
  314. hMonitor = MonitorFromWindow(hAppWnd, MONITOR_DEFAULTTONEAREST);
  315. if (hMonitor) {
  316. MONITORINFO sMonitorInfo;
  317. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  318. // init a default value to avoid GetMonitorInfo fails
  319. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  320. #ifdef UNICODE
  321. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  322. #else
  323. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  324. #endif
  325. return sMonitorInfo.rcWork;
  326. } else {
  327. return sImeG.rcWorkArea;
  328. }
  329. }
  330. /**********************************************************************/
  331. /* ImeMonitorWorkAreaFromPoint() */
  332. /**********************************************************************/
  333. RECT PASCAL ImeMonitorWorkAreaFromPoint(
  334. POINT ptPoint)
  335. {
  336. HMONITOR hMonitor;
  337. hMonitor = MonitorFromPoint(ptPoint, MONITOR_DEFAULTTONEAREST);
  338. if (hMonitor) {
  339. MONITORINFO sMonitorInfo;
  340. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  341. // init a default value to avoid GetMonitorInfo fails
  342. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  343. #ifdef UNICODE
  344. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  345. #else
  346. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  347. #endif
  348. return sMonitorInfo.rcWork;
  349. } else {
  350. return sImeG.rcWorkArea;
  351. }
  352. }
  353. /**********************************************************************/
  354. /* ImeMonitorWorkAreaFromRect() */
  355. /**********************************************************************/
  356. RECT PASCAL ImeMonitorWorkAreaFromRect(
  357. LPRECT lprcRect)
  358. {
  359. HMONITOR hMonitor;
  360. hMonitor = MonitorFromRect(lprcRect, MONITOR_DEFAULTTONEAREST);
  361. if (hMonitor) {
  362. MONITORINFO sMonitorInfo;
  363. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  364. // init a default value to avoid GetMonitorInfo fails
  365. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  366. #ifdef UNICODE
  367. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  368. #else
  369. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  370. #endif
  371. return sMonitorInfo.rcWork;
  372. } else {
  373. return sImeG.rcWorkArea;
  374. }
  375. }
  376. #endif