ReactOS 0.4.17-dev-243-g1369312
softkbd.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing IME Soft Keyboard
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9#include "resource.h"
10
12
13/*
14 * There are two types of IME Soft Keyboard: Type T1 and Type C1.
15 * T1 is created for Traditional Chinese but not limitted to it.
16 * C1 is created for Simplified Chinese but not limitted to it.
17 * Type C1 has SHIFT status while Type T1 hasn't.
18 */
19
20static UINT guScanCode[256]; /* Mapping: virtual key --> scan code */
21static POINT gptRaiseEdge; /* Border + Edge metrics */
23
24typedef struct tagSOFTKBDDATAEX
25{
27 WORD wCode[2][256];
29
30static inline BOOL
32 _In_ const POINT *ppt,
33 _In_ LONG x,
34 _In_ LONG y,
35 _In_ LONG cx,
36 _In_ LONG cy)
37{
38 return (x <= ppt->x) && (ppt->x < x + cx) && (y <= ppt->y) && (ppt->y < y + cy);
39}
40
41static void
43 _In_ HDC hdc,
44 _In_ INT x,
45 _In_ INT y,
48 _In_ INT nBitmapID)
49{
51 HDC hMemDC = CreateCompatibleDC(hdc);
52 HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap);
53 BitBlt(hdc, x, y, width, height, hMemDC, 0, 0, SRCCOPY);
54 DeleteObject(SelectObject(hMemDC, hbmOld));
55 DeleteDC(hMemDC);
56}
57
58static inline INT
60 _In_ INT x,
61 _In_ INT xMin,
62 _In_ INT xMax)
63{
64 if (x < xMin)
65 return xMin;
66 if (x > xMax)
67 return xMax;
68 return x;
69}
70
71static VOID
73 _Out_ LPRECT prcWork)
74{
76 {
77 SystemParametersInfoW(SPI_GETWORKAREA, 0, prcWork, 0);
78 return;
79 }
80
81 prcWork->left = GetSystemMetrics(SM_XVIRTUALSCREEN);
82 prcWork->top = GetSystemMetrics(SM_YVIRTUALSCREEN);
83 prcWork->right = prcWork->left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
84 prcWork->bottom = prcWork->top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
85}
86
87static BOOL
90 _Out_ LPRECT prcWork)
91{
92 HMONITOR hMonitor;
94
96 {
98 return TRUE;
99 }
100
101 hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
102 if (!hMonitor)
103 {
104 ERR("hwnd: %p\n", hwnd);
105 return FALSE;
106 }
107
108 ZeroMemory(&mi, sizeof(mi));
109 mi.cbSize = sizeof(mi);
110 GetMonitorInfoW(hMonitor, &mi);
111 *prcWork = mi.rcWork;
112 return TRUE;
113}
114
115/*****************************************************************************
116 * IME Soft Keyboard Type T1
117 */
118
119#define T1_CLASSNAMEW L"SoftKBDClsT1"
120
121#undef DEFINE_T1K
122#define DEFINE_T1K(t1k_code, virtual_key_code, t1k_code_name, virtual_key_name, is_special) \
123 t1k_code_name = t1k_code,
124
125/* Define T1 internal codes (T1K_...) */
126typedef enum T1KEY
127{
128#include "t1keys.h"
130
131#undef DEFINE_T1K
132#define DEFINE_T1K(t1k_code, virtual_key_code, t1k_code_name, virtual_key_name, is_special) \
133 virtual_key_code,
134
135#define T1K_MAX 60
136
137/* Mapping: T1K --> Virtual Key */
139{
140#include "t1keys.h"
141};
142
143typedef struct T1WINDOW
144{
145 INT cxDefWidth; /* Regular key width */
146 INT cxWidth47; /* [BackSpace] width */
147 INT cxWidth48; /* [Tab] width */
148 INT cxWidth49; /* [Caps] width */
149 INT cxWidth50; /* [Enter] width */
150 INT cxWidth51or52; /* [Shift] width */
151 INT cxWidth53or54; /* [Ctrl] width */
152 INT cxWidth55or56; /* [Alt] width */
153 INT cxWidth57; /* [Esc] width */
154 INT cxWidth58; /* [Space] width */
155 INT cyDefHeight; /* Regular key height */
156 INT cyHeight50; /* [Enter] height */
157 POINT KeyPos[T1K_MAX]; /* T1K --> POINT */
158 WCHAR chKeyChar[48]; /* T1K --> WCHAR */
159 HBITMAP hbmKeyboard; /* The keyboard image */
160 DWORD CharSet; /* LOGFONT.lfCharSet */
161 UINT PressedKey; /* Currently pressed key */
162 POINT pt0, pt1; /* The soft keyboard window position */
163 LPARAM KeyboardSubType; /* See IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE */
165
166#define T1_KEYPOS(iKey) pT1->KeyPos[iKey]
167
169
170static void
172{
173 WCHAR wch;
174 SIZE textSize;
175 HFONT hFont;
176 HGDIOBJ hFontOld;
177 HDC hDC;
178#if DBG
179 WCHAR szFace[LF_FACESIZE];
180#endif
181
183 g_T1LogFont.lfHeight = -12;
186#ifdef NO_HACK /* FIXME: We lack proper Asian fonts! */
191#else
193#endif
195
196 hDC = GetDC(NULL);
197 hFontOld = SelectObject(hDC, hFont);
198
199#if DBG
200 GetTextFaceW(hDC, _countof(szFace), szFace);
201 TRACE("szFace: %s\n", debugstr_w(szFace));
202#endif
203
204 GetTextMetricsW(hDC, ptm);
205
206 wch = 0x4E11; /* U+4E11: δΈ‘ */
207 if (GetTextExtentPoint32W(hDC, &wch, 1, &textSize) && textSize.cx > ptm->tmMaxCharWidth)
208 ptm->tmMaxCharWidth = textSize.cx;
209
210 DeleteObject(SelectObject(hDC, hFontOld));
212}
213
214static void
216{
218 LONG cxLarge, cyLarge;
219 LONG xKey1, yKey1, xKey2, yKey2, xKey3, yKey3;
220 LONG yKey4, xKey4, xKey5, yKey5, xKey6, xKey7;
221 INT iKey;
222
224
225 cxLarge = (3 * tm.tmMaxCharWidth + 18) / 2;
226 cyLarge = tm.tmHeight + 8;
227
228 /* key widths and heights */
229 pT1->cxDefWidth = (2 * tm.tmMaxCharWidth + 12) / 2;
230 pT1->cxWidth47 = (2 * tm.tmMaxCharWidth + 12) / 2 + 1;
231 pT1->cxWidth49 = (4 * tm.tmMaxCharWidth + 24) / 2 + 3;
232 pT1->cxWidth51or52 = (5 * tm.tmMaxCharWidth + 30) / 2 + 5;
233 pT1->cxWidth58 = 4 * (3 * tm.tmMaxCharWidth + 18) / 2 + 15;
234 pT1->cxWidth48 = pT1->cxWidth50 = cxLarge + 2;
235 pT1->cxWidth53or54 = pT1->cxWidth55or56 = cxLarge + 2;
236 pT1->cyHeight50 = 2 * (tm.tmHeight + 8) + 3;
237 pT1->cxWidth57 = cxLarge + 1;
238 pT1->cyDefHeight = cyLarge;
239
240 /* First row */
241 xKey1 = gptRaiseEdge.x + 3;
242 yKey1 = gptRaiseEdge.y + 3;
243 for (iKey = 0; iKey < T1K_Q; ++iKey)
244 {
245 T1_KEYPOS(iKey).x = xKey1;
246 T1_KEYPOS(iKey).y = yKey1;
247 xKey1 += pT1->cxDefWidth + 3;
248 }
249 T1_KEYPOS(T1K_BACKSPACE).y = yKey1;
250 T1_KEYPOS(T1K_BACKSPACE).x = xKey1;
251
252 /* 2nd row */
253 xKey2 = 3 + gptRaiseEdge.x + pT1->cxWidth48 + 3;
254 yKey2 = 3 + yKey1 + cyLarge;
255 T1_KEYPOS(T1K_TAB).x = gptRaiseEdge.x + 3;
256 T1_KEYPOS(T1K_TAB).y = yKey2;
257 for (iKey = T1K_Q; iKey < T1K_A; ++iKey)
258 {
259 T1_KEYPOS(iKey).x = xKey2;
260 T1_KEYPOS(iKey).y = yKey2;
261 xKey2 += pT1->cxDefWidth + 3;
262 }
263 T1_KEYPOS(T1K_ENTER).x = xKey2;
264 T1_KEYPOS(T1K_ENTER).y = yKey2;
265
266 /* 3rd row */
267 xKey3 = gptRaiseEdge.x + 3 + pT1->cxWidth49 + 3;
268 yKey3 = yKey2 + cyLarge + 3;
269 T1_KEYPOS(T1K_CAPS).x = gptRaiseEdge.x + 3;
270 T1_KEYPOS(T1K_CAPS).y = yKey3;
271 for (iKey = T1K_A; iKey < T1K_Z; ++iKey)
272 {
273 T1_KEYPOS(iKey).x = xKey3;
274 T1_KEYPOS(iKey).y = yKey3;
275 xKey3 += pT1->cxDefWidth + 3;
276 }
277
278 /* 4th row */
279 xKey4 = gptRaiseEdge.x + pT1->cxWidth51or52 + 3 + 3;
280 yKey4 = yKey3 + cyLarge + 3;
281 T1_KEYPOS(T1K_L_SHIFT).x = gptRaiseEdge.x + 3;
282 T1_KEYPOS(T1K_L_SHIFT).y = yKey4;
283 for (iKey = T1K_Z; iKey < T1K_BACKSPACE; ++iKey)
284 {
285 T1_KEYPOS(iKey).x = xKey4;
286 T1_KEYPOS(iKey).y = yKey4;
287 xKey4 += pT1->cxDefWidth + 3;
288 }
289 T1_KEYPOS(T1K_R_SHIFT).x = xKey4;
290 T1_KEYPOS(T1K_R_SHIFT).y = yKey4;
291
292 /* 5th row */
293 xKey5 = gptRaiseEdge.x + 3 + pT1->cxWidth53or54 + 3;
294 T1_KEYPOS(T1K_L_CTRL).x = gptRaiseEdge.x + 3;
295 T1_KEYPOS(T1K_ESCAPE).x = xKey5;
296 T1_KEYPOS(T1K_L_ALT).x = xKey5 + pT1->cxWidth57 + 3;
297
298 yKey5 = yKey4 + cyLarge + 3;
299 T1_KEYPOS(T1K_L_CTRL).y = T1_KEYPOS(T1K_ESCAPE).y = T1_KEYPOS(T1K_L_ALT).y = yKey5;
300 T1_KEYPOS(T1K_R_ALT).y = T1_KEYPOS(T1K_SPACE).y = T1_KEYPOS(T1K_R_CTRL).y = yKey5;
301
302 xKey6 = xKey5 + pT1->cxWidth57 + 3 + pT1->cxWidth55or56 + 3;
303 T1_KEYPOS(T1K_SPACE).x = xKey6;
304
305 xKey7 = xKey6 + pT1->cxWidth58 + 3;
306 T1_KEYPOS(T1K_R_ALT).x = xKey7;
307 T1_KEYPOS(T1K_R_CTRL).x = xKey7 + pT1->cxWidth57 + pT1->cxWidth55or56 + 6;
308}
309
310/* Draw keyboard key edge */
311static void
313 _In_ HDC hDC,
314 _In_ INT x,
315 _In_ INT y,
316 _In_ INT width,
318{
319 HGDIOBJ hBlackPen = GetStockObject(BLACK_PEN);
320 HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH);
321 HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH);
322 INT dx = width + 4, dy = height + 4;
323 INT x0 = x - 2, y0 = y + height + 2;
324
325 /* Face */
326 SelectObject(hDC, hBlackPen);
327 SelectObject(hDC, hLtGrayBrush);
328 Rectangle(hDC, x0, y - 2, x0 + dx, y0);
329
330 /* Rounded corners */
331 PatBlt(hDC, x0, y - 2, 1, 1, PATCOPY);
332 PatBlt(hDC, x0, y0, 1, -1, PATCOPY);
333 PatBlt(hDC, x0 + dx, y - 2, -1, 1, PATCOPY);
334 PatBlt(hDC, x0 + dx, y0, -1, -1, PATCOPY);
335
336 /* Light edge */
337 PatBlt(hDC, x0 + 1, y + dy - 3, 1, 2 - dy, WHITENESS);
338 PatBlt(hDC, x0 + 1, y - 1, dx - 2, 1, WHITENESS);
339
340 /* Dark edge */
341 SelectObject(hDC, hGrayBrush);
342 PatBlt(hDC, x0 + 1, y + dy - 3, dx - 2, -1, PATCOPY);
343 PatBlt(hDC, x0 + dx - 1, y + dy - 3, -1, 2 - dy, PATCOPY);
344}
345
346static void
348 _In_ HDC hDC,
349 _In_ const T1WINDOW *pT1,
350 _In_ LPCWSTR pszBmpName)
351{
352 HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, pszBmpName);
355 INT iKey;
356 for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey)
357 {
358 const POINT *ppt = &T1_KEYPOS(iKey);
359 BitBlt(hDC, ppt->x, ppt->y, 8, 8, hdcMem, iKey * 8, 0, SRCCOPY);
360 }
361 SelectObject(hdcMem, hbmOld);
364}
365
366static void
368 _In_ HWND hWnd,
369 _Inout_ PT1WINDOW pT1)
370{
371 HDC hDC, hMemDC;
373 RECT rc;
374 INT iKey;
375
376 /* Create the bitmap */
377 hDC = GetDC(hWnd);
378 hMemDC = CreateCompatibleDC(hDC);
379 GetClientRect(hWnd, &rc);
380 pT1->hbmKeyboard = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
382
383 /* Draw keyboard face */
384 SelectObject(hMemDC, pT1->hbmKeyboard);
385 SelectObject(hMemDC, hNullPen);
386 SelectObject(hMemDC, hbrLtGray);
387 Rectangle(hMemDC, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
388 DrawEdge(hMemDC, &rc, EDGE_RAISED, BF_RECT);
389
390 /* 53 --> Left [Ctrl] */
391 T1_DrawConvexRect(hMemDC,
392 T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y,
393 pT1->cxWidth53or54, pT1->cyDefHeight);
394 Imm32DrawBitmap(hMemDC,
395 pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8,
396 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4,
397 16, 9, IDB_T1_CTRL);
398
399 /* 54 --> Right [Ctrl] */
400 T1_DrawConvexRect(hMemDC,
401 T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y,
402 pT1->cxWidth53or54, pT1->cyDefHeight);
403 Imm32DrawBitmap(hMemDC,
404 pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8,
405 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4,
406 16, 9, IDB_T1_CTRL);
407
408 /* 57 --> [Esc] */
409 T1_DrawConvexRect(hMemDC,
410 T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y,
411 pT1->cxWidth57, pT1->cyDefHeight);
412 Imm32DrawBitmap(hMemDC,
413 pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9,
414 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4,
415 18, 9, IDB_T1_ESCAPE);
416
417 /* 55 --> Left [Alt] */
418 T1_DrawConvexRect(hMemDC,
419 T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y,
420 pT1->cxWidth55or56, pT1->cyDefHeight);
421 Imm32DrawBitmap(hMemDC,
422 pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8,
423 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4,
424 16, 9, IDB_T1_ALT);
425
426 /* 56 --> Right [Alt] */
427 T1_DrawConvexRect(hMemDC,
428 T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y,
429 pT1->cxWidth55or56, pT1->cyDefHeight);
430 Imm32DrawBitmap(hMemDC,
431 pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8,
432 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4,
433 16, 9, IDB_T1_ALT);
434
435 /* 58 --> [Space] */
436 T1_DrawConvexRect(hMemDC,
437 T1_KEYPOS(T1K_SPACE).x, T1_KEYPOS(T1K_SPACE).y,
438 pT1->cxWidth58, pT1->cyDefHeight);
439
440 /* 51 --> Left [Shift] */
441 T1_DrawConvexRect(hMemDC,
442 T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y,
443 pT1->cxWidth51or52, pT1->cyDefHeight);
444 Imm32DrawBitmap(hMemDC,
445 pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11,
446 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4,
447 23, 9, IDB_T1_SHIFT);
448
449 /* 52 --> Right [Shift] */
450 T1_DrawConvexRect(hMemDC,
451 T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y,
452 pT1->cxWidth51or52, pT1->cyDefHeight);
453 Imm32DrawBitmap(hMemDC,
454 pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11,
455 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4,
456 23, 9, IDB_T1_SHIFT);
457
458 /* 49 --> [Caps] */
459 T1_DrawConvexRect(hMemDC,
460 T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y,
461 pT1->cxWidth49, pT1->cyDefHeight);
462 Imm32DrawBitmap(hMemDC,
463 pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11,
464 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4,
465 22, 9, IDB_T1_CAPS);
466
467 /* 48 --> [Tab] */
468 T1_DrawConvexRect(hMemDC,
469 T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y,
470 pT1->cxWidth48, pT1->cyDefHeight);
471 Imm32DrawBitmap(hMemDC,
472 pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8,
473 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4,
474 16, 9, IDB_T1_TAB);
475
476 /* 50 --> [Enter] */
477 T1_DrawConvexRect(hMemDC,
478 T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y,
479 pT1->cxWidth50, pT1->cyHeight50);
480 Imm32DrawBitmap(hMemDC,
481 pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13,
482 pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4,
483 26, 9, IDB_T1_ENTER);
484
485 /* 47 --> [BackSpace] */
486 T1_DrawConvexRect(hMemDC,
487 T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y,
488 pT1->cxWidth47, pT1->cyDefHeight);
489 Imm32DrawBitmap(hMemDC,
490 pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8,
491 pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4,
492 16, 9, IDB_T1_BACKSPACE);
493
494 /* Regular keys */
495 for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey)
496 {
497 LPPOINT ppt = &T1_KEYPOS(iKey);
498 T1_DrawConvexRect(hMemDC, ppt->x, ppt->y, pT1->cxDefWidth, pT1->cyDefHeight);
499 }
500
502 DeleteDC(hMemDC);
503}
504
505static INT
507 _In_ HWND hWnd)
508{
509 PT1WINDOW pT1;
510 HGLOBAL hGlobal = GlobalAlloc(GHND, sizeof(T1WINDOW));
511 if (!hGlobal)
512 return -1;
513
514 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
515 if (!pT1)
516 {
517 GlobalFree(hGlobal);
518 return -1;
519 }
520
521 SetWindowLongPtrW(hWnd, 0, (LONG_PTR)hGlobal);
522 pT1->pt1.x = pT1->pt1.y = -1;
523 pT1->PressedKey = T1K_NONE;
525
526 T1_InitButtonPos(pT1);
527 T1_InitBitmap(hWnd, pT1);
528 GlobalUnlock(hGlobal);
529
530 return 0;
531}
532
533static void
535 _In_ HWND hWnd,
536 _In_ const POINT *ppt1,
537 _In_ const POINT *ppt2)
538{
540 INT x = ppt1->x - ppt2->x, y = ppt1->y - ppt2->y;
541 HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH);
542 RECT rc;
543 HDC hDisplayDC;
544
545 GetWindowRect(hWnd, &rc);
546 hDisplayDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
547 SelectObject(hDisplayDC, hGrayBrush);
548 PatBlt(hDisplayDC, x, y, rc.right - rc.left - cxBorder, cyBorder, PATINVERT);
549 PatBlt(hDisplayDC, x, cyBorder + y, cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT);
550 PatBlt(hDisplayDC, x + cxBorder, y + rc.bottom - rc.top, rc.right - rc.left - cxBorder, -cyBorder, PATINVERT);
551 PatBlt(hDisplayDC, x + rc.right - rc.left, y, -cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT);
552 DeleteDC(hDisplayDC);
553}
554
555static void
557 _In_ HWND hWnd)
558{
559 HGLOBAL hGlobal;
560 PT1WINDOW pT1;
561 HWND hwndOwner;
562
563 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
564 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
565 if (!hGlobal || !pT1)
566 return;
567
568 if (pT1->pt1.x != -1 && pT1->pt1.y != -1)
569 T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1);
570
572 GlobalUnlock(hGlobal);
573 GlobalFree(hGlobal);
574
575 hwndOwner = GetWindow(hWnd, GW_OWNER);
576 if (hwndOwner)
578}
579
580static void
582 _In_ HWND hWnd,
583 _In_ HDC hDC,
584 _In_ const T1WINDOW *pT1,
585 _In_ UINT iPressed)
586{
587 INT cxWidth = pT1->cxDefWidth, cyHeight = pT1->cyDefHeight;
588 HDC hChoiceDC;
589
590 if (iPressed >= T1K_NONE)
591 return;
592
593 if (hDC)
594 hChoiceDC = hDC;
595 else
596 hChoiceDC = GetDC(hWnd);
597
598 if (iPressed >= T1K_BACKSPACE)
599 {
600 switch (iPressed)
601 {
602 case T1K_BACKSPACE:
603 cxWidth = pT1->cxWidth47;
604 break;
605 case T1K_TAB:
606 cxWidth = pT1->cxWidth48;
607 break;
608 case T1K_ENTER:
609 cxWidth = pT1->cxWidth50;
610 cyHeight = pT1->cyHeight50;
611 break;
612 case T1K_ESCAPE:
613 cxWidth = pT1->cxWidth57;
614 break;
615 case T1K_SPACE:
616 cxWidth = pT1->cxWidth58;
617 break;
618 default:
619 cxWidth = 0;
620 MessageBeep(0xFFFFFFFF);
621 break;
622 }
623 }
624
625 if (cxWidth > 0)
626 {
627 PatBlt(hChoiceDC,
628 T1_KEYPOS(iPressed).x - 1, T1_KEYPOS(iPressed).y - 1,
629 cxWidth + 2, cyHeight + 2,
630 DSTINVERT);
631 }
632
633 if (!hDC)
634 ReleaseDC(hWnd, hChoiceDC);
635}
636
637static void
639 _In_ HDC hDC,
640 _In_ HWND hWnd)
641{
642 HGLOBAL hGlobal;
643 PT1WINDOW pT1;
644 HDC hMemDC;
645 RECT rc;
646
647 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
648 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
649 if (!hGlobal || !pT1)
650 return;
651
652 hMemDC = CreateCompatibleDC(hDC);
653 SelectObject(hMemDC, pT1->hbmKeyboard);
654 GetClientRect(hWnd, &rc);
655 BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY);
656 DeleteDC(hMemDC);
657
658 if (pT1->PressedKey < T1K_NONE)
659 T1_InvertButton(hWnd, hDC, pT1, pT1->PressedKey);
660
661 GlobalUnlock(hGlobal);
662}
663
664static UINT
666 _In_ const T1WINDOW *pT1,
667 _In_ const POINT *ppt)
668{
669 INT iKey;
670 for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey)
671 {
672 const POINT *pptKey = &T1_KEYPOS(iKey);
673 if (Imm32PtInRect(ppt, pptKey->x, pptKey->y, pT1->cxDefWidth, pT1->cyDefHeight))
674 return iKey;
675 }
676
677 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y, pT1->cxWidth47, pT1->cyDefHeight))
678 return T1K_BACKSPACE;
679
680 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y, pT1->cxWidth48, pT1->cyDefHeight))
681 return T1K_TAB;
682
683 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y, pT1->cxWidth49, pT1->cyDefHeight))
684 return T1K_CAPS;
685
686 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y, pT1->cxWidth50, pT1->cyHeight50))
687 return T1K_ENTER;
688
689 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight) ||
690 Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight))
691 {
692 return T1K_L_SHIFT;
693 }
694
695 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight) ||
696 Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight))
697 {
698 return T1K_L_CTRL;
699 }
700
701 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight) ||
702 Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight))
703 {
704 return T1K_L_ALT;
705 }
706
707 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y, pT1->cxWidth57, pT1->cyDefHeight))
708 return T1K_ESCAPE;
709
710 if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_SPACE).x, T1_KEYPOS(T1K_SPACE).y, pT1->cxWidth58, pT1->cyDefHeight))
711 return T1K_SPACE;
712
713 return T1K_NONE;
714}
715
716static BOOL
718 _In_ UINT iKey,
719 _In_ const T1WINDOW *pT1)
720{
721 if (iKey < T1K_BACKSPACE)
722 return !!pT1->chKeyChar[iKey];
723 return iKey <= T1K_TAB || iKey == T1K_ENTER || (T1K_ESCAPE <= iKey && iKey <= T1K_SPACE);
724}
725
730static BOOL
732 _In_ HWND hWnd,
734{
735 HGLOBAL hGlobal;
736 PT1WINDOW pT1;
737 HCURSOR hCursor;
738 UINT iPressed, iKey;
739 RECT rc, rcWork;
740
741 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
742 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
743 if (!hGlobal || !pT1)
744 return FALSE;
745
746 if (pT1->pt1.x != -1 && pT1->pt1.y != -1)
747 {
749 GlobalUnlock(hGlobal);
750 return TRUE;
751 }
752
753 GetCursorPos(&pT1->pt0);
754 ScreenToClient(hWnd, &pT1->pt0);
755
756 iKey = T1_HitTest(pT1, &pT1->pt0);
757 if (iKey >= T1K_NONE)
758 hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL);
759 else
760 hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_HAND);
761 SetCursor(hCursor);
762
764 {
766
767 iPressed = pT1->PressedKey;
768 if (iPressed < T1K_NONE)
769 {
770 UINT iVK = gT1K2VK[iPressed];
772 T1_InvertButton(hWnd, NULL, pT1, pT1->PressedKey);
773 pT1->PressedKey = T1K_NONE;
774 }
775
776 if (iKey >= T1K_NONE)
777 {
778 Imm32GetAllMonitorSize(&rcWork);
779 GetCursorPos(&pT1->pt0);
780 GetWindowRect(hWnd, &rc);
781 pT1->pt1.x = pT1->pt0.x - rc.left;
782 pT1->pt1.y = pT1->pt0.y - rc.top;
783 T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1);
784 }
785 else if (T1_IsValidButton(iKey, pT1))
786 {
787 UINT iVK = gT1K2VK[iKey];
788 keybd_event(iVK, guScanCode[iVK], 0, 0);
789 pT1->PressedKey = iKey;
790 T1_InvertButton(hWnd, 0, pT1, iKey);
791 }
792 else
793 {
794 MessageBeep(0xFFFFFFFF);
795 }
796 }
797
798 return TRUE;
799}
800
801static BOOL
803 _In_ HWND hWnd)
804{
805 BOOL ret = FALSE;
806 HGLOBAL hGlobal;
807 PT1WINDOW pT1;
808
809 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
810 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
811 if (!hGlobal || !pT1)
812 return FALSE;
813
814 if (pT1->pt1.x != -1 && pT1->pt1.y != -1)
815 {
816 T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1);
817 GetCursorPos(&pT1->pt0);
818 T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1);
819 ret = TRUE;
820 }
821
822 GlobalUnlock(hGlobal);
823 return ret;
824}
825
826static BOOL
828 _In_ HWND hWnd)
829{
830 BOOL ret = FALSE;
831 HGLOBAL hGlobal;
832 PT1WINDOW pT1;
833 INT x, y, iPressed;
834 HWND hwndOwner, hwndCapture = GetCapture();
835 HIMC hIMC;
836 LPINPUTCONTEXT pIC;
837
838 if (hwndCapture == hWnd)
840
841 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
842 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
843 if (!hGlobal || !pT1)
844 return FALSE;
845
846 iPressed = pT1->PressedKey;
847 if (iPressed >= T1K_NONE)
848 {
849 if (pT1->pt1.x != -1 && pT1->pt1.y != -1)
850 {
851 T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1);
852 x = pT1->pt0.x - pT1->pt1.x;
853 y = pT1->pt0.y - pT1->pt1.y;
855 pT1->pt1.x = pT1->pt1.y = -1;
856 pT1->PressedKey = T1K_NONE;
857 ret = TRUE;
858
859 hwndOwner = GetWindow(hWnd, GW_OWNER);
860 hIMC = (HIMC)GetWindowLongPtrW(hwndOwner, 0);
861 if (hIMC)
862 {
863 pIC = ImmLockIMC(hIMC);
864 if (pIC)
865 {
866 pIC->fdwInit |= INIT_SOFTKBDPOS;
867 pIC->ptSoftKbdPos.x = x;
868 pIC->ptSoftKbdPos.y = y;
869 ImmUnlockIMC(hIMC);
870 }
871 }
872 }
873 }
874 else
875 {
876 UINT iVK = gT1K2VK[iPressed];
878
879 T1_InvertButton(hWnd, 0, pT1, pT1->PressedKey);
880 pT1->PressedKey = T1K_NONE;
881 ret = TRUE;
882 }
883
884 GlobalUnlock(hGlobal);
885 return ret;
886}
887
888static LRESULT
890 _In_ HWND hWnd,
891 _In_ const SOFTKBDDATA *pData)
892{
893 HGLOBAL hGlobal;
894 PT1WINDOW pT1;
895 HDC hDC, hMemDC;
896 HFONT hFont;
897 HGDIOBJ hFontOld, hbmOld;
898 RECT rc;
899 INT iKey;
900
901 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
902 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
903 if (!hGlobal || !pT1)
904 return 1;
905
906 hDC = GetDC(hWnd);
907 hMemDC = CreateCompatibleDC(hDC);
909
910 hbmOld = SelectObject(hMemDC, pT1->hbmKeyboard);
911#if 0 /* The default text color is black */
912 SetTextColor(hMemDC, RGB(0, 0, 0));
913#endif
914 SetBkColor(hMemDC, RGB(192, 192, 192));
915
916 if (pT1->CharSet == DEFAULT_CHARSET)
917 {
919 }
920 else
921 {
923 lf.lfCharSet = (BYTE)pT1->CharSet;
925 }
926 hFontOld = SelectObject(hMemDC, hFont);
927
928 for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey)
929 {
930 INT x0 = T1_KEYPOS(iKey).x, y0 = T1_KEYPOS(iKey).y;
931 INT x = x0 + 6, y = y0 + 8;
932 WCHAR wch = pT1->chKeyChar[iKey] = pData->wCode[0][gT1K2VK[iKey]];
933 SetRect(&rc, x, y, x0 + pT1->cxDefWidth, y0 + pT1->cyDefHeight);
934 ExtTextOutW(hMemDC, x, y, ETO_OPAQUE, &rc, &wch, wch != 0, NULL);
935 }
936
937 DeleteObject(SelectObject(hMemDC, hFontOld));
938 SelectObject(hMemDC, hbmOld);
939 DeleteDC(hMemDC);
940 GlobalUnlock(hGlobal);
941 return 0;
942}
943
944static LRESULT
946 _In_ HWND hWnd,
949{
950 LRESULT ret = 1;
951 PT1WINDOW pT1;
952 HGLOBAL hGlobal;
953
954 switch (wParam)
955 {
957 {
958 TRACE("IMC_GETSOFTKBDFONT: %p\n", lParam);
959 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
960 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
961 if (hGlobal && pT1)
962 {
964 DWORD CharSet = pT1->CharSet;
965 GlobalUnlock(hGlobal);
966
967 *plf = g_T1LogFont;
969 plf->lfCharSet = (BYTE)CharSet;
970
971 ret = 0;
972 }
973 break;
974 }
976 {
977 const LOGFONTW *plf = (LPLOGFONTW)lParam;
978 TRACE("IMC_SETSOFTKBDFONT: %p\n", lParam);
979 if (g_T1LogFont.lfCharSet == plf->lfCharSet)
980 return 0;
981
982 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
983 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
984 if (hGlobal && pT1)
985 {
986 pT1->CharSet = plf->lfCharSet;
987 GlobalUnlock(hGlobal);
988 return 0;
989 }
990
991 break;
992 }
994 {
995 RECT rc;
996 TRACE("IMC_GETSOFTKBDPOS\n");
997 GetWindowRect(hWnd, &rc);
998 return MAKELRESULT(rc.left, rc.top);
999 }
1000 case IMC_SETSOFTKBDPOS:
1001 {
1002 POINT pt;
1004
1006 TRACE("IMC_SETSOFTKBDPOS(%ld, %ld)\n", pt.x, pt.y);
1007
1009
1011 if (hwndParent)
1012 {
1014 if (hIMC)
1015 {
1016 LPINPUTCONTEXT pIC = ImmLockIMC(hIMC);
1017 if (pIC)
1018 {
1019 pIC->ptSoftKbdPos.x = pt.x;
1020 pIC->ptSoftKbdPos.y = pt.y;
1021 ImmUnlockIMC(hIMC);
1022 return 0;
1023 }
1024 }
1025 }
1026 break;
1027 }
1030 {
1031 TRACE("IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE\n");
1032 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1033 pT1 = (PT1WINDOW)GlobalLock(hGlobal);
1034 if (!hGlobal || !pT1)
1035 return -1;
1036
1037 ret = pT1->KeyboardSubType;
1038
1040 pT1->KeyboardSubType = lParam;
1041
1042 GlobalUnlock(hGlobal);
1043 break;
1044 }
1045 case IMC_SETSOFTKBDDATA:
1046 {
1047 TRACE("IMC_SETSOFTKBDDATA: %p\n", lParam);
1049 if (!ret)
1050 {
1052 PostMessageW(hWnd, WM_PAINT, 0, 0);
1053 }
1054 break;
1055 }
1056 }
1057
1058 return ret;
1059}
1060
1061static LRESULT CALLBACK
1063{
1064 switch (uMsg)
1065 {
1066 case WM_CREATE:
1067 {
1068 return T1_OnCreate(hWnd);
1069 }
1070 case WM_DESTROY:
1071 {
1073 break;
1074 }
1075 case WM_SETCURSOR:
1076 {
1078 break;
1079 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1080 }
1081 case WM_MOUSEMOVE:
1082 {
1083 if (T1_OnMouseMove(hWnd))
1084 break;
1085 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1086 }
1087 case WM_PAINT:
1088 {
1089 PAINTSTRUCT ps;
1090 HDC hDC = BeginPaint(hWnd, &ps);
1091 T1_OnDraw(hDC, hWnd);
1092 EndPaint(hWnd, &ps);
1093 break;
1094 }
1095 case WM_SHOWWINDOW:
1096 {
1097 if (!lParam && wParam != SW_SHOWNORMAL)
1099 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1100 }
1101 case WM_MOUSEACTIVATE:
1102 {
1103 return MA_NOACTIVATE;
1104 }
1105 case WM_LBUTTONUP:
1106 {
1107 if (T1_OnButtonUp(hWnd))
1108 break;
1109 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1110 }
1111 case WM_IME_CONTROL:
1112 {
1114 }
1115 default:
1116 {
1117 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1118 }
1119 }
1120
1121 return 0;
1122}
1123
1124/*****************************************************************************
1125 * IME Soft Keyboard Type C1
1126 */
1127
1128#define C1_CLASSNAMEW L"SoftKBDClsC1"
1129
1130#define C1K_MAX 56
1131
1132#undef DEFINE_C1K
1133#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \
1134 c1k_code_name = c1k_code,
1135
1136/* Define C1 internal codes (C1K_...) */
1137typedef enum C1KEY
1138{
1139#include "c1keys.h"
1141
1142#undef DEFINE_C1K
1143#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \
1144 virtual_key_code,
1145
1146/* Mapping: C1K --> Virtual Key */
1148{
1149#include "c1keys.h"
1150};
1151
1152typedef struct C1WINDOW
1153{
1154 WCHAR Data[2][47];
1162
1163/* The flags for C1WINDOW.dwFlags */
1164#define FLAG_SHIFT_PRESSED 1
1165#define FLAG_DRAGGING 2
1166#define FLAG_PRESSED 4
1167
1170
1171static void C1_InitButtonPos(void)
1172{
1173 LONG x = 0, y = 0;
1174 INT iKey;
1175
1176 /* 1st row */
1177 for (iKey = C1K_OEM_3; iKey < C1K_Q; ++iKey)
1178 {
1179 gptC1ButtonPos[iKey].x = x;
1180 gptC1ButtonPos[iKey].y = y;
1181 x += 24;
1182 }
1183 gptC1ButtonPos[C1K_BACKSPACE].x = x;
1184 gptC1ButtonPos[C1K_BACKSPACE].y = y;
1185
1186 /* 2nd row */
1187 y = 28;
1188 gptC1ButtonPos[C1K_TAB].x = 0;
1189 gptC1ButtonPos[C1K_TAB].y = y;
1190 x = 36;
1191 for (; iKey < C1K_A; ++iKey)
1192 {
1193 gptC1ButtonPos[iKey].x = x;
1194 gptC1ButtonPos[iKey].y = y;
1195 x += 24;
1196 }
1197
1198 /* 3rd row */
1199 y = 56;
1200 gptC1ButtonPos[C1K_CAPS].x = 0;
1201 gptC1ButtonPos[C1K_CAPS].y = y;
1202 x = 42;
1203 for (; iKey < C1K_Z; ++iKey)
1204 {
1205 gptC1ButtonPos[iKey].x = x;
1206 gptC1ButtonPos[iKey].y = y;
1207 x += 24;
1208 }
1209 gptC1ButtonPos[C1K_ENTER].x = x;
1210 gptC1ButtonPos[C1K_ENTER].y = y;
1211
1212 /* 4th row */
1213 y = 84;
1214 gptC1ButtonPos[C1K_SHIFT].x = 0;
1215 gptC1ButtonPos[C1K_SHIFT].y = y;
1216 x = 60;
1217 for (; iKey < C1K_BACKSPACE; ++iKey)
1218 {
1219 gptC1ButtonPos[iKey].x = x;
1220 gptC1ButtonPos[iKey].y = y;
1221 x += 24;
1222 }
1223
1224 /* 5th row */
1225 y = 112;
1226 gptC1ButtonPos[C1K_INSERT].x = 0;
1227 gptC1ButtonPos[C1K_INSERT].y = y;
1228 gptC1ButtonPos[C1K_DELETE].x = 58;
1229 gptC1ButtonPos[C1K_DELETE].y = y;
1230 gptC1ButtonPos[C1K_SPACE].x = 96;
1231 gptC1ButtonPos[C1K_SPACE].y = y;
1232 gptC1ButtonPos[C1K_ESCAPE].x = 310;
1233 gptC1ButtonPos[C1K_ESCAPE].y = y;
1234}
1235
1236static void
1238 _In_ HDC hDC,
1239 _In_ INT x,
1240 _In_ INT y,
1241 _In_ INT width,
1242 _In_ INT height)
1243{
1244 HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH);
1245 HGDIOBJ hBlackPen = GetStockObject(BLACK_PEN);
1246 HGDIOBJ hWhiteBrush = GetStockObject(WHITE_BRUSH);
1247 HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH);
1248 INT y2 = y + height - 1;
1249
1250 /* Draw face */
1251 SelectObject(hDC, hLtGrayBrush);
1252 SelectObject(hDC, hBlackPen);
1253 Rectangle(hDC, x, y, x + width, y + height);
1254
1255 /* Draw light edge */
1256 SelectObject(hDC, hWhiteBrush);
1257 PatBlt(hDC, x, y2, 2, 1 - height, PATCOPY);
1258 PatBlt(hDC, x, y, width - 1, 2, PATCOPY);
1259
1260 /* Draw dark edge */
1261 SelectObject(hDC, hGrayBrush);
1262 PatBlt(hDC, x + 1, y2, width - 2, -1, PATCOPY);
1263 PatBlt(hDC, x + width - 1, y2, -1, 2 - height, PATCOPY);
1264}
1265
1266static void
1268 _In_ HDC hDC,
1269 _In_ INT iKey)
1270{
1271 INT width = 24, height = 28;
1272
1273 if (iKey < 0)
1274 return;
1275
1276 switch (iKey)
1277 {
1278 case C1K_BACKSPACE: case C1K_TAB:
1279 width = 36;
1280 break;
1281 case C1K_CAPS: case C1K_ENTER:
1282 width = 42;
1283 break;
1284 case C1K_SHIFT:
1285 width = 60;
1286 break;
1287 case C1K_INSERT: case C1K_DELETE: case C1K_ESCAPE:
1288 width = 38;
1289 height = 24;
1290 break;
1291 case C1K_SPACE:
1292 width = 172;
1293 height = 24;
1294 break;
1295 default:
1296 break;
1297 }
1298
1300 hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, DSTINVERT);
1301}
1302
1303static void
1305 _In_ HDC hDC,
1306 _In_ INT nBitmapID)
1307{
1309 HGDIOBJ hbmOld;
1310 HDC hMemDC;
1311 INT iKey;
1312
1314 hMemDC = CreateCompatibleDC(hDC);
1315 hbmOld = SelectObject(hMemDC, hBitmap);
1316 for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey)
1317 {
1318 BitBlt(hDC, gptC1ButtonPos[iKey].x + 2, gptC1ButtonPos[iKey].y + 2, 8, 8,
1319 hMemDC, iKey * 8, 0, SRCCOPY);
1320 }
1321 DeleteObject(SelectObject(hMemDC, hbmOld));
1322 DeleteDC(hMemDC);
1323}
1324
1325static void
1327 _In_ HDC hDC,
1328 _In_ INT x,
1329 _In_ INT y,
1330 _In_ INT width,
1331 _In_ INT height)
1332{
1333 HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH);
1334 HGDIOBJ hNullPen = GetStockObject(NULL_PEN);
1335 INT iKey;
1336
1337 /* Draw keyboard frame */
1338 SelectObject(hDC, hLtGrayBrush);
1339 SelectObject(hDC, hNullPen);
1340 Rectangle(hDC, x, y, width + 1, height + 1);
1341
1342 for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey)
1343 {
1344 C1_DrawConvexRect(hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28);
1345 }
1346
1348
1349 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28);
1350 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_BACKSPACE].x + 2, gptC1ButtonPos[C1K_BACKSPACE].y + 2, 32, 24, IDB_C1_BACKSPACE);
1351
1352 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28);
1353 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_TAB].x + 2, gptC1ButtonPos[C1K_TAB].y + 2, 32, 24, IDB_C1_TAB);
1354
1355 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28);
1356 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_CAPS].x + 2, gptC1ButtonPos[C1K_CAPS].y + 2, 38, 24, IDB_C1_CAPS);
1357
1358 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28);
1359 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ENTER].x + 2, gptC1ButtonPos[C1K_ENTER].y + 2, 38, 24, IDB_C1_ENTER);
1360
1361 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28);
1362 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_SHIFT].x + 2, gptC1ButtonPos[C1K_SHIFT].y + 2, 56, 24, IDB_C1_SHIFT);
1363
1364 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24);
1365 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_INSERT].x + 2, gptC1ButtonPos[C1K_INSERT].y + 2, 34, 20, IDB_C1_INS);
1366
1367 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24);
1368 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_DELETE].x + 2, gptC1ButtonPos[C1K_DELETE].y + 2, 34, 20, IDB_C1_DEL);
1369
1370 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24);
1371
1372 C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y , 38, 24);
1373 Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ESCAPE].x + 2, gptC1ButtonPos[C1K_ESCAPE].y + 2, 34, 20, IDB_C1_ESCAPE);
1374}
1375
1376static INT
1378 _In_ HWND hWnd)
1379{
1380 HGLOBAL hGlobal;
1381 PC1WINDOW pC1;
1382 HDC hDC, hMemDC;
1383 RECT rc;
1384 HGDIOBJ hbmOld;
1385 HBITMAP hbmKeyboard;
1386
1387 hGlobal = GlobalAlloc(GHND, sizeof(C1WINDOW));
1388 if (!hGlobal)
1389 return -1;
1390
1391 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1392 if (!pC1)
1393 {
1394 GlobalFree(hGlobal);
1395 return -1;
1396 }
1397 SetWindowLongPtrW(hWnd, 0, (LONG_PTR)hGlobal);
1398
1399 if (!gbC1ButtonInit)
1400 {
1403 }
1404
1405 pC1->iPressedKey = -1;
1406 pC1->CharSet = GB2312_CHARSET;
1407
1408 GetClientRect(hWnd, &rc);
1409
1410 hDC = GetDC(hWnd);
1411 hMemDC = CreateCompatibleDC(hDC);
1412 hbmKeyboard = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
1413 ReleaseDC(hWnd, hDC);
1414
1415 hbmOld = SelectObject(hMemDC, hbmKeyboard);
1416 C1_InitBitmap(hMemDC, rc.left, rc.top, rc.right, rc.bottom);
1417 SelectObject(hMemDC, hbmOld);
1418 pC1->hbmKeyboard = hbmKeyboard;
1419 DeleteDC(hMemDC);
1420
1421 GlobalUnlock(hGlobal);
1422 return 0;
1423}
1424
1425static void
1427 _In_ HDC hDC,
1428 _In_ HWND hWnd)
1429{
1430 HGLOBAL hGlobal;
1431 PC1WINDOW pC1;
1432 HDC hMemDC;
1433 RECT rc;
1434 HGDIOBJ hbmOld;
1435
1436 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1437 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1438 if (!hGlobal || !pC1)
1439 return;
1440
1441 GetClientRect(hWnd, &rc);
1442
1443 hMemDC = CreateCompatibleDC(hDC);
1444 hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard);
1445 BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY);
1446 SelectObject(hMemDC, hbmOld);
1447 DeleteDC(hMemDC);
1448
1449 GlobalUnlock(hGlobal);
1450}
1451
1452static BOOL
1454 _In_ HWND hWnd,
1455 _In_ const SOFTKBDDATA *pData)
1456{
1457 HGLOBAL hGlobal;
1458 PC1WINDOW pC1;
1459 HDC hDC, hMemDC;
1460 INT iKey;
1461 BOOL bDisabled;
1462 HBITMAP hbmKeyboard;
1463 HGDIOBJ hbmOld, hFontOld;
1464 HFONT hFont;
1465 RECT rc;
1466 LOGFONTW lf;
1467 const SOFTKBDDATAEX *pDataEx;
1468
1469 if (pData->uCount != 2)
1470 return 0;
1471
1472 pDataEx = (const SOFTKBDDATAEX *)pData;
1473
1474 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1475 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1476 if (!hGlobal || !pC1)
1477 return FALSE;
1478
1479 hDC = GetDC(hWnd);
1480 hMemDC = CreateCompatibleDC(hDC);
1481
1482 hbmKeyboard = pC1->hbmKeyboard;
1483 hbmOld = SelectObject(hMemDC, hbmKeyboard);
1484
1485 GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
1486 lf.lfHeight = -12;
1487 if (pC1->CharSet != DEFAULT_CHARSET)
1488 lf.lfCharSet = (BYTE)pC1->CharSet;
1489
1491 hFontOld = SelectObject(hMemDC, hFont);
1492 for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey)
1493 {
1494 pC1->Data[1][iKey] = pDataEx->wCode[0][(BYTE)gC1K2VK[iKey]];
1495 pC1->Data[0][iKey] = pDataEx->wCode[1][(BYTE)gC1K2VK[iKey]];
1496 }
1497
1498 SetBkColor(hMemDC, RGB(191, 191, 191));
1499 for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey)
1500 {
1501 /* Upper right */
1502 rc.right = gptC1ButtonPos[iKey].x + 24 - 2;
1503 rc.top = gptC1ButtonPos[iKey].y + 2;
1504 rc.left = rc.right - 14;
1505 rc.bottom = rc.top + 14;
1506 bDisabled = (pC1->Data[0][iKey] == 0);
1507 DrawTextW(hMemDC, &pC1->Data[0][iKey], !bDisabled, &rc,
1509
1510 /* Lower left */
1511 rc.left = gptC1ButtonPos[iKey].x + 2;
1512 rc.bottom = gptC1ButtonPos[iKey].y + 28 - 2;
1513 rc.right = rc.left + 14;
1514 rc.top = rc.bottom - 14;
1515 bDisabled = (pC1->Data[1][iKey] == 0);
1516 DrawTextW(hMemDC, &pC1->Data[1][iKey], !bDisabled, &rc,
1518 }
1519
1520 if (pC1->dwFlags & FLAG_SHIFT_PRESSED)
1521 C1_InvertButton(hMemDC, C1K_SHIFT);
1522
1523 pC1->dwFlags = 0;
1524
1525 SelectObject(hMemDC, hbmOld);
1526 DeleteObject(SelectObject(hMemDC, hFontOld));
1527
1528 DeleteDC(hMemDC);
1529 ReleaseDC(hWnd, hDC);
1530
1531 GlobalUnlock(hGlobal);
1532 return TRUE;
1533}
1534
1535static void
1537 _In_ HWND hWnd,
1538 _In_ LPPOINT ppt1,
1539 _Inout_ LPPOINT ppt2)
1540{
1541 HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH);
1542 INT x, y;
1543 RECT rc, rcWork;
1545 HDC hDisplayDC;
1546
1547 Imm32GetAllMonitorSize(&rcWork);
1548 hDisplayDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
1549
1550 SelectObject(hDisplayDC, hGrayBrush);
1551 x = ppt1->x - ppt2->x;
1552 y = ppt1->y - ppt2->y;
1553 if (x < rcWork.left)
1554 x = rcWork.left;
1555 if (y < rcWork.top)
1556 y = rcWork.top;
1557
1558 GetWindowRect(hWnd, &rc);
1559
1560 if (rc.right - rc.left + x > rcWork.right)
1561 x = rc.left + rcWork.right - rc.right;
1562 if (y + rc.bottom - rc.top > rcWork.bottom)
1563 y = rc.top + rcWork.bottom - rc.bottom;
1564
1565 ppt2->x = ppt1->x - x;
1566 ppt2->y = ppt1->y - y;
1567
1568 PatBlt(hDisplayDC, x, y, rc.right - rc.left - cxBorder, cyBorder, PATINVERT);
1569 PatBlt(hDisplayDC, x, y + cyBorder, cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT);
1570 PatBlt(hDisplayDC, x + cxBorder, y + rc.bottom - rc.top, rc.right - rc.left - cxBorder, -cyBorder, PATINVERT);
1571 PatBlt(hDisplayDC, x + rc.right - rc.left, y, -cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT);
1572
1573 DeleteDC(hDisplayDC);
1574}
1575
1576static INT
1578 _In_ const POINT *ppt)
1579{
1580 INT iKey;
1581
1582 for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey)
1583 {
1584 if (Imm32PtInRect(ppt, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28))
1585 return iKey;
1586 }
1587
1588 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28))
1589 return C1K_BACKSPACE;
1590 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28))
1591 return C1K_TAB;
1592 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28))
1593 return C1K_CAPS;
1594 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28))
1595 return C1K_ENTER;
1596 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28))
1597 return C1K_SHIFT;
1598 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y, 38, 24))
1599 return C1K_ESCAPE;
1600 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24))
1601 return C1K_SPACE;
1602 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24))
1603 return C1K_INSERT;
1604 if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24))
1605 return C1K_DELETE;
1606
1607 return -1;
1608}
1609
1610static void
1612 _In_ HWND hWnd,
1613 _Inout_ PC1WINDOW pC1)
1614{
1615 INT iPressedKey;
1616 HDC hMemDC;
1617 WCHAR wch = 0xFF;
1618 HGDIOBJ hbmOld;
1619 HDC hDC;
1620
1622
1623 iPressedKey = pC1->iPressedKey;
1624 if (iPressedKey == -1)
1625 {
1626 pC1->dwFlags |= FLAG_DRAGGING;
1627 C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2);
1628 return;
1629 }
1630
1631 if (iPressedKey < C1K_BACKSPACE)
1632 {
1633 wch = pC1->Data[!(pC1->dwFlags & 1)][iPressedKey];
1634 if (!wch)
1635 {
1636 MessageBeep(0xFFFFFFFF);
1637 pC1->iPressedKey = -1;
1638 return;
1639 }
1640 }
1641
1642 if ((iPressedKey != C1K_SHIFT) || !(pC1->dwFlags & FLAG_SHIFT_PRESSED))
1643 {
1644 hDC = GetDC(hWnd);
1645 hMemDC = CreateCompatibleDC(hDC);
1646 hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard);
1647 C1_InvertButton(hDC, pC1->iPressedKey);
1648 C1_InvertButton(hMemDC, pC1->iPressedKey);
1649 SelectObject(hMemDC, hbmOld);
1650 DeleteDC(hMemDC);
1651 ReleaseDC(hWnd, hDC);
1652 }
1653
1654 pC1->dwFlags |= FLAG_PRESSED;
1655}
1656
1657static BOOL
1659 _In_ HWND hWnd,
1661{
1662 HGLOBAL hGlobal;
1663 PC1WINDOW pC1;
1664 HCURSOR hCursor;
1665 INT iKey;
1666 POINT pt1, pt2;
1667
1668 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1669 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1670 if (!hGlobal || !pC1)
1671 return FALSE;
1672
1673 if (pC1->dwFlags & FLAG_DRAGGING)
1674 {
1675 hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL);
1676 SetCursor(hCursor);
1677 GlobalUnlock(hGlobal);
1678 return TRUE;
1679 }
1680
1681 GetCursorPos(&pt1);
1682 pt2 = pt1;
1683 ScreenToClient(hWnd, &pt2);
1684
1685 iKey = C1_HitTest(&pt2);
1686 if (iKey == -1)
1687 hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL);
1688 else
1689 hCursor = LoadCursorW(0, (LPCWSTR)IDC_HAND);
1690 SetCursor(hCursor);
1691
1693 {
1694 pC1->pt1 = pt1;
1695 pC1->pt2 = pt2;
1696 pC1->iPressedKey = iKey;
1697 C1_OnButtonDown(hWnd, pC1);
1698 }
1699
1700 GlobalUnlock(hGlobal);
1701 return TRUE;
1702}
1703
1704static BOOL
1706 _In_ HWND hWnd,
1709{
1710 HGLOBAL hGlobal;
1711 PC1WINDOW pC1;
1712 HDC hMemDC;
1713 DWORD dwFlags;
1714 INT iPressedKey;
1715 POINT pt;
1716 HGDIOBJ hbmOld;
1717 HDC hDC;
1718 INT iKey;
1719
1720 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1721 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1722 if (!hGlobal || !pC1)
1723 return FALSE;
1724
1725 if (pC1->dwFlags & FLAG_DRAGGING)
1726 {
1727 C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2);
1728 GetCursorPos(&pC1->pt1);
1729 C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2);
1730 GlobalUnlock(hGlobal);
1731 return TRUE;
1732 }
1733
1734 if (pC1->iPressedKey != -1)
1735 {
1736 GetCursorPos(&pt);
1738 iKey = C1_HitTest(&pt);
1739
1740 hDC = GetDC(hWnd);
1741 hMemDC = CreateCompatibleDC(hDC);
1742 hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard);
1743 dwFlags = pC1->dwFlags;
1744
1745 iPressedKey = pC1->iPressedKey;
1746 if (!!(dwFlags & FLAG_PRESSED) == (iKey != iPressedKey))
1747 {
1748 if (iPressedKey != C1K_SHIFT || !(dwFlags & FLAG_SHIFT_PRESSED))
1749 {
1750 C1_InvertButton(hDC, iPressedKey);
1751 C1_InvertButton(hMemDC, pC1->iPressedKey);
1752 }
1753
1754 pC1->dwFlags ^= FLAG_PRESSED;
1755 }
1756
1757 SelectObject(hMemDC, hbmOld);
1758 DeleteDC(hMemDC);
1759 ReleaseDC(hWnd, hDC);
1760 }
1761
1762 GlobalUnlock(hGlobal);
1763 return TRUE;
1764}
1765
1766static BOOL
1768 _In_ HWND hWnd,
1771{
1772 HGLOBAL hGlobal;
1773 PC1WINDOW pC1;
1774 BOOL ret = FALSE;
1775 INT x, y, iKey;
1776 HDC hDC, hMemDC;
1777 HGDIOBJ hbmOld;
1778 HIMC hIMC;
1779 HWND hwndOwner;
1780 LPINPUTCONTEXT pIC;
1781
1782 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1783 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1784 if (!hGlobal || !pC1)
1785 return FALSE;
1786
1788
1789 if (pC1->dwFlags & FLAG_DRAGGING)
1790 {
1791 pC1->dwFlags &= ~FLAG_DRAGGING;
1792 C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2);
1793 x = pC1->pt1.x - pC1->pt2.x;
1794 y = pC1->pt1.y - pC1->pt2.y;
1795 SetWindowPos(hWnd, 0, x, y, 0, 0, 0x15u);
1796 ret = TRUE;
1797
1798 hwndOwner = GetWindow(hWnd, GW_OWNER);
1799 hIMC = (HIMC)GetWindowLongPtrW(hwndOwner, 0);
1800 if (hIMC)
1801 {
1802 pIC = ImmLockIMC(hIMC);
1803 if (pIC)
1804 {
1805 pIC->fdwInit |= INIT_SOFTKBDPOS;
1806 pIC->ptSoftKbdPos.x = x;
1807 pIC->ptSoftKbdPos.y = y;
1808 ImmUnlockIMC(hIMC);
1809 }
1810 }
1811
1812 GlobalUnlock(hGlobal);
1813 return ret;
1814 }
1815
1816 iKey = pC1->iPressedKey;
1817 if (iKey == -1)
1818 return FALSE;
1819
1820 if (!(pC1->dwFlags & FLAG_PRESSED))
1821 {
1822 pC1->iPressedKey = -1;
1823 GlobalUnlock(hGlobal);
1824 return ret;
1825 }
1826
1827 if (iKey == C1K_SHIFT)
1828 {
1829 if (!(pC1->dwFlags & FLAG_SHIFT_PRESSED))
1830 {
1832 pC1->dwFlags &= ~FLAG_PRESSED;
1833 pC1->iPressedKey = -1;
1834 GlobalUnlock(hGlobal);
1835 return ret;
1836 }
1837 }
1838 else if (iKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED))
1839 {
1840 INT iVK = gC1K2VK[pC1->iPressedKey];
1841 keybd_event(VK_SHIFT, guScanCode[C1K_SHIFT], 0, 0);
1842 keybd_event(iVK, guScanCode[(BYTE)iVK], 0, 0);
1845 }
1846 else
1847 {
1848 INT iVK = gC1K2VK[iKey];
1849 keybd_event(iVK, guScanCode[iVK], 0, 0);
1850 keybd_event(iVK, guScanCode[iVK], KEYEVENTF_KEYUP, 0);
1851 }
1852
1853 ret = TRUE;
1854
1855 hDC = GetDC(hWnd);
1856 hMemDC = CreateCompatibleDC(hDC);
1857 hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard);
1858
1860 C1_InvertButton(hMemDC, pC1->iPressedKey);
1861
1862 if (pC1->iPressedKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED))
1863 {
1864 C1_InvertButton(hDC, C1K_SHIFT);
1865 C1_InvertButton(hMemDC, C1K_SHIFT);
1866 }
1867
1868 if (pC1->iPressedKey < C1K_BACKSPACE || pC1->iPressedKey == C1K_SHIFT)
1869 pC1->dwFlags &= ~FLAG_SHIFT_PRESSED;
1870
1871 SelectObject(hMemDC, hbmOld);
1872 DeleteDC(hMemDC);
1873 ReleaseDC(hWnd, hDC);
1874
1875 pC1->dwFlags &= ~FLAG_PRESSED;
1876 pC1->iPressedKey = -1;
1877 GlobalUnlock(hGlobal);
1878 return ret;
1879}
1880
1881static void
1883 _In_ HWND hWnd)
1884{
1885 HGLOBAL hGlobal;
1886 PC1WINDOW pC1;
1887 HWND hwndOwner;
1888
1889 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1890 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1891 if (!hGlobal || !pC1)
1892 return;
1893
1894 if (pC1->dwFlags & FLAG_DRAGGING)
1895 C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2);
1896
1898 GlobalUnlock(hGlobal);
1899 GlobalFree(hGlobal);
1900
1901 hwndOwner = GetWindow(hWnd, GW_OWNER);
1902 if (hwndOwner)
1904}
1905
1906static LRESULT
1908 _In_ HWND hWnd,
1911{
1912 HGLOBAL hGlobal;
1913 PC1WINDOW pC1;
1914 LOGFONTW lf;
1915 RECT rc;
1916 LRESULT ret = 0;
1917 HDC hDC;
1918
1919 switch (wParam)
1920 {
1921 case IMC_GETSOFTKBDFONT:
1922 {
1923 TRACE("IMC_GETSOFTKBDFONT: %p\n", lParam);
1924 hDC = GetDC(hWnd);
1926 ReleaseDC(hWnd, hDC);
1927 *(LPLOGFONTW)lParam = lf;
1928 break;
1929 }
1930 case IMC_SETSOFTKBDFONT:
1931 {
1933 LOGFONTW lf;
1934 TRACE("IMC_SETSOFTKBDFONT: %p\n", lParam);
1936 if (lf.lfCharSet == plf->lfCharSet)
1937 return 0;
1938
1939 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1940 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1941 if (!hGlobal || !pC1)
1942 return 1;
1943
1944 pC1->CharSet = plf->lfCharSet;
1945 GlobalUnlock(hGlobal);
1946 break;
1947 }
1948 case IMC_GETSOFTKBDPOS:
1949 {
1950 TRACE("IMC_GETSOFTKBDPOS\n");
1951 GetWindowRect(hWnd, &rc);
1952 return MAKELRESULT(rc.left, rc.top);
1953 }
1954 case IMC_SETSOFTKBDPOS:
1955 {
1956 POINT pt;
1958 TRACE("IMC_SETSOFTKBDPOS: %d, %d\n", pt.x, pt.y);
1959 SetWindowPos(hWnd, NULL, pt.x, pt.y, 0, 0,
1961 break;
1962 }
1965 {
1966 TRACE("IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE: %p, %p\n", wParam, lParam);
1967 hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0);
1968 pC1 = (PC1WINDOW)GlobalLock(hGlobal);
1969 if (!hGlobal || !pC1)
1970 return -1;
1971 ret = pC1->SubType;
1973 pC1->SubType = lParam;
1974 GlobalUnlock(hGlobal);
1975 break;
1976 }
1977 case IMC_SETSOFTKBDDATA:
1978 {
1979 TRACE("IMC_SETSOFTKBDDATA: %p\n", lParam);
1981 return -1;
1982
1983 InvalidateRect(hWnd, 0, 0);
1984 }
1985 default:
1986 break;
1987 }
1988
1989 return ret;
1990}
1991
1992static LRESULT CALLBACK
1994{
1995 switch (uMsg)
1996 {
1997 case WM_CREATE:
1998 {
1999 return C1_OnCreate(hWnd);
2000 }
2001 case WM_DESTROY:
2002 {
2004 break;
2005 }
2006 case WM_SETCURSOR:
2007 {
2009 break;
2010 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
2011 }
2012 case WM_MOUSEMOVE:
2013 {
2015 break;
2016 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
2017 }
2018 case WM_LBUTTONUP:
2019 {
2021 break;
2022 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
2023 }
2024 case WM_PAINT:
2025 {
2026 PAINTSTRUCT ps;
2027 HDC hDC = BeginPaint(hWnd, &ps);
2028 C1_OnDraw(hDC, hWnd);
2029 EndPaint(hWnd, &ps);
2030 break;
2031 }
2032 case WM_IME_CONTROL:
2033 {
2035 }
2036 case WM_MOUSEACTIVATE:
2037 {
2038 return MA_NOACTIVATE;
2039 }
2040 default:
2041 {
2042 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
2043 }
2044 }
2045 return 0;
2046}
2047
2048/*****************************************************************************/
2049
2050static BOOL
2052 _In_ UINT uType)
2053{
2054 WNDCLASSEXW wcx;
2055 LPCWSTR pszClass = ((uType == SOFTKEYBOARD_TYPE_T1) ? T1_CLASSNAMEW : C1_CLASSNAMEW);
2056 if (GetClassInfoExW(ghImm32Inst, pszClass, &wcx))
2057 return TRUE;
2058
2059 ZeroMemory(&wcx, sizeof(wcx));
2060 wcx.cbSize = sizeof(wcx);
2061 wcx.style = CS_IME;
2062 wcx.cbWndExtra = sizeof(PT1WINDOW);
2064 wcx.hInstance = ghImm32Inst;
2066 wcx.lpszClassName = pszClass;
2067
2068 if (uType == SOFTKEYBOARD_TYPE_T1)
2069 {
2072 }
2073 else
2074 {
2077 }
2078
2079 return !!RegisterClassExW(&wcx);
2080}
2081
2082static void
2084 _In_ UINT uType,
2085 _Out_ LPINT pcx,
2086 _Out_ LPINT pcy)
2087{
2088 if (uType == SOFTKEYBOARD_TYPE_T1)
2089 {
2092 *pcx = 15 * tm.tmMaxCharWidth + 2 * gptRaiseEdge.x + 139;
2093 *pcy = 5 * tm.tmHeight + 2 * gptRaiseEdge.y + 58;
2094 }
2095 else
2096 {
2098 *pcx = 2 * (GetSystemMetrics(SM_CXBORDER) + cxEdge) + 348;
2099 *pcy = 2 * (GetSystemMetrics(SM_CYBORDER) + cyEdge) + 136;
2100 }
2101}
2102
2103/***********************************************************************
2104 * ImmCreateSoftKeyboard (IMM32.@)
2105 *
2106 * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmCreateSoftKeyboard.html
2107 */
2110 _In_ UINT uType,
2112 _In_ INT x,
2113 _In_ INT y)
2114{
2115 HKL hKL;
2116 PIMEDPI pImeDpi;
2117 UINT iVK;
2118 INT xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD, cxEdge, cyEdge;
2119 HWND hwndSoftKBD;
2120 DWORD Style, ExStyle, UICaps;
2121 LPCWSTR pszClass;
2122 RECT rcWorkArea;
2123
2124 TRACE("(%u, %p, %d, %d)\n", uType, hwndParent, x, y);
2125
2126 if ((uType != SOFTKEYBOARD_TYPE_T1) && (uType != SOFTKEYBOARD_TYPE_C1))
2127 {
2128 ERR("uType: %u\n", uType);
2129 return NULL; /* Invalid keyboard type */
2130 }
2131
2132 /* Check IME */
2133 hKL = GetKeyboardLayout(0);
2134 pImeDpi = ImmLockImeDpi(hKL);
2135 if (IS_NULL_UNEXPECTEDLY(pImeDpi))
2136 return NULL; /* No IME */
2137
2138 UICaps = pImeDpi->ImeInfo.fdwUICaps;
2139 ImmUnlockImeDpi(pImeDpi);
2140
2141 /* Check IME capability */
2142 if (!(UICaps & UI_CAP_SOFTKBD))
2143 {
2144 ERR("UICaps: 0x%X\n", UICaps);
2145 return NULL; /* No capability for soft keyboard */
2146 }
2147
2148 /* Want metrics? */
2150 {
2151 for (iVK = 0; iVK < 0xFF; ++iVK)
2152 {
2153 guScanCode[iVK] = MapVirtualKeyW(iVK, 0);
2154 }
2155
2156 cxEdge = GetSystemMetrics(SM_CXEDGE);
2157 cyEdge = GetSystemMetrics(SM_CYEDGE);
2160
2162 }
2163
2164 if (!Imm32GetNearestWorkArea(hwndParent, &rcWorkArea))
2165 return NULL;
2166
2167 /* Register the window class */
2168 if (!Imm32RegisterSoftKeyboard(uType))
2169 {
2170 ERR("\n");
2171 return NULL;
2172 }
2173
2174 /* Calculate keyboard size */
2175 Imm32GetSoftKeyboardDimension(uType, &cxSoftKBD, &cySoftKBD);
2176
2177 /* Adjust keyboard position */
2178 xSoftKBD = Imm32Clamp(x, rcWorkArea.left, rcWorkArea.right - cxSoftKBD);
2179 ySoftKBD = Imm32Clamp(y, rcWorkArea.top , rcWorkArea.bottom - cySoftKBD);
2180
2181 /* Create soft keyboard window */
2182 if (uType == SOFTKEYBOARD_TYPE_T1)
2183 {
2185 ExStyle = 0;
2186 pszClass = T1_CLASSNAMEW;
2187 }
2188 else
2189 {
2192 pszClass = C1_CLASSNAMEW;
2193 }
2194 hwndSoftKBD = CreateWindowExW(ExStyle, pszClass, NULL, Style,
2195 xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD,
2197 /* Initial is hidden */
2198 ShowWindow(hwndSoftKBD, SW_HIDE);
2199 UpdateWindow(hwndSoftKBD);
2200
2201 return hwndSoftKBD;
2202}
2203
2204/***********************************************************************
2205 * ImmShowSoftKeyboard (IMM32.@)
2206 *
2207 * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmShowSoftKeyboard.html
2208 */
2211 _In_ HWND hwndSoftKBD,
2212 _In_ INT nCmdShow)
2213{
2214 TRACE("(%p, %d)\n", hwndSoftKBD, nCmdShow);
2215
2216 if (nCmdShow != SW_HIDE && nCmdShow != SW_SHOWNOACTIVATE)
2217 WARN("nCmdShow %d is unexpected\n", nCmdShow);
2218
2219 return hwndSoftKBD && ShowWindow(hwndSoftKBD, nCmdShow);
2220}
2221
2222/***********************************************************************
2223 * ImmDestroySoftKeyboard (IMM32.@)
2224 *
2225 * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmDestroySoftKeyboard.html
2226 */
2229 _In_ HWND hwndSoftKBD)
2230{
2231 TRACE("(%p)\n", hwndSoftKBD);
2232 return DestroyWindow(hwndSoftKBD);
2233}
static HDC hDC
Definition: 3dtext.c:33
const DWORD Style
Definition: appswitch.c:72
const DWORD ExStyle
Definition: appswitch.c:73
int cyBorder
Definition: appswitch.c:54
int cxBorder
Definition: appswitch.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
HFONT hFont
Definition: main.c:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static HWND hwndParent
Definition: cryptui.c:299
#define LF_FACESIZE
Definition: dimm.idl:39
DWORD HIMC
Definition: dimm.idl:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
#define CALLBACK
Definition: compat.h:35
static void CharSet(RTF_Info *info)
Definition: reader.c:2400
#define pt(x, y)
Definition: drawing.c:79
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Height *Stride) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Stride)
Definition: common.c:42
#define RGB(r, g, b)
Definition: precomp.h:67
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HMODULE ghImm32Inst
Definition: imm.c:17
PIMEDPI WINAPI ImmLockImeDpi(_In_ HKL hKL)
Definition: ime.c:532
VOID WINAPI ImmUnlockImeDpi(_Inout_opt_ PIMEDPI pImeDpi)
Definition: ime.c:562
#define UI_CAP_SOFTKBD
Definition: imm.h:256
#define SOFTKEYBOARD_TYPE_C1
Definition: imm.h:469
#define SOFTKEYBOARD_TYPE_T1
Definition: imm.h:468
#define IMC_SETSOFTKBDDATA
Definition: immdev.h:95
#define INIT_SOFTKBDPOS
Definition: immdev.h:156
#define IMC_SETSOFTKBDFONT
Definition: immdev.h:90
LPINPUTCONTEXT WINAPI ImmLockIMC(_In_ HIMC hIMC)
Definition: imm.c:1080
#define IMC_GETSOFTKBDSUBTYPE
Definition: immdev.h:93
#define IMC_GETSOFTKBDPOS
Definition: immdev.h:91
#define IMC_SETSOFTKBDSUBTYPE
Definition: immdev.h:94
#define IMN_SOFTKBDDESTROYED
Definition: immdev.h:98
BOOL WINAPI ImmUnlockIMC(_In_ HIMC hIMC)
Definition: imm.c:1090
#define IMC_SETSOFTKBDPOS
Definition: immdev.h:92
#define IMC_GETSOFTKBDFONT
Definition: immdev.h:89
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define debugstr_w
Definition: kernel32.h:32
GLint dy
Definition: linetemp.h:97
GLint x0
Definition: linetemp.h:95
GLint y0
Definition: linetemp.h:96
GLint dx
Definition: linetemp.h:97
#define ZeroMemory
Definition: minwinbase.h:31
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
int * LPINT
Definition: minwindef.h:151
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static MONITORINFO mi
Definition: win.c:9400
UINT_PTR HKL
Definition: msctf.idl:125
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
unsigned int UINT
Definition: ndis.h:50
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:16
#define HGLOBAL
Definition: ole.h:15
#define WS_EX_DLGMODALFRAME
Definition: pedump.c:645
short WCHAR
Definition: pedump.c:58
#define WS_BORDER
Definition: pedump.c:625
#define WS_POPUP
Definition: pedump.c:616
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define _countof(array)
Definition: sndvol32.h:70
static void C1_OnButtonDown(_In_ HWND hWnd, _Inout_ PC1WINDOW pC1)
Definition: softkbd.c:1611
struct tagSOFTKBDDATAEX * PSOFTKBDDATAEX
static void C1_InitBitmap(_In_ HDC hDC, _In_ INT x, _In_ INT y, _In_ INT width, _In_ INT height)
Definition: softkbd.c:1326
static POINT gptRaiseEdge
Definition: softkbd.c:21
#define FLAG_SHIFT_PRESSED
Definition: softkbd.c:1164
static BOOL T1_IsValidButton(_In_ UINT iKey, _In_ const T1WINDOW *pT1)
Definition: softkbd.c:717
static POINT gptC1ButtonPos[C1K_MAX]
Definition: softkbd.c:1169
#define C1K_MAX
Definition: softkbd.c:1130
struct tagSOFTKBDDATAEX SOFTKBDDATAEX
static void C1_DrawDragBorder(_In_ HWND hWnd, _In_ LPPOINT ppt1, _Inout_ LPPOINT ppt2)
Definition: softkbd.c:1536
static BOOL C1_OnButtonUp(_In_ HWND hWnd, _In_ WPARAM wParam, _In_ LPARAM lParam)
Definition: softkbd.c:1767
static BOOL C1_OnSetCursor(_In_ HWND hWnd, _In_ LPARAM lParam)
Definition: softkbd.c:1658
#define FLAG_PRESSED
Definition: softkbd.c:1166
static BOOL gbC1ButtonInit
Definition: softkbd.c:1168
static LRESULT T1_OnImeControl(_In_ HWND hWnd, _Inout_ WPARAM wParam, _Inout_ LPARAM lParam)
Definition: softkbd.c:945
static void T1_DrawDragBorder(_In_ HWND hWnd, _In_ const POINT *ppt1, _In_ const POINT *ppt2)
Definition: softkbd.c:534
static void C1_OnDraw(_In_ HDC hDC, _In_ HWND hWnd)
Definition: softkbd.c:1426
static void C1_InitButtonPos(void)
Definition: softkbd.c:1171
static BOOL T1_OnSetCursor(_In_ HWND hWnd, _In_ LPARAM lParam)
Definition: softkbd.c:731
static BOOL Imm32RegisterSoftKeyboard(_In_ UINT uType)
Definition: softkbd.c:2051
C1KEY
Definition: softkbd.c:1138
#define C1_CLASSNAMEW
Definition: softkbd.c:1128
static void Imm32GetSoftKeyboardDimension(_In_ UINT uType, _Out_ LPINT pcx, _Out_ LPINT pcy)
Definition: softkbd.c:2083
struct C1WINDOW * PC1WINDOW
#define T1_CLASSNAMEW
Definition: softkbd.c:119
static void T1_GetTextMetric(_Out_ LPTEXTMETRICW ptm)
Definition: softkbd.c:171
#define FLAG_DRAGGING
Definition: softkbd.c:1165
BOOL WINAPI ImmDestroySoftKeyboard(_In_ HWND hwndSoftKBD)
Definition: softkbd.c:2228
const BYTE gC1K2VK[C1K_MAX]
Definition: softkbd.c:1147
static UINT guScanCode[256]
Definition: softkbd.c:20
static void C1_OnDestroy(_In_ HWND hWnd)
Definition: softkbd.c:1882
static BOOL C1_OnMouseMove(_In_ HWND hWnd, _In_ WPARAM wParam, _In_ LPARAM lParam)
Definition: softkbd.c:1705
static LRESULT CALLBACK T1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: softkbd.c:1062
static INT T1_OnCreate(_In_ HWND hWnd)
Definition: softkbd.c:506
static void C1_InvertButton(_In_ HDC hDC, _In_ INT iKey)
Definition: softkbd.c:1267
static LOGFONTW g_T1LogFont
Definition: softkbd.c:168
static void T1_DrawLabels(_In_ HDC hDC, _In_ const T1WINDOW *pT1, _In_ LPCWSTR pszBmpName)
Definition: softkbd.c:347
static BOOL C1_SetData(_In_ HWND hWnd, _In_ const SOFTKBDDATA *pData)
Definition: softkbd.c:1453
static BOOL T1_OnButtonUp(_In_ HWND hWnd)
Definition: softkbd.c:827
static void T1_OnDraw(_In_ HDC hDC, _In_ HWND hWnd)
Definition: softkbd.c:638
static BOOL T1_OnMouseMove(_In_ HWND hWnd)
Definition: softkbd.c:802
static LRESULT C1_OnImeControl(_In_ HWND hWnd, _In_ WPARAM wParam, _In_ LPARAM lParam)
Definition: softkbd.c:1907
static void Imm32DrawBitmap(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ INT width, _In_ INT height, _In_ INT nBitmapID)
Definition: softkbd.c:42
static BOOL g_bWantSoftKBDMetrics
Definition: softkbd.c:22
static void T1_InitBitmap(_In_ HWND hWnd, _Inout_ PT1WINDOW pT1)
Definition: softkbd.c:367
static BOOL Imm32GetNearestWorkArea(_In_opt_ HWND hwnd, _Out_ LPRECT prcWork)
Definition: softkbd.c:88
const BYTE gT1K2VK[T1K_MAX]
Definition: softkbd.c:138
HWND WINAPI ImmCreateSoftKeyboard(_In_ UINT uType, _In_ HWND hwndParent, _In_ INT x, _In_ INT y)
Definition: softkbd.c:2109
static void T1_InvertButton(_In_ HWND hWnd, _In_ HDC hDC, _In_ const T1WINDOW *pT1, _In_ UINT iPressed)
Definition: softkbd.c:581
static UINT T1_HitTest(_In_ const T1WINDOW *pT1, _In_ const POINT *ppt)
Definition: softkbd.c:665
#define T1K_MAX
Definition: softkbd.c:135
static void T1_DrawConvexRect(_In_ HDC hDC, _In_ INT x, _In_ INT y, _In_ INT width, _In_ INT height)
Definition: softkbd.c:312
static VOID Imm32GetAllMonitorSize(_Out_ LPRECT prcWork)
Definition: softkbd.c:72
static void C1_DrawConvexRect(_In_ HDC hDC, _In_ INT x, _In_ INT y, _In_ INT width, _In_ INT height)
Definition: softkbd.c:1237
static BOOL Imm32PtInRect(_In_ const POINT *ppt, _In_ LONG x, _In_ LONG y, _In_ LONG cx, _In_ LONG cy)
Definition: softkbd.c:31
T1KEY
Definition: softkbd.c:127
static void T1_OnDestroy(_In_ HWND hWnd)
Definition: softkbd.c:556
static LRESULT CALLBACK C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: softkbd.c:1993
static void T1_InitButtonPos(_Out_ PT1WINDOW pT1)
Definition: softkbd.c:215
static INT C1_OnCreate(_In_ HWND hWnd)
Definition: softkbd.c:1377
static INT C1_HitTest(_In_ const POINT *ppt)
Definition: softkbd.c:1577
#define T1_KEYPOS(iKey)
Definition: softkbd.c:166
static LRESULT T1_SetData(_In_ HWND hWnd, _In_ const SOFTKBDDATA *pData)
Definition: softkbd.c:889
struct T1WINDOW * PT1WINDOW
BOOL WINAPI ImmShowSoftKeyboard(_In_ HWND hwndSoftKBD, _In_ INT nCmdShow)
Definition: softkbd.c:2210
static void C1_DrawLabel(_In_ HDC hDC, _In_ INT nBitmapID)
Definition: softkbd.c:1304
static INT Imm32Clamp(_In_ INT x, _In_ INT xMin, _In_ INT xMax)
Definition: softkbd.c:59
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
LPARAM SubType
Definition: softkbd.c:1157
INT iPressedKey
Definition: softkbd.c:1158
DWORD dwFlags
Definition: softkbd.c:1155
POINT pt1
Definition: softkbd.c:1159
WCHAR Data[2][47]
Definition: softkbd.c:1154
HBITMAP hbmKeyboard
Definition: softkbd.c:1156
POINT pt2
Definition: softkbd.c:1159
DWORD CharSet
Definition: softkbd.c:1160
IMEINFO ImeInfo
Definition: imm32_undoc.h:108
BYTE lfOutPrecision
Definition: dimm.idl:68
LONG lfHeight
Definition: dimm.idl:59
LONG lfWeight
Definition: dimm.idl:63
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
BYTE lfClipPrecision
Definition: dimm.idl:69
BYTE lfCharSet
Definition: dimm.idl:67
BYTE lfQuality
Definition: dimm.idl:70
BYTE lfPitchAndFamily
Definition: dimm.idl:71
INT cxWidth53or54
Definition: softkbd.c:151
INT cxWidth58
Definition: softkbd.c:154
INT cxWidth57
Definition: softkbd.c:153
UINT PressedKey
Definition: softkbd.c:161
INT cyHeight50
Definition: softkbd.c:156
INT cxDefWidth
Definition: softkbd.c:145
INT cyDefHeight
Definition: softkbd.c:155
INT cxWidth47
Definition: softkbd.c:146
DWORD CharSet
Definition: softkbd.c:160
INT cxWidth50
Definition: softkbd.c:149
INT cxWidth48
Definition: softkbd.c:147
INT cxWidth49
Definition: softkbd.c:148
LPARAM KeyboardSubType
Definition: softkbd.c:163
WCHAR chKeyChar[48]
Definition: softkbd.c:158
POINT pt0
Definition: softkbd.c:162
INT cxWidth51or52
Definition: softkbd.c:150
POINT pt1
Definition: softkbd.c:162
HBITMAP hbmKeyboard
Definition: softkbd.c:159
POINT KeyPos[T1K_MAX]
Definition: softkbd.c:157
INT cxWidth55or56
Definition: softkbd.c:152
LONG cx
Definition: kdterminal.h:27
LPCWSTR lpszClassName
Definition: winuser.h:3334
HBRUSH hbrBackground
Definition: winuser.h:3332
WNDPROC lpfnWndProc
Definition: winuser.h:3326
UINT cbSize
Definition: winuser.h:3324
int cbWndExtra
Definition: winuser.h:3328
HCURSOR hCursor
Definition: winuser.h:3331
HINSTANCE hInstance
Definition: winuser.h:3329
UINT style
Definition: winuser.h:3325
HICON hIcon
Definition: winuser.h:3330
DWORD fdwUICaps
Definition: immdev.h:25
DWORD fdwInit
Definition: immdev.h:125
POINT ptSoftKbdPos
Definition: immdev.h:110
BYTE lfCharSet
Definition: wingdi.h:2351
DWORD cbSize
Definition: winuser.h:3892
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
WORD wCode[2][256]
Definition: softkbd.c:27
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
const uint16_t * LPCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
HDC hdcMem
Definition: welcome.c:104
#define IS_NULL_UNEXPECTEDLY(p)
Definition: precomp.h:67
#define IDB_T1_CAPS
Definition: resource.h:4
#define IDB_C1_TAB
Definition: resource.h:12
#define IDB_T1_ALT
Definition: resource.h:9
#define IDB_T1_CTRL
Definition: resource.h:7
#define IDB_C1_ESCAPE
Definition: resource.h:18
#define IDB_C1_CHARS
Definition: resource.h:19
#define IDB_T1_TAB
Definition: resource.h:3
#define IDB_T1_ENTER
Definition: resource.h:5
#define IDB_C1_SHIFT
Definition: resource.h:15
#define IDB_C1_CAPS
Definition: resource.h:13
#define IDB_C1_DEL
Definition: resource.h:17
#define IDB_T1_SHIFT
Definition: resource.h:6
#define IDB_C1_INS
Definition: resource.h:16
#define IDB_T1_CHARS
Definition: resource.h:10
#define IDB_T1_ESCAPE
Definition: resource.h:8
#define IDB_C1_ENTER
Definition: resource.h:14
#define IDB_T1_BACKSPACE
Definition: resource.h:2
#define IDB_C1_BACKSPACE
Definition: resource.h:11
#define GHND
Definition: winbase.h:321
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
HICON HCURSOR
Definition: windef.h:99
#define WINAPI
Definition: msvc.h:6
#define FIXED_PITCH
Definition: wingdi.h:444
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
struct tagLOGFONTW * LPLOGFONTW
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define FF_MODERN
Definition: wingdi.h:449
#define OUT_TT_ONLY_PRECIS
Definition: wingdi.h:422
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
#define LTGRAY_BRUSH
Definition: wingdi.h:900
#define PATINVERT
Definition: wingdi.h:328
#define WHITENESS
Definition: wingdi.h:337
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define DEFAULT_CHARSET
Definition: wingdi.h:384
int WINAPI GetTextFaceW(_In_ HDC hdc, _In_ int c, _Out_writes_to_opt_(c, return) LPWSTR lpName)
#define SRCCOPY
Definition: wingdi.h:333
#define WHITE_BRUSH
Definition: wingdi.h:902
#define GRAY_BRUSH
Definition: wingdi.h:898
#define PATCOPY
Definition: wingdi.h:335
#define DSTINVERT
Definition: wingdi.h:327
#define CHINESEBIG5_CHARSET
Definition: wingdi.h:390
#define NULL_BRUSH
Definition: wingdi.h:901
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define ETO_OPAQUE
Definition: wingdi.h:647
#define BLACK_PEN
Definition: wingdi.h:903
#define NULL_PEN
Definition: wingdi.h:904
#define PROOF_QUALITY
Definition: wingdi.h:438
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
#define FW_NORMAL
Definition: wingdi.h:373
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917
BOOL WINAPI DeleteDC(_In_ HDC)
#define GB2312_CHARSET
Definition: wingdi.h:389
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define WM_PAINT
Definition: winuser.h:1648
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define GW_OWNER
Definition: winuser.h:777
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define SW_HIDE
Definition: winuser.h:779
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define SM_CYVIRTUALSCREEN
Definition: winuser.h:1050
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define SM_CYEDGE
Definition: winuser.h:1020
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define CS_IME
Definition: winuser.h:667
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_IME_NOTIFY
Definition: winuser.h:1858
#define SM_CXEDGE
Definition: winuser.h:1019
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CREATE
Definition: winuser.h:1636
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define DT_SINGLELINE
Definition: winuser.h:540
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3064
#define SW_SHOWNOACTIVATE
Definition: winuser.h:785
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_MOUSEMOVE
Definition: winuser.h:1803
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define IDC_SIZEALL
Definition: winuser.h:704
#define MA_NOACTIVATE
Definition: winuser.h:2539
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
BOOL WINAPI GetClassInfoExW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _Out_ LPWNDCLASSEXW)
BOOL WINAPI MessageBeep(_In_ UINT uType)
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2474
#define IDI_APPLICATION
Definition: winuser.h:712
#define WM_SHOWWINDOW
Definition: winuser.h:1656
#define SM_CXVIRTUALSCREEN
Definition: winuser.h:1049
UINT WINAPI MapVirtualKeyW(_In_ UINT, _In_ UINT)
#define SM_CYBORDER
Definition: winuser.h:976
#define DT_LEFT
Definition: winuser.h:534
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define DT_TOP
Definition: winuser.h:542
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
#define MAKELRESULT(l, h)
Definition: winuser.h:4118
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define SM_CXBORDER
Definition: winuser.h:975
BOOL WINAPI UpdateWindow(_In_ HWND)
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
HDC WINAPI GetDC(_In_opt_ HWND)
#define WM_MOUSEACTIVATE
Definition: winuser.h:1665
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
#define WM_LBUTTONUP
Definition: winuser.h:1805
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
HWND WINAPI GetParent(_In_ HWND)
#define DT_BOTTOM
Definition: winuser.h:525
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define WM_SETCURSOR
Definition: winuser.h:1664
#define WM_IME_CONTROL
Definition: winuser.h:1859
#define VK_SHIFT
Definition: winuser.h:2238
#define IDC_HAND
Definition: winuser.h:706
#define WM_DESTROY
Definition: winuser.h:1637
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define DT_RIGHT
Definition: winuser.h:538
#define SM_XVIRTUALSCREEN
Definition: winuser.h:1047
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2532
#define SWP_NOZORDER
Definition: winuser.h:1258
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define SetWindowLongPtrW
Definition: winuser.h:5512
#define POINTSTOPOINT(p, ps)
Definition: winuser.h:4119
#define BF_RECT
Definition: winuser.h:462
#define SM_CMONITORS
Definition: winuser.h:1051
BOOL WINAPI DestroyWindow(_In_ HWND)
#define EDGE_RAISED
Definition: winuser.h:450
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2444
int WINAPI GetSystemMetrics(_In_ int)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1113
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SM_YVIRTUALSCREEN
Definition: winuser.h:1048
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
unsigned char BYTE
Definition: xxhash.c:193