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.

1195 lines
36 KiB

  1. /**************************************************************************\
  2. * Module Name: sftkbdc1.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Softkeyboard support for Simplified Chinese
  7. *
  8. * History:
  9. * 03-Jan-1996 wkwok Ported from Win95
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "softkbd.h"
  14. // Virtual Key for Letter Buttons
  15. CONST BYTE SKC1VirtKey[BUTTON_NUM_C1] = {
  16. VK_OEM_3, '1', '2', '3', '4', '5', '6','7', '8', '9', '0', VK_OEM_MINUS, VK_OEM_EQUAL,
  17. 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', VK_OEM_LBRACKET, VK_OEM_RBRACKET, VK_OEM_BSLASH,
  18. 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', VK_OEM_SEMICLN, VK_OEM_QUOTE,
  19. 'Z', 'X', 'C', 'V', 'B', 'N', 'M', VK_OEM_COMMA, VK_OEM_PERIOD, VK_OEM_SLASH,
  20. VK_BACK, VK_TAB, VK_CAPITAL, VK_RETURN, VK_SHIFT, VK_INSERT, VK_DELETE, VK_SPACE,
  21. VK_ESCAPE
  22. };
  23. POINT gptButtonPos[BUTTON_NUM_C1]; // button point array, in the client area
  24. BOOL gfSoftKbdC1Init = FALSE; // init flag
  25. /**********************************************************************\
  26. * InitSKC1ButtonPos -- init gptButtonPos
  27. *
  28. \**********************************************************************/
  29. VOID InitSKC1ButtonPos()
  30. {
  31. int i, x, y;
  32. // init the first row
  33. y = 0;
  34. for (i=0, x=X_ROW_LETTER_C1; i < COL_LETTER_C1; i++, x += W_LETTER_BTN_C1) {
  35. gptButtonPos[i].x = x;
  36. gptButtonPos[i].y = y;
  37. }
  38. gptButtonPos[BACKSP_TYPE_C1].x = x;
  39. gptButtonPos[BACKSP_TYPE_C1].y = y;
  40. // init the second row
  41. y += H_LETTER_BTN_C1;
  42. x = 0;
  43. gptButtonPos[TAB_TYPE_C1].x = x;
  44. gptButtonPos[TAB_TYPE_C1].y = y;
  45. for (i=0, x=X_ROW2_LETTER_C1; i < COL2_LETTER_C1; i++, x += W_LETTER_BTN_C1) {
  46. gptButtonPos[i + COL_LETTER_C1].x = x;
  47. gptButtonPos[i + COL_LETTER_C1].y = y;
  48. }
  49. // init the third row
  50. y += H_LETTER_BTN_C1;
  51. x = 0;
  52. gptButtonPos[CAPS_TYPE_C1].x = x;
  53. gptButtonPos[CAPS_TYPE_C1].y = y;
  54. for (i=0, x=X_ROW3_LETTER_C1; i < COL3_LETTER_C1; i++, x += W_LETTER_BTN_C1) {
  55. gptButtonPos[i + COL_LETTER_C1 + COL2_LETTER_C1].x = x;
  56. gptButtonPos[i + COL_LETTER_C1 + COL2_LETTER_C1].y = y;
  57. }
  58. gptButtonPos[ENTER_TYPE_C1].x = x;
  59. gptButtonPos[ENTER_TYPE_C1].y = y;
  60. // init the forth row
  61. y += H_LETTER_BTN_C1;
  62. x = 0;
  63. gptButtonPos[SHIFT_TYPE_C1].x = x;
  64. gptButtonPos[SHIFT_TYPE_C1].y = y;
  65. for (i=0, x=X_ROW4_LETTER_C1; i < COL4_LETTER_C1; i++, x += W_LETTER_BTN_C1) {
  66. gptButtonPos[i + COL_LETTER_C1 + COL2_LETTER_C1 + COL3_LETTER_C1].x = x;
  67. gptButtonPos[i + COL_LETTER_C1 + COL2_LETTER_C1 + COL3_LETTER_C1].y = y;
  68. }
  69. // init the bottom row
  70. y += H_LETTER_BTN_C1;
  71. x = 0;
  72. gptButtonPos[INS_TYPE_C1].x = x;
  73. gptButtonPos[INS_TYPE_C1].y = y;
  74. x = X_DEL_C1;
  75. gptButtonPos[DEL_TYPE_C1].x = x;
  76. gptButtonPos[DEL_TYPE_C1].y = y;
  77. x += W_DEL_C1 + 2 * BORDER_C1;
  78. gptButtonPos[SPACE_TYPE_C1].x = x;
  79. gptButtonPos[SPACE_TYPE_C1].y = y;
  80. x = X_ESC_C1;
  81. gptButtonPos[ESC_TYPE_C1].x = x;
  82. gptButtonPos[ESC_TYPE_C1].y = y;
  83. return;
  84. }
  85. /**********************************************************************\
  86. * SKC1DrawConvexRect --- draw button
  87. *
  88. * (x1,y1) x2-1
  89. * +----3------>^
  90. * |+----3-----||y1+1
  91. * || ||
  92. * 33 1 42
  93. * || ||
  94. * |V ||
  95. * |<----4-----+|
  96. * y2-1 ------2------+
  97. * (x2,y2)
  98. *
  99. * 1 - light gray
  100. * 2 - black
  101. * 3 - white
  102. * 4 - dark gray
  103. *
  104. \**********************************************************************/
  105. VOID SKC1DrawConvexRect(
  106. HDC hDC,
  107. int x,
  108. int y,
  109. int nWidth,
  110. int nHeight)
  111. {
  112. // paint background
  113. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  114. SelectObject(hDC, GetStockObject(BLACK_PEN));
  115. Rectangle(hDC, x, y, x + nWidth, y + nHeight);
  116. // paint white border
  117. SelectObject(hDC, GetStockObject(WHITE_BRUSH));
  118. PatBlt(hDC, x, y + nHeight - 1, BORDER_C1, -nHeight + 1, PATCOPY);
  119. PatBlt(hDC, x, y, nWidth - 1 , BORDER_C1, PATCOPY);
  120. // paint dark gray border
  121. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  122. PatBlt(hDC, x + 1, y + nHeight -1, nWidth - BORDER_C1, -1, PATCOPY);
  123. PatBlt(hDC, x + nWidth - 1, y + nHeight - 1, -1, -nHeight + BORDER_C1, PATCOPY);
  124. return;
  125. }
  126. /**********************************************************************\
  127. * SKC1InvertButton --- Invert Button
  128. *
  129. \**********************************************************************/
  130. VOID SKC1InvertButton(
  131. HDC hDC,
  132. int uKeyIndex)
  133. {
  134. int nWidth, nHeight;
  135. if (uKeyIndex < 0) return;
  136. if (uKeyIndex < LETTER_NUM_C1) {
  137. nWidth = W_LETTER_BTN_C1;
  138. nHeight = H_LETTER_BTN_C1;
  139. } else {
  140. switch (uKeyIndex) {
  141. case BACKSP_TYPE_C1:
  142. nWidth = W_BACKSP_C1 + 2 * BORDER_C1;
  143. nHeight = H_LETTER_BTN_C1;
  144. break;
  145. case TAB_TYPE_C1:
  146. nWidth = W_TAB_C1 + 2 * BORDER_C1;
  147. nHeight = H_LETTER_BTN_C1;
  148. break;
  149. case CAPS_TYPE_C1:
  150. nWidth = W_CAPS_C1 + 2 * BORDER_C1;
  151. nHeight = H_LETTER_BTN_C1;
  152. break;
  153. case ENTER_TYPE_C1:
  154. nWidth = W_ENTER_C1 + 2 * BORDER_C1;
  155. nHeight = H_LETTER_BTN_C1;
  156. break;
  157. case SHIFT_TYPE_C1:
  158. nWidth = W_SHIFT_C1 + 2 * BORDER_C1;
  159. nHeight = H_LETTER_BTN_C1;
  160. break;
  161. case INS_TYPE_C1:
  162. nWidth = W_INS_C1 + 2 * BORDER_C1;
  163. nHeight = H_BOTTOM_BTN_C1;
  164. break;
  165. case DEL_TYPE_C1:
  166. nWidth = W_DEL_C1 + 2 * BORDER_C1;
  167. nHeight = H_BOTTOM_BTN_C1;
  168. break;
  169. case SPACE_TYPE_C1:
  170. nWidth = W_SPACE_C1 + 2 * BORDER_C1;
  171. nHeight = H_BOTTOM_BTN_C1;
  172. break;
  173. case ESC_TYPE_C1:
  174. nWidth = W_ESC_C1 + 2 * BORDER_C1;
  175. nHeight = H_BOTTOM_BTN_C1;
  176. break;
  177. }
  178. }
  179. BitBlt(hDC, gptButtonPos[uKeyIndex].x, gptButtonPos[uKeyIndex].y,
  180. nWidth, nHeight, hDC, gptButtonPos[uKeyIndex].x , gptButtonPos[uKeyIndex].y,
  181. DSTINVERT);
  182. return;
  183. }
  184. /**********************************************************************\
  185. * SKC1DrawBitmap --- Draw bitmap within rectangle
  186. *
  187. \**********************************************************************/
  188. VOID SKC1DrawBitmap(
  189. HDC hDC,
  190. int x,
  191. int y,
  192. int nWidth,
  193. int nHeight,
  194. LPWSTR lpszBitmap)
  195. {
  196. HDC hMemDC;
  197. HBITMAP hBitmap, hOldBmp;
  198. hBitmap = LoadBitmap(ghInst, lpszBitmap);
  199. hMemDC = CreateCompatibleDC(hDC);
  200. hOldBmp = SelectObject(hMemDC, hBitmap);
  201. BitBlt(hDC, x, y, nWidth, nHeight, hMemDC, 0 , 0, SRCCOPY);
  202. SelectObject(hMemDC, hOldBmp);
  203. DeleteDC(hMemDC);
  204. DeleteObject(hBitmap);
  205. return;
  206. }
  207. /**********************************************************************\
  208. * SKC1DrawLabel -- Draw the label of button
  209. *
  210. \**********************************************************************/
  211. VOID SKC1DrawLabel(
  212. HDC hDC,
  213. LPWSTR lpszLabel)
  214. {
  215. HDC hMemDC;
  216. HBITMAP hBitmap, hOldBmp;
  217. int i, x;
  218. hBitmap = LoadBitmap(ghInst, lpszLabel);
  219. hMemDC = CreateCompatibleDC(hDC);
  220. hOldBmp = SelectObject(hMemDC, hBitmap);
  221. for (i=x=0; i < LETTER_NUM_C1; i++, x += SIZELABEL_C1){
  222. BitBlt(hDC, gptButtonPos[i].x + X_LABEL_C1, gptButtonPos[i].y + Y_LABEL_C1,
  223. SIZELABEL_C1, SIZELABEL_C1, hMemDC, x , 0, SRCCOPY);
  224. }
  225. SelectObject(hMemDC, hOldBmp);
  226. DeleteDC(hMemDC);
  227. DeleteObject(hBitmap);
  228. return;
  229. }
  230. /**********************************************************************\
  231. * InitSKC1Bitmap -- init bitmap
  232. *
  233. \**********************************************************************/
  234. VOID InitSKC1Bitmap(
  235. HDC hDC,
  236. RECT rcClient)
  237. {
  238. int i;
  239. // draw softkbd rectangle
  240. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  241. SelectObject(hDC, GetStockObject(NULL_PEN));
  242. Rectangle(hDC, rcClient.left, rcClient.top, rcClient.right + 1, rcClient.bottom + 1);
  243. // draw letter buttons
  244. for (i = 0; i < LETTER_NUM_C1; i++) {
  245. SKC1DrawConvexRect(hDC, gptButtonPos[i].x, gptButtonPos[i].y,
  246. W_LETTER_BTN_C1, H_LETTER_BTN_C1);
  247. }
  248. // draw letter label
  249. SKC1DrawLabel(hDC, MAKEINTRESOURCEW(LABEL_C1));
  250. // draw other buttons
  251. SKC1DrawConvexRect(hDC, gptButtonPos[BACKSP_TYPE_C1].x, gptButtonPos[BACKSP_TYPE_C1].y,
  252. W_BACKSP_C1 + 2 * BORDER_C1, H_LETTER_BTN_C1);
  253. SKC1DrawBitmap(hDC, gptButtonPos[BACKSP_TYPE_C1].x + BORDER_C1, gptButtonPos[BACKSP_TYPE_C1].y + BORDER_C1,
  254. W_BACKSP_C1, H_BACKSP_C1, MAKEINTRESOURCEW(BACKSP_C1));
  255. SKC1DrawConvexRect(hDC, gptButtonPos[TAB_TYPE_C1].x, gptButtonPos[TAB_TYPE_C1].y,
  256. W_TAB_C1 + 2 * BORDER_C1, H_LETTER_BTN_C1);
  257. SKC1DrawBitmap(hDC, gptButtonPos[TAB_TYPE_C1].x + BORDER_C1, gptButtonPos[TAB_TYPE_C1].y + BORDER_C1,
  258. W_TAB_C1, H_TAB_C1, MAKEINTRESOURCEW(TAB_C1));
  259. SKC1DrawConvexRect(hDC, gptButtonPos[CAPS_TYPE_C1].x, gptButtonPos[CAPS_TYPE_C1].y,
  260. W_CAPS_C1 + 2 * BORDER_C1, H_LETTER_BTN_C1);
  261. SKC1DrawBitmap(hDC, gptButtonPos[CAPS_TYPE_C1].x + BORDER_C1, gptButtonPos[CAPS_TYPE_C1].y + BORDER_C1,
  262. W_CAPS_C1, H_CAPS_C1, MAKEINTRESOURCEW(CAPS_C1));
  263. SKC1DrawConvexRect(hDC, gptButtonPos[ENTER_TYPE_C1].x, gptButtonPos[ENTER_TYPE_C1].y,
  264. W_ENTER_C1 + 2 * BORDER_C1, H_LETTER_BTN_C1);
  265. SKC1DrawBitmap(hDC, gptButtonPos[ENTER_TYPE_C1].x + BORDER_C1, gptButtonPos[ENTER_TYPE_C1].y + BORDER_C1,
  266. W_ENTER_C1, H_ENTER_C1, MAKEINTRESOURCEW(ENTER_C1));
  267. SKC1DrawConvexRect(hDC, gptButtonPos[SHIFT_TYPE_C1].x, gptButtonPos[SHIFT_TYPE_C1].y,
  268. W_SHIFT_C1 + 2 * BORDER_C1, H_LETTER_BTN_C1);
  269. SKC1DrawBitmap(hDC, gptButtonPos[SHIFT_TYPE_C1].x + BORDER_C1, gptButtonPos[SHIFT_TYPE_C1].y + BORDER_C1,
  270. W_SHIFT_C1, H_SHIFT_C1, MAKEINTRESOURCEW(SHIFT_C1));
  271. SKC1DrawConvexRect(hDC, gptButtonPos[INS_TYPE_C1].x, gptButtonPos[INS_TYPE_C1].y,
  272. W_INS_C1 + 2 * BORDER_C1, H_BOTTOM_BTN_C1);
  273. SKC1DrawBitmap(hDC, gptButtonPos[INS_TYPE_C1].x + BORDER_C1, gptButtonPos[INS_TYPE_C1].y + BORDER_C1,
  274. W_INS_C1, H_INS_C1, MAKEINTRESOURCEW(INS_C1));
  275. SKC1DrawConvexRect(hDC, gptButtonPos[DEL_TYPE_C1].x, gptButtonPos[DEL_TYPE_C1].y,
  276. W_DEL_C1 + 2 * BORDER_C1, H_BOTTOM_BTN_C1);
  277. SKC1DrawBitmap(hDC, gptButtonPos[DEL_TYPE_C1].x + BORDER_C1, gptButtonPos[DEL_TYPE_C1].y + BORDER_C1,
  278. W_DEL_C1, H_DEL_C1, MAKEINTRESOURCEW(DEL_C1));
  279. SKC1DrawConvexRect(hDC, gptButtonPos[SPACE_TYPE_C1].x, gptButtonPos[SPACE_TYPE_C1].y,
  280. W_SPACE_C1 + 2 * BORDER_C1, H_BOTTOM_BTN_C1);
  281. SKC1DrawConvexRect(hDC, gptButtonPos[ESC_TYPE_C1].x, gptButtonPos[ESC_TYPE_C1].y,
  282. W_ESC_C1 + 2 * BORDER_C1, H_BOTTOM_BTN_C1);
  283. SKC1DrawBitmap(hDC, gptButtonPos[ESC_TYPE_C1].x + BORDER_C1, gptButtonPos[ESC_TYPE_C1].y + BORDER_C1,
  284. W_ESC_C1, H_ESC_C1, MAKEINTRESOURCEW(ESC_C1));
  285. return;
  286. }
  287. /**********************************************************************\
  288. * CreateC1Window
  289. *
  290. * Init softkeyboard gloabl variabls, context and bitmap
  291. *
  292. \**********************************************************************/
  293. LRESULT CreateC1Window(
  294. HWND hSKWnd)
  295. {
  296. HGLOBAL hSKC1Ctxt;
  297. PSKC1CTXT pSKC1Ctxt;
  298. // alloc and lock hSKC1CTxt
  299. hSKC1Ctxt = GlobalAlloc(GHND, sizeof(SKC1CTXT));
  300. if (!hSKC1Ctxt) {
  301. return (-1L);
  302. }
  303. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  304. if (!pSKC1Ctxt) {
  305. GlobalFree(hSKC1Ctxt);
  306. return (-1L);
  307. }
  308. // save handle in SKC1_CONTEXT
  309. SetWindowLongPtr(hSKWnd, SKC1_CONTEXT, (LONG_PTR)hSKC1Ctxt);
  310. // init global varialbles
  311. if (!gfSoftKbdC1Init){
  312. InitSKC1ButtonPos();
  313. gfSoftKbdC1Init = TRUE;
  314. }
  315. // no index and default char set
  316. pSKC1Ctxt->uKeyIndex = -1;
  317. pSKC1Ctxt->lfCharSet = GB2312_CHARSET;
  318. // init softkeyboard
  319. {
  320. HDC hDC, hMemDC;
  321. HBITMAP hBitmap, hOldBmp;
  322. RECT rcClient;
  323. GetClientRect(hSKWnd, &rcClient);
  324. hDC = GetDC(hSKWnd);
  325. hMemDC = CreateCompatibleDC(hDC);
  326. hBitmap = CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
  327. rcClient.bottom - rcClient.top);
  328. ReleaseDC(hSKWnd, hDC);
  329. hOldBmp = SelectObject(hMemDC, hBitmap);
  330. InitSKC1Bitmap(hMemDC, rcClient);
  331. SelectObject(hMemDC, hOldBmp);
  332. pSKC1Ctxt->hSoftkbd = hBitmap; // save hBitmap in SKC1CTXT
  333. DeleteDC(hMemDC);
  334. }
  335. // unlock hSKC1CTxt
  336. GlobalUnlock(hSKC1Ctxt);
  337. return (0L);
  338. }
  339. /**********************************************************************\
  340. * DestroyC1Window
  341. *
  342. * Destroy softkeyboard context and bitmap
  343. *
  344. \**********************************************************************/
  345. VOID DestroyC1Window(
  346. HWND hSKWnd)
  347. {
  348. HGLOBAL hSKC1Ctxt;
  349. PSKC1CTXT pSKC1Ctxt;
  350. HWND hUIWnd;
  351. // Get and Lock hSKC1Ctxt
  352. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  353. if (!hSKC1Ctxt) return;
  354. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  355. if (!pSKC1Ctxt) return;
  356. if (pSKC1Ctxt->uState & FLAG_DRAG_C1) {
  357. SKC1DrawDragBorder(hSKWnd, &pSKC1Ctxt->ptSkCursor,
  358. &pSKC1Ctxt->ptSkOffset);
  359. }
  360. DeleteObject(pSKC1Ctxt->hSoftkbd); // delete hBitmap
  361. // Unlock and Free hSKC1Ctxt
  362. GlobalUnlock(hSKC1Ctxt);
  363. GlobalFree(hSKC1Ctxt);
  364. // send message to parent window
  365. hUIWnd = GetWindow(hSKWnd, GW_OWNER);
  366. if (hUIWnd) {
  367. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0);\
  368. }
  369. return;
  370. }
  371. /**********************************************************************\
  372. * ShowSKC1Window -- Show softkeyboard
  373. *
  374. \**********************************************************************/
  375. VOID ShowSKC1Window(
  376. HDC hDC,
  377. HWND hSKWnd)
  378. {
  379. HGLOBAL hSKC1Ctxt;
  380. PSKC1CTXT pSKC1Ctxt;
  381. // Get and Lock hSKC1Ctxt
  382. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  383. if (!hSKC1Ctxt) return;
  384. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  385. if (!pSKC1Ctxt) return;
  386. // create mem dc to show softkeyboard
  387. {
  388. HDC hMemDC;
  389. HBITMAP hOldBmp;
  390. RECT rcClient;
  391. hMemDC = CreateCompatibleDC(hDC);
  392. hOldBmp = SelectObject(hMemDC, pSKC1Ctxt->hSoftkbd);
  393. GetClientRect(hSKWnd, &rcClient);
  394. BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
  395. hMemDC, 0, 0, SRCCOPY);
  396. SelectObject(hMemDC, hOldBmp);
  397. DeleteDC(hMemDC);
  398. }
  399. // Unlock hSKC1Ctxt
  400. GlobalUnlock(hSKC1Ctxt);
  401. return;
  402. }
  403. /**********************************************************************\
  404. * UpdateSKC1Window -- update softkeyboard
  405. *
  406. \**********************************************************************/
  407. BOOL UpdateSKC1Window(
  408. HWND hSKWnd,
  409. LPSOFTKBDDATA lpSoftKbdData)
  410. {
  411. HGLOBAL hSKC1Ctxt;
  412. PSKC1CTXT pSKC1Ctxt;
  413. LOGFONT lfFont;
  414. HFONT hOldFont, hFont;
  415. HDC hDC, hMemDC;
  416. HBITMAP hOldBmp;
  417. int i;
  418. // check the lpSoftKbdData
  419. if (lpSoftKbdData->uCount!=2) return FALSE;
  420. // Get and Lock hSKC1Ctxt
  421. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  422. if (!hSKC1Ctxt) return FALSE;
  423. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  424. if (!pSKC1Ctxt) return FALSE;
  425. // create font
  426. hDC = GetDC(hSKWnd);
  427. hMemDC = CreateCompatibleDC(hDC);
  428. hOldBmp = SelectObject(hMemDC, pSKC1Ctxt->hSoftkbd);
  429. GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lfFont), &lfFont);
  430. lfFont.lfHeight = -SIZEFONT_C1;
  431. if (pSKC1Ctxt->lfCharSet != DEFAULT_CHARSET) {
  432. lfFont.lfCharSet = (BYTE)pSKC1Ctxt->lfCharSet;
  433. }
  434. hFont = CreateFontIndirect(&lfFont);
  435. hOldFont = SelectObject(hMemDC, hFont);
  436. // update shift/non-shift chars
  437. for (i=0; i < LETTER_NUM_C1; i++) {
  438. pSKC1Ctxt->wNonShiftCode[i] = lpSoftKbdData->wCode[0][SKC1VirtKey[i]];
  439. pSKC1Ctxt->wShiftCode[i] = lpSoftKbdData->wCode[1][SKC1VirtKey[i]];
  440. }
  441. SetBkColor(hMemDC, 0x00BFBFBF); // set text bk color ??
  442. for (i=0; i < LETTER_NUM_C1; i++) {
  443. int nchar;
  444. RECT rc;
  445. // draw shift char.
  446. rc.left = gptButtonPos[i].x + X_SHIFT_CHAR_C1;
  447. rc.top = gptButtonPos[i].y + Y_SHIFT_CHAR_C1;
  448. rc.right = rc.left + SIZEFONT_C1;
  449. rc.bottom = rc.top + SIZEFONT_C1;
  450. nchar = (pSKC1Ctxt->wShiftCode[i] == 0) ? 0 : 1;
  451. #if (WINVER >= 0x0400)
  452. DrawTextEx(hMemDC, (LPWSTR)&pSKC1Ctxt->wShiftCode[i],
  453. nchar, &rc, DT_CENTER, NULL);
  454. #else
  455. ExtTextOut(hMemDC,
  456. rc.left,
  457. rc.top,
  458. ETO_OPAQUE, &rc,
  459. (LPWSTR)&pSKC1Ctxt->wShiftCode[i], nchar, NULL);
  460. #endif
  461. // draw non-shift char.
  462. rc.left = gptButtonPos[i].x + X_NONSHIFT_CHAR_C1;
  463. rc.top = gptButtonPos[i].y + Y_NONSHIFT_CHAR_C1;
  464. rc.right = rc.left + SIZEFONT_C1;
  465. rc.bottom = rc.top + SIZEFONT_C1;
  466. nchar = (pSKC1Ctxt->wNonShiftCode[i] == 0) ? 0 : 1;
  467. #if (WINVER >= 0x0400)
  468. DrawTextEx(hMemDC, (LPWSTR)&pSKC1Ctxt->wNonShiftCode[i],
  469. nchar, &rc, DT_CENTER, NULL);
  470. #else
  471. ExtTextOut(hMemDC,
  472. rc.left,
  473. rc.top,
  474. ETO_OPAQUE, &rc,
  475. (LPWSTR)&pSKC1Ctxt->wNonShiftCode[i], nchar, NULL);
  476. #endif
  477. }
  478. // init states
  479. if (pSKC1Ctxt->uState & FLAG_SHIFT_C1){
  480. SKC1InvertButton(hMemDC, SHIFT_TYPE_C1);
  481. }
  482. pSKC1Ctxt->uState = 0;
  483. SelectObject(hMemDC, hOldBmp);
  484. SelectObject(hMemDC, hOldFont);
  485. DeleteDC(hMemDC);
  486. DeleteObject(hFont);
  487. ReleaseDC(hSKWnd,hDC);
  488. // Unlock hSKC1Ctxt
  489. GlobalUnlock(hSKC1Ctxt);
  490. return TRUE;
  491. }
  492. /**********************************************************************\
  493. * SKC1DrawDragBorder() -- Draw Drag Border
  494. *
  495. \**********************************************************************/
  496. VOID SKC1DrawDragBorder(
  497. HWND hWnd, // window is dragged
  498. LPPOINT lpptCursor, // the cursor position
  499. LPPOINT lpptOffset) // the offset form cursor to window org
  500. {
  501. HDC hDC;
  502. RECT rcWnd, rcWorkArea;
  503. int cxBorder, cyBorder;
  504. int x, y;
  505. extern void GetAllMonitorSize(LPRECT lprc);
  506. // get rectangle of work area
  507. GetAllMonitorSize(&rcWorkArea);
  508. cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
  509. cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
  510. // create DISPLAY dc to draw track
  511. hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
  512. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  513. // start point (left,top)
  514. x = lpptCursor->x - lpptOffset->x;
  515. y = lpptCursor->y - lpptOffset->y;
  516. // check for the min boundary of the display
  517. if (x < rcWorkArea.left) {
  518. x = rcWorkArea.left;
  519. }
  520. if (y < rcWorkArea.top) {
  521. y = rcWorkArea.top;
  522. }
  523. // check for the max boundary of the display
  524. GetWindowRect(hWnd, &rcWnd);
  525. if (x + rcWnd.right - rcWnd.left > rcWorkArea.right) {
  526. x = rcWorkArea.right - (rcWnd.right - rcWnd.left);
  527. }
  528. if (y + rcWnd.bottom - rcWnd.top > rcWorkArea.bottom) {
  529. y = rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
  530. }
  531. // adjust Offset
  532. lpptOffset->x = lpptCursor->x - x;
  533. lpptOffset->y = lpptCursor->y - y;
  534. // draw rectangle
  535. PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder, PATINVERT);
  536. PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
  537. PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top, rcWnd.right -
  538. rcWnd.left - cxBorder, -cyBorder, PATINVERT);
  539. PatBlt(hDC, x + rcWnd.right - rcWnd.left, y, - cxBorder, rcWnd.bottom -
  540. rcWnd.top - cyBorder, PATINVERT);
  541. // delete DISPLAY DC
  542. DeleteDC(hDC);
  543. return;
  544. }
  545. /**********************************************************************\
  546. * SKC1MousePosition() -- judge the cursor position
  547. *
  548. \**********************************************************************/
  549. #define CHECK_RECT(name) \
  550. if (ImmPtInRect(gptButtonPos[name ## _TYPE_C1].x, \
  551. gptButtonPos[name ## _TYPE_C1].y, \
  552. W_ ## name ## _C1 + 2 * BORDER_C1, \
  553. H_ ## name ## _C1 + 2 * BORDER_C1, \
  554. lpptCursor)) { \
  555. return name ## _TYPE_C1; \
  556. }
  557. INT SKC1MousePosition(
  558. LPPOINT lpptCursor)
  559. {
  560. int i;
  561. // letter buttons
  562. for (i = 0; i < LETTER_NUM_C1; i++){
  563. if (ImmPtInRect(gptButtonPos[i].x,
  564. gptButtonPos[i].y,
  565. W_LETTER_BTN_C1,
  566. H_LETTER_BTN_C1,
  567. lpptCursor)) {
  568. return i;
  569. }
  570. }
  571. CHECK_RECT(BACKSP);
  572. CHECK_RECT(TAB);
  573. CHECK_RECT(CAPS);
  574. CHECK_RECT(ENTER);
  575. CHECK_RECT(SHIFT);
  576. CHECK_RECT(ESC);
  577. CHECK_RECT(SPACE);
  578. CHECK_RECT(INS);
  579. CHECK_RECT(DEL);
  580. return -1;
  581. }
  582. #undef CHECK_RECT
  583. /**********************************************************************\
  584. * SKC1ButtonDown
  585. *
  586. \**********************************************************************/
  587. VOID SKC1ButtonDown(
  588. HWND hSKWnd,
  589. PSKC1CTXT pSKC1Ctxt)
  590. {
  591. // capture the mouse activity
  592. SetCapture(hSKWnd);
  593. // in drag area
  594. if (pSKC1Ctxt->uKeyIndex == -1) {
  595. pSKC1Ctxt->uState |= FLAG_DRAG_C1;
  596. SKC1DrawDragBorder(hSKWnd, &pSKC1Ctxt->ptSkCursor, &pSKC1Ctxt->ptSkOffset);
  597. } else {
  598. UINT uVirtKey = 0xff;
  599. BOOL bRet = FALSE;
  600. if (pSKC1Ctxt->uKeyIndex == SHIFT_TYPE_C1) {
  601. if (!(pSKC1Ctxt->uState & FLAG_SHIFT_C1)) {
  602. bRet = TRUE;
  603. }
  604. } else if (pSKC1Ctxt->uKeyIndex < LETTER_NUM_C1) {
  605. if (pSKC1Ctxt->uState & FLAG_SHIFT_C1) {
  606. uVirtKey = pSKC1Ctxt->wShiftCode[pSKC1Ctxt->uKeyIndex];
  607. }
  608. else {
  609. uVirtKey = pSKC1Ctxt->wNonShiftCode[pSKC1Ctxt->uKeyIndex];
  610. }
  611. if (uVirtKey) {
  612. bRet = TRUE;
  613. } else {
  614. MessageBeep(0xFFFFFFFF);
  615. pSKC1Ctxt->uKeyIndex = -1;
  616. }
  617. } else {
  618. bRet = TRUE;
  619. }
  620. if (bRet) {
  621. HDC hDC, hMemDC;
  622. HBITMAP hOldBmp;
  623. hDC = GetDC(hSKWnd);
  624. hMemDC = CreateCompatibleDC(hDC);
  625. hOldBmp = SelectObject(hMemDC, pSKC1Ctxt->hSoftkbd);
  626. SKC1InvertButton(hDC, pSKC1Ctxt->uKeyIndex);
  627. SKC1InvertButton(hMemDC, pSKC1Ctxt->uKeyIndex);
  628. SelectObject(hMemDC, hOldBmp);
  629. DeleteDC(hMemDC);
  630. ReleaseDC(hSKWnd,hDC);
  631. }
  632. if(uVirtKey) {
  633. pSKC1Ctxt->uState |= FLAG_FOCUS_C1;
  634. }
  635. }
  636. return;
  637. }
  638. /**********************************************************************\
  639. * SKC1SetCursor
  640. *
  641. \**********************************************************************/
  642. BOOL SKC1SetCursor(
  643. HWND hSKWnd,
  644. LPARAM lParam)
  645. {
  646. HGLOBAL hSKC1Ctxt;
  647. PSKC1CTXT pSKC1Ctxt;
  648. POINT ptSkCursor, ptSkOffset;
  649. int uKeyIndex;
  650. // Get and lock hSKC1Ctxt
  651. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  652. if (!hSKC1Ctxt) {
  653. return (FALSE);
  654. }
  655. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  656. if (!pSKC1Ctxt) {
  657. return (FALSE);
  658. }
  659. if (pSKC1Ctxt->uState & FLAG_DRAG_C1){
  660. // in drag operation
  661. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  662. GlobalUnlock(hSKC1Ctxt);
  663. return (TRUE);
  664. }
  665. GetCursorPos(&ptSkCursor);
  666. ptSkOffset = ptSkCursor;
  667. ScreenToClient(hSKWnd, &ptSkOffset);
  668. uKeyIndex = SKC1MousePosition(&ptSkOffset);
  669. if (uKeyIndex != -1) {
  670. SetCursor(LoadCursor(NULL, IDC_HAND));
  671. } else {
  672. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  673. }
  674. if (HIWORD(lParam) != WM_LBUTTONDOWN){
  675. // unlock hSKC1Ctxt
  676. GlobalUnlock(hSKC1Ctxt);
  677. return (TRUE);
  678. }
  679. pSKC1Ctxt->ptSkCursor = ptSkCursor;
  680. pSKC1Ctxt->ptSkOffset = ptSkOffset;
  681. pSKC1Ctxt->uKeyIndex = uKeyIndex;
  682. SKC1ButtonDown(hSKWnd, pSKC1Ctxt);
  683. // unlock hSKC1Ctxt
  684. GlobalUnlock(hSKC1Ctxt);
  685. return (TRUE);
  686. }
  687. /**********************************************************************\
  688. * SKC1MouseMove
  689. *
  690. \**********************************************************************/
  691. BOOL SKC1MouseMove(
  692. HWND hSKWnd,
  693. WPARAM wParam,
  694. LPARAM lParam)
  695. {
  696. HGLOBAL hSKC1Ctxt;
  697. PSKC1CTXT pSKC1Ctxt;
  698. UNREFERENCED_PARAMETER(wParam);
  699. UNREFERENCED_PARAMETER(lParam);
  700. // get and lock hSKC1Ctxt
  701. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  702. if (!hSKC1Ctxt) {
  703. return (FALSE);
  704. }
  705. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  706. if (!pSKC1Ctxt) {
  707. return (FALSE);
  708. }
  709. if (pSKC1Ctxt->uState & FLAG_DRAG_C1) {
  710. SKC1DrawDragBorder(hSKWnd, &pSKC1Ctxt->ptSkCursor,
  711. &pSKC1Ctxt->ptSkOffset);
  712. GetCursorPos(&pSKC1Ctxt->ptSkCursor);
  713. SKC1DrawDragBorder(hSKWnd, &pSKC1Ctxt->ptSkCursor,
  714. &pSKC1Ctxt->ptSkOffset);
  715. } else if (pSKC1Ctxt->uKeyIndex != -1) {
  716. HDC hDC, hMemDC;
  717. HBITMAP hOldBmp;
  718. POINT ptSkOffset;
  719. int uKeyIndex;
  720. GetCursorPos(&ptSkOffset);
  721. ScreenToClient(hSKWnd, &ptSkOffset);
  722. uKeyIndex = SKC1MousePosition(&ptSkOffset);
  723. hDC = GetDC(hSKWnd);
  724. hMemDC = CreateCompatibleDC(hDC);
  725. hOldBmp = SelectObject(hMemDC, pSKC1Ctxt->hSoftkbd);
  726. if (((pSKC1Ctxt->uState & FLAG_FOCUS_C1) && (uKeyIndex != pSKC1Ctxt->uKeyIndex)) ||
  727. (!(pSKC1Ctxt->uState & FLAG_FOCUS_C1) && (uKeyIndex == pSKC1Ctxt->uKeyIndex))) {
  728. if ((pSKC1Ctxt->uKeyIndex != SHIFT_TYPE_C1) ||
  729. !(pSKC1Ctxt->uState & FLAG_SHIFT_C1)) {
  730. SKC1InvertButton(hDC, pSKC1Ctxt->uKeyIndex);
  731. SKC1InvertButton(hMemDC, pSKC1Ctxt->uKeyIndex);
  732. }
  733. pSKC1Ctxt->uState ^= FLAG_FOCUS_C1;
  734. }
  735. SelectObject(hMemDC, hOldBmp);
  736. DeleteDC(hMemDC);
  737. ReleaseDC(hSKWnd,hDC);
  738. }
  739. // unlock hSKC1Ctxt
  740. GlobalUnlock(hSKC1Ctxt);
  741. return (TRUE);
  742. }
  743. /**********************************************************************\
  744. * SKC1ButtonUp
  745. *
  746. \**********************************************************************/
  747. BOOL SKC1ButtonUp(
  748. HWND hSKWnd,
  749. WPARAM wParam,
  750. LPARAM lParam)
  751. {
  752. HGLOBAL hSKC1Ctxt;
  753. PSKC1CTXT pSKC1Ctxt;
  754. POINT pt;
  755. UINT uVirtKey;
  756. BOOL bRet = FALSE;
  757. UNREFERENCED_PARAMETER(wParam);
  758. UNREFERENCED_PARAMETER(lParam);
  759. // Get and lock hSKC1Ctxt
  760. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  761. if (!hSKC1Ctxt) {
  762. return (bRet);
  763. }
  764. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  765. if (!pSKC1Ctxt) {
  766. return (bRet);
  767. }
  768. ReleaseCapture();
  769. if (pSKC1Ctxt->uState & FLAG_DRAG_C1) {
  770. pSKC1Ctxt->uState &= ~(FLAG_DRAG_C1);
  771. SKC1DrawDragBorder(hSKWnd, &pSKC1Ctxt->ptSkCursor, &pSKC1Ctxt->ptSkOffset);
  772. pt.x = pSKC1Ctxt->ptSkCursor.x - pSKC1Ctxt->ptSkOffset.x;
  773. pt.y = pSKC1Ctxt->ptSkCursor.y - pSKC1Ctxt->ptSkOffset.y;
  774. SetWindowPos(hSKWnd, (HWND)NULL, pt.x, pt.y,
  775. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  776. // update IMC
  777. bRet = TRUE;
  778. {
  779. HWND hUIWnd;
  780. HIMC hImc;
  781. PINPUTCONTEXT pInputContext;
  782. hUIWnd = GetWindow(hSKWnd, GW_OWNER);
  783. hImc = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  784. if (hImc) {
  785. pInputContext = ImmLockIMC(hImc);
  786. if (pInputContext) {
  787. pInputContext->ptSoftKbdPos = pt;
  788. pInputContext->fdwInit |= INIT_SOFTKBDPOS;
  789. ImmUnlockIMC(hImc);
  790. }
  791. }
  792. }
  793. } else if (pSKC1Ctxt->uKeyIndex != -1) {
  794. if (pSKC1Ctxt->uState & FLAG_FOCUS_C1) {
  795. if (pSKC1Ctxt->uKeyIndex == SHIFT_TYPE_C1) {
  796. if (pSKC1Ctxt->uState & FLAG_SHIFT_C1) {
  797. bRet = TRUE;
  798. } else {
  799. pSKC1Ctxt->uState |= FLAG_SHIFT_C1;
  800. }
  801. } else if ((pSKC1Ctxt->uKeyIndex < LETTER_NUM_C1) &&
  802. (pSKC1Ctxt->uState & FLAG_SHIFT_C1)) {
  803. keybd_event((BYTE)VK_SHIFT, (BYTE)guScanCode[VK_SHIFT],
  804. 0, 0);
  805. uVirtKey = SKC1VirtKey[pSKC1Ctxt->uKeyIndex];
  806. keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
  807. 0, 0);
  808. keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
  809. (DWORD)KEYEVENTF_KEYUP, 0);
  810. keybd_event((BYTE)VK_SHIFT, (BYTE)guScanCode[VK_SHIFT],
  811. (DWORD)KEYEVENTF_KEYUP, 0);
  812. bRet = TRUE;
  813. } else {
  814. uVirtKey = SKC1VirtKey[pSKC1Ctxt->uKeyIndex];
  815. keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
  816. 0, 0);
  817. keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
  818. (DWORD)KEYEVENTF_KEYUP, 0);
  819. bRet = TRUE;
  820. }
  821. if (bRet){
  822. HDC hDC, hMemDC;
  823. HBITMAP hOldBmp;
  824. hDC = GetDC(hSKWnd);
  825. hMemDC = CreateCompatibleDC(hDC);
  826. hOldBmp = SelectObject(hMemDC, pSKC1Ctxt->hSoftkbd);
  827. SKC1InvertButton(hDC, pSKC1Ctxt->uKeyIndex);
  828. SKC1InvertButton(hMemDC, pSKC1Ctxt->uKeyIndex);
  829. if ((pSKC1Ctxt->uKeyIndex != SHIFT_TYPE_C1) &&
  830. (pSKC1Ctxt->uKeyIndex < LETTER_NUM_C1) &&
  831. (pSKC1Ctxt->uState & FLAG_SHIFT_C1)) {
  832. SKC1InvertButton(hDC, SHIFT_TYPE_C1);
  833. SKC1InvertButton(hMemDC, SHIFT_TYPE_C1);
  834. }
  835. if ((pSKC1Ctxt->uKeyIndex < LETTER_NUM_C1) ||
  836. (pSKC1Ctxt->uKeyIndex == SHIFT_TYPE_C1)) {
  837. pSKC1Ctxt->uState &= ~(FLAG_SHIFT_C1);
  838. }
  839. SelectObject(hMemDC, hOldBmp);
  840. DeleteDC(hMemDC);
  841. ReleaseDC(hSKWnd,hDC);
  842. }
  843. pSKC1Ctxt->uState &= ~ (FLAG_FOCUS_C1);
  844. }
  845. pSKC1Ctxt->uKeyIndex = -1;
  846. }
  847. // unlock hSKC1Ctxt
  848. GlobalUnlock(hSKC1Ctxt);
  849. return (bRet);
  850. }
  851. /**********************************************************************\
  852. * SKWndProcC1 -- softkeyboard window procedure
  853. *
  854. \**********************************************************************/
  855. LRESULT SKWndProcC1(
  856. HWND hSKWnd,
  857. UINT uMsg,
  858. WPARAM wParam,
  859. LPARAM lParam)
  860. {
  861. LRESULT lRet = 0L;
  862. switch (uMsg) {
  863. case WM_CREATE:
  864. lRet = CreateC1Window(hSKWnd);
  865. break;
  866. case WM_DESTROY:
  867. DestroyC1Window(hSKWnd);
  868. break;
  869. case WM_PAINT:
  870. {
  871. HDC hDC;
  872. PAINTSTRUCT ps;
  873. hDC = BeginPaint(hSKWnd, &ps);
  874. ShowSKC1Window(hDC, hSKWnd);
  875. EndPaint(hSKWnd, &ps);
  876. }
  877. break;
  878. case WM_MOUSEACTIVATE:
  879. lRet = MA_NOACTIVATE;
  880. break;
  881. case WM_SETCURSOR:
  882. if (!SKC1SetCursor(hSKWnd, lParam)) {
  883. lRet = DefWindowProc(hSKWnd, uMsg, wParam, lParam);
  884. }
  885. break;
  886. case WM_MOUSEMOVE:
  887. if (!SKC1MouseMove(hSKWnd, wParam, lParam)) {
  888. lRet = DefWindowProc(hSKWnd, uMsg, wParam, lParam);
  889. }
  890. break;
  891. case WM_LBUTTONUP:
  892. if (!SKC1ButtonUp(hSKWnd, wParam, lParam)) {
  893. lRet = DefWindowProc(hSKWnd, uMsg, wParam, lParam);
  894. }
  895. break;
  896. case WM_IME_CONTROL:
  897. switch (wParam) {
  898. case IMC_GETSOFTKBDFONT:
  899. {
  900. HDC hDC;
  901. LOGFONT lfFont;
  902. hDC = GetDC(hSKWnd);
  903. GetObject(GetStockObject(DEFAULT_GUI_FONT),
  904. sizeof(lfFont), &lfFont);
  905. ReleaseDC(hSKWnd, hDC);
  906. *(LPLOGFONT)lParam = lfFont;
  907. }
  908. break;
  909. case IMC_SETSOFTKBDFONT:
  910. {
  911. LOGFONT lfFont;
  912. GetObject(GetStockObject(DEFAULT_GUI_FONT),
  913. sizeof(lfFont), &lfFont);
  914. // in differet version of Windows
  915. if (lfFont.lfCharSet != ((LPLOGFONT)lParam)->lfCharSet) {
  916. HGLOBAL hSKC1Ctxt;
  917. LPSKC1CTXT lpSKC1Ctxt;
  918. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd,
  919. SKC1_CONTEXT);
  920. if (!hSKC1Ctxt) {
  921. return 1;
  922. }
  923. lpSKC1Ctxt = (LPSKC1CTXT)GlobalLock(hSKC1Ctxt);
  924. if (!lpSKC1Ctxt) {
  925. return 1;
  926. }
  927. lpSKC1Ctxt->lfCharSet =
  928. ((LPLOGFONT)lParam)->lfCharSet;
  929. GlobalUnlock(hSKC1Ctxt);
  930. }
  931. }
  932. break;
  933. case IMC_GETSOFTKBDPOS:
  934. {
  935. RECT rcWnd;
  936. GetWindowRect(hSKWnd, &rcWnd);
  937. return MAKELRESULT(rcWnd.left, rcWnd.top);
  938. }
  939. break;
  940. case IMC_SETSOFTKBDPOS:
  941. {
  942. SetWindowPos(hSKWnd, NULL,
  943. ((LPPOINTS)lParam)->x, ((LPPOINTS)lParam)->y,
  944. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  945. return (0);
  946. }
  947. break;
  948. case IMC_SETSOFTKBDDATA:
  949. if (UpdateSKC1Window(hSKWnd, (LPSOFTKBDDATA)lParam)) {
  950. InvalidateRect(hSKWnd, NULL, FALSE);
  951. } else lRet = -1L;
  952. break;
  953. case IMC_GETSOFTKBDSUBTYPE:
  954. case IMC_SETSOFTKBDSUBTYPE:
  955. {
  956. HGLOBAL hSKC1Ctxt;
  957. PSKC1CTXT pSKC1Ctxt;
  958. lRet = -1L;
  959. hSKC1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKC1_CONTEXT);
  960. if (!hSKC1Ctxt) break;
  961. pSKC1Ctxt = (PSKC1CTXT)GlobalLock(hSKC1Ctxt);
  962. if (!pSKC1Ctxt) break;
  963. if (wParam == IMC_GETSOFTKBDSUBTYPE) {
  964. lRet = pSKC1Ctxt->uSubtype;
  965. } else {
  966. lRet = pSKC1Ctxt->uSubtype;
  967. pSKC1Ctxt->uSubtype = (UINT)lParam;
  968. }
  969. GlobalUnlock(hSKC1Ctxt);
  970. }
  971. break;
  972. }
  973. break;
  974. default:
  975. lRet = DefWindowProc(hSKWnd, uMsg, wParam, lParam);
  976. }
  977. return (lRet);
  978. }