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