https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6783061894743604dd0578...
commit 6783061894743604dd057858f5ae3b1d38f238f7 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sat Nov 25 18:56:33 2023 +0900 Commit: GitHub noreply@github.com CommitDate: Sat Nov 25 18:56:33 2023 +0900
[IMM32] Implement Soft Keyboard Type C1 (#6036)
Follow-up to #6021. This PR will finish ImmCreateSoftKeyboard implementation.
- Add c1key.h to define C1 internal codes. - The tests are done, using FreeCJ2004 on Chinese/Taiwanese system.
FreeCJ2004: https://web.archive.org/web/20061208204431/http://input.foruto.com/download/...
CORE-19268 --- dll/win32/imm32/c1keys.h | 64 +++ dll/win32/imm32/softkbd.c | 1029 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 1027 insertions(+), 66 deletions(-)
diff --git a/dll/win32/imm32/c1keys.h b/dll/win32/imm32/c1keys.h new file mode 100644 index 00000000000..34f1ea3049e --- /dev/null +++ b/dll/win32/imm32/c1keys.h @@ -0,0 +1,64 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Defining internal codes (C1K_...) of IME Soft Keyboard Type C1 + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ + +/* DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) */ +DEFINE_C1K( 0, 0xC0, C1K_OEM_3, VK_OEM_3, FALSE) +DEFINE_C1K( 1, 0x31, C1K_1, VK_1, FALSE) +DEFINE_C1K( 2, 0x32, C1K_2, VK_2, FALSE) +DEFINE_C1K( 3, 0x33, C1K_3, VK_3, FALSE) +DEFINE_C1K( 4, 0x34, C1K_4, VK_4, FALSE) +DEFINE_C1K( 5, 0x35, C1K_5, VK_5, FALSE) +DEFINE_C1K( 6, 0x36, C1K_6, VK_6, FALSE) +DEFINE_C1K( 7, 0x37, C1K_7, VK_7, FALSE) +DEFINE_C1K( 8, 0x38, C1K_8, VK_8, FALSE) +DEFINE_C1K( 9, 0x39, C1K_9, VK_9, FALSE) +DEFINE_C1K(10, 0x30, C1K_0, VK_0, FALSE) +DEFINE_C1K(11, 0xBD, C1K_OEM_MINUS, VK_OEM_MINUS, FALSE) +DEFINE_C1K(12, 0xBB, C1K_OEM_PLUS, VK_OEM_PLUS, FALSE) +DEFINE_C1K(13, 0x51, C1K_Q, VK_Q, FALSE) +DEFINE_C1K(14, 0x57, C1K_W, VK_W, FALSE) +DEFINE_C1K(15, 0x45, C1K_E, VK_E, FALSE) +DEFINE_C1K(16, 0x52, C1K_R, VK_R, FALSE) +DEFINE_C1K(17, 0x54, C1K_T, VK_T, FALSE) +DEFINE_C1K(18, 0x59, C1K_Y, VK_Y, FALSE) +DEFINE_C1K(19, 0x55, C1K_U, VK_U, FALSE) +DEFINE_C1K(20, 0x49, C1K_I, VK_I, FALSE) +DEFINE_C1K(21, 0x4F, C1K_O, VK_O, FALSE) +DEFINE_C1K(22, 0x50, C1K_P, VK_P, FALSE) +DEFINE_C1K(23, 0xDB, C1K_OEM_4, VK_OEM_4, FALSE) +DEFINE_C1K(24, 0xDD, C1K_OEM_6, VK_OEM_6, FALSE) +DEFINE_C1K(25, 0xDC, C1K_OEM_5, VK_OEM_5, FALSE) +DEFINE_C1K(26, 0x41, C1K_A, VK_A, FALSE) +DEFINE_C1K(27, 0x53, C1K_S, VK_S, FALSE) +DEFINE_C1K(28, 0x44, C1K_D, VK_D, FALSE) +DEFINE_C1K(29, 0x46, C1K_F, VK_F, FALSE) +DEFINE_C1K(30, 0x47, C1K_G, VK_G, FALSE) +DEFINE_C1K(31, 0x48, C1K_H, VK_H, FALSE) +DEFINE_C1K(32, 0x4A, C1K_J, VK_J, FALSE) +DEFINE_C1K(33, 0x4B, C1K_K, VK_K, FALSE) +DEFINE_C1K(34, 0x4C, C1K_L, VK_L, FALSE) +DEFINE_C1K(35, 0xBA, C1K_OEM_1, VK_OEM_1, FALSE) +DEFINE_C1K(36, 0xDE, C1K_OEM_7, VK_OEM_7, FALSE) +DEFINE_C1K(37, 0x5A, C1K_Z, VK_Z, FALSE) +DEFINE_C1K(38, 0x58, C1K_X, VK_X, FALSE) +DEFINE_C1K(39, 0x43, C1K_C, VK_C, FALSE) +DEFINE_C1K(40, 0x56, C1K_V, VK_V, FALSE) +DEFINE_C1K(41, 0x42, C1K_B, VK_B, FALSE) +DEFINE_C1K(42, 0x4E, C1K_N, VK_N, FALSE) +DEFINE_C1K(43, 0x4D, C1K_M, VK_M, FALSE) +DEFINE_C1K(44, 0xBC, C1K_OEM_COMMA, VK_OEM_COMMA, FALSE) +DEFINE_C1K(45, 0xBE, C1K_OEM_DOT, VK_OEM_PERIOD, FALSE) +DEFINE_C1K(46, 0xBF, C1K_OEM_2, VK_OEM_2, FALSE) +DEFINE_C1K(47, 0x08, C1K_BACKSPACE, VK_BACK, TRUE) +DEFINE_C1K(48, 0x09, C1K_TAB, VK_TAB, TRUE) +DEFINE_C1K(49, 0x14, C1K_CAPS, VK_CAPITAL, TRUE) +DEFINE_C1K(50, 0x0D, C1K_ENTER, VK_RETURN, TRUE) +DEFINE_C1K(51, 0x10, C1K_SHIFT, VK_SHIFT, TRUE) +DEFINE_C1K(52, 0x2D, C1K_INSERT, VK_INSERT, TRUE) +DEFINE_C1K(53, 0x2E, C1K_DELETE, VK_DELETE, TRUE) +DEFINE_C1K(54, 0x20, C1K_SPACE, VK_SPACE, TRUE) +DEFINE_C1K(55, 0x1B, C1K_ESCAPE, VK_ESCAPE, TRUE) diff --git a/dll/win32/imm32/softkbd.c b/dll/win32/imm32/softkbd.c index 8cf17248760..522ff99185c 100644 --- a/dll/win32/imm32/softkbd.c +++ b/dll/win32/imm32/softkbd.c @@ -32,6 +32,23 @@ Imm32PtInRect( return (x <= ppt->x) && (ppt->x < x + cx) && (y <= ppt->y) && (ppt->y < y + cy); }
+static void +Imm32DrawBitmap( + _In_ HDC hdc, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height, + _In_ INT nBitmapID) +{ + HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); + HDC hMemDC = CreateCompatibleDC(hdc); + HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap); + BitBlt(hdc, x, y, width, height, hMemDC, 0, 0, SRCCOPY); + DeleteObject(SelectObject(hMemDC, hbmOld)); + DeleteDC(hMemDC); +} + static inline INT Imm32Clamp( _In_ INT x, @@ -320,24 +337,6 @@ T1_DrawConvexRect( PatBlt(hDC, x0 + dx - 1, y + dy - 3, -1, 2 - dy, PATCOPY); }
-static void -T1_DrawBitmap( - _In_ HDC hDC, - _In_ INT x, - _In_ INT y, - _In_ INT cx, - _In_ INT cy, - _In_ INT nBitmapID) -{ - HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); - HDC hMemDC = CreateCompatibleDC(hDC); - HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap); - BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY); - SelectObject(hMemDC, hbmOld); - DeleteObject(hBitmap); - DeleteDC(hMemDC); -} - static void T1_DrawLabels( _In_ HDC hDC, @@ -386,46 +385,46 @@ T1_InitBitmap( T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4, - 16, 9, IDB_T1_CTRL); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4, + 16, 9, IDB_T1_CTRL);
/* 54 --> Right [Ctrl] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4, - 16, 9, IDB_T1_CTRL); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4, + 16, 9, IDB_T1_CTRL);
/* 57 --> [Esc] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y, pT1->cxWidth57, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4, - 18, 9, IDB_T1_ESCAPE); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4, + 18, 9, IDB_T1_ESCAPE);
/* 55 --> Left [Alt] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4, - 16, 9, IDB_T1_ALT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4, + 16, 9, IDB_T1_ALT);
/* 56 --> Right [Alt] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4, - 16, 9, IDB_T1_ALT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4, + 16, 9, IDB_T1_ALT);
/* 58 --> [Space] */ T1_DrawConvexRect(hMemDC, @@ -436,55 +435,55 @@ T1_InitBitmap( T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4, - 23, 9, IDB_T1_SHIFT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT);
/* 52 --> Right [Shift] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4, - 23, 9, IDB_T1_SHIFT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT);
/* 49 --> [Caps] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y, pT1->cxWidth49, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4, - 22, 9, IDB_T1_CAPS); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4, + 22, 9, IDB_T1_CAPS);
/* 48 --> [Tab] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y, pT1->cxWidth48, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4, - 16, 9, IDB_T1_TAB); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4, + 16, 9, IDB_T1_TAB);
/* 50 --> [Enter] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y, pT1->cxWidth50, pT1->cyHeight50); - T1_DrawBitmap(hMemDC, - pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13, - pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4, - 26, 9, IDB_T1_ENTER); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13, + pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4, + 26, 9, IDB_T1_ENTER);
/* 47 --> [BackSpace] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y, pT1->cxWidth47, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4, - 16, 9, IDB_T1_BACKSPACE); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4, + 16, 9, IDB_T1_BACKSPACE);
/* Regular keys */ for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) @@ -842,7 +841,7 @@ T1_OnButtonUp( iPressed = pT1->PressedKey; if (iPressed >= T1K_NONE) { - if (pT1->pt1.x != -1 && pT1->pt1.y != -1 ) + if (pT1->pt1.x != -1 && pT1->pt1.y != -1) { T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); x = pT1->pt0.x - pT1->pt1.x; @@ -1123,6 +1122,865 @@ T1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define C1_CLASSNAMEW L"SoftKBDClsC1"
+#define C1K_MAX 56 + +#undef DEFINE_C1K +#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \ + c1k_code_name = c1k_code, + +/* Define C1 internal codes (C1K_...) */ +typedef enum C1KEY +{ +#include "c1keys.h" +} C1KEY; + +#undef DEFINE_C1K +#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \ + virtual_key_code, + +/* Mapping: C1K --> Virtual Key */ +const BYTE gC1K2VK[C1K_MAX] = +{ +#include "c1keys.h" +}; + +typedef struct C1WINDOW +{ + WCHAR Data[2][47]; + DWORD dwFlags; + HBITMAP hbmKeyboard; + LPARAM SubType; + INT iPressedKey; + POINT pt1, pt2; + DWORD CharSet; +} C1WINDOW, *PC1WINDOW; + +/* The flags for C1WINDOW.dwFlags */ +#define FLAG_SHIFT_PRESSED 1 +#define FLAG_DRAGGING 2 +#define FLAG_PRESSED 4 + +static BOOL gbC1ButtonInit = FALSE; +static POINT gptC1ButtonPos[C1K_MAX]; + +static void C1_InitButtonPos(void) +{ + LONG x = 0, y = 0; + INT iKey; + + /* 1st row */ + for (iKey = C1K_OEM_3; iKey < C1K_Q; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + gptC1ButtonPos[C1K_BACKSPACE].x = x; + gptC1ButtonPos[C1K_BACKSPACE].y = y; + + /* 2nd row */ + y = 28; + gptC1ButtonPos[C1K_TAB].x = 0; + gptC1ButtonPos[C1K_TAB].y = y; + x = 36; + for (; iKey < C1K_A; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + + /* 3rd row */ + y = 56; + gptC1ButtonPos[C1K_CAPS].x = 0; + gptC1ButtonPos[C1K_CAPS].y = y; + x = 42; + for (; iKey < C1K_Z; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + gptC1ButtonPos[C1K_ENTER].x = x; + gptC1ButtonPos[C1K_ENTER].y = y; + + /* 4th row */ + y = 84; + gptC1ButtonPos[C1K_SHIFT].x = 0; + gptC1ButtonPos[C1K_SHIFT].y = y; + x = 60; + for (; iKey < C1K_BACKSPACE; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + + /* 5th row */ + y = 112; + gptC1ButtonPos[C1K_INSERT].x = 0; + gptC1ButtonPos[C1K_INSERT].y = y; + gptC1ButtonPos[C1K_DELETE].x = 58; + gptC1ButtonPos[C1K_DELETE].y = y; + gptC1ButtonPos[C1K_SPACE].x = 96; + gptC1ButtonPos[C1K_SPACE].y = y; + gptC1ButtonPos[C1K_ESCAPE].x = 310; + gptC1ButtonPos[C1K_ESCAPE].y = y; +} + +static void +C1_DrawConvexRect( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height) +{ + HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH); + HGDIOBJ hBlackPen = GetStockObject(BLACK_PEN); + HGDIOBJ hWhiteBrush = GetStockObject(WHITE_BRUSH); + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + INT y2 = y + height - 1; + + /* Draw face */ + SelectObject(hDC, hLtGrayBrush); + SelectObject(hDC, hBlackPen); + Rectangle(hDC, x, y, x + width, y + height); + + /* Draw light edge */ + SelectObject(hDC, hWhiteBrush); + PatBlt(hDC, x, y2, 2, 1 - height, PATCOPY); + PatBlt(hDC, x, y, width - 1, 2, PATCOPY); + + /* Draw dark edge */ + SelectObject(hDC, hGrayBrush); + PatBlt(hDC, x + 1, y2, width - 2, -1, PATCOPY); + PatBlt(hDC, x + width - 1, y2, -1, 2 - height, PATCOPY); +} + +static void +C1_InvertButton( + _In_ HDC hDC, + _In_ INT iKey) +{ + INT width = 24, height = 28; + + if (iKey < 0) + return; + + switch (iKey) + { + case C1K_BACKSPACE: case C1K_TAB: + width = 36; + break; + case C1K_CAPS: case C1K_ENTER: + width = 42; + break; + case C1K_SHIFT: + width = 60; + break; + case C1K_INSERT: case C1K_DELETE: case C1K_ESCAPE: + width = 38; + height = 24; + break; + case C1K_SPACE: + width = 172; + height = 24; + break; + default: + break; + } + + BitBlt(hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, width, height, + hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, DSTINVERT); +} + +static void +C1_DrawLabel( + _In_ HDC hDC, + _In_ INT nBitmapID) +{ + HBITMAP hBitmap; + HGDIOBJ hbmOld; + HDC hMemDC; + INT iKey; + + hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, hBitmap); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + BitBlt(hDC, gptC1ButtonPos[iKey].x + 2, gptC1ButtonPos[iKey].y + 2, 8, 8, + hMemDC, iKey * 8, 0, SRCCOPY); + } + DeleteObject(SelectObject(hMemDC, hbmOld)); + DeleteDC(hMemDC); +} + +static void +C1_InitBitmap( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height) +{ + HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH); + HGDIOBJ hNullPen = GetStockObject(NULL_PEN); + INT iKey; + + /* Draw keyboard frame */ + SelectObject(hDC, hLtGrayBrush); + SelectObject(hDC, hNullPen); + Rectangle(hDC, x, y, width + 1, height + 1); + + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + C1_DrawConvexRect(hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28); + } + + C1_DrawLabel(hDC, IDB_C1_CHARS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_BACKSPACE].x + 2, gptC1ButtonPos[C1K_BACKSPACE].y + 2, 32, 24, IDB_C1_BACKSPACE); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_TAB].x + 2, gptC1ButtonPos[C1K_TAB].y + 2, 32, 24, IDB_C1_TAB); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_CAPS].x + 2, gptC1ButtonPos[C1K_CAPS].y + 2, 38, 24, IDB_C1_CAPS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ENTER].x + 2, gptC1ButtonPos[C1K_ENTER].y + 2, 38, 24, IDB_C1_ENTER); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_SHIFT].x + 2, gptC1ButtonPos[C1K_SHIFT].y + 2, 56, 24, IDB_C1_SHIFT); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_INSERT].x + 2, gptC1ButtonPos[C1K_INSERT].y + 2, 34, 20, IDB_C1_INS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_DELETE].x + 2, gptC1ButtonPos[C1K_DELETE].y + 2, 34, 20, IDB_C1_DEL); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y , 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ESCAPE].x + 2, gptC1ButtonPos[C1K_ESCAPE].y + 2, 34, 20, IDB_C1_ESCAPE); +} + +static INT +C1_OnCreate( + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hDC, hMemDC; + RECT rc; + HGDIOBJ hbmOld; + HBITMAP hbmKeyboard; + + hGlobal = GlobalAlloc(GHND, sizeof(C1WINDOW)); + if (!hGlobal) + return -1; + + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!pC1) + { + GlobalFree(hGlobal); + return -1; + } + SetWindowLongPtrW(hWnd, 0, (LONG_PTR)hGlobal); + + if (!gbC1ButtonInit) + { + C1_InitButtonPos(); + gbC1ButtonInit = TRUE; + } + + pC1->iPressedKey = -1; + pC1->CharSet = GB2312_CHARSET; + + GetClientRect(hWnd, &rc); + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmKeyboard = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top); + ReleaseDC(hWnd, hDC); + + hbmOld = SelectObject(hMemDC, hbmKeyboard); + C1_InitBitmap(hMemDC, rc.left, rc.top, rc.right, rc.bottom); + SelectObject(hMemDC, hbmOld); + pC1->hbmKeyboard = hbmKeyboard; + DeleteDC(hMemDC); + + GlobalUnlock(hGlobal); + return 0; +} + +static void +C1_OnDraw( + _In_ HDC hDC, + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hMemDC; + RECT rc; + HGDIOBJ hbmOld; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return; + + GetClientRect(hWnd, &rc); + + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + + GlobalUnlock(hGlobal); +} + +static BOOL +C1_SetData( + _In_ HWND hWnd, + _In_ const SOFTKBDDATA *pData) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hDC, hMemDC; + INT iKey; + BOOL bDisabled; + HBITMAP hbmKeyboard; + HGDIOBJ hbmOld, hFontOld; + HFONT hFont; + RECT rc; + LOGFONTW lf; + + if (pData->uCount != 2) + return 0; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + + hbmKeyboard = pC1->hbmKeyboard; + hbmOld = SelectObject(hMemDC, hbmKeyboard); + + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); + lf.lfHeight = -12; + if (pC1->CharSet != DEFAULT_CHARSET) + lf.lfCharSet = (BYTE)pC1->CharSet; + + hFont = CreateFontIndirectW(&lf); + hFontOld = SelectObject(hMemDC, hFont); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + pC1->Data[1][iKey] = pData->wCode[0][(BYTE)gC1K2VK[iKey]]; + pC1->Data[0][iKey] = pData->wCode[1][(BYTE)gC1K2VK[iKey]]; + } + + SetBkColor(hMemDC, RGB(191, 191, 191)); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + /* Upper right */ + rc.right = gptC1ButtonPos[iKey].x + 24 - 2; + rc.top = gptC1ButtonPos[iKey].y + 2; + rc.left = rc.right - 14; + rc.bottom = rc.top + 14; + bDisabled = (pC1->Data[0][iKey] == 0); + DrawTextW(hMemDC, &pC1->Data[0][iKey], !bDisabled, &rc, + DT_RIGHT | DT_TOP | DT_SINGLELINE); + + /* Lower left */ + rc.left = gptC1ButtonPos[iKey].x + 2; + rc.bottom = gptC1ButtonPos[iKey].y + 28 - 2; + rc.right = rc.left + 14; + rc.top = rc.bottom - 14; + bDisabled = (pC1->Data[1][iKey] == 0); + DrawTextW(hMemDC, &pC1->Data[1][iKey], !bDisabled, &rc, + DT_LEFT | DT_BOTTOM | DT_SINGLELINE); + } + + if (pC1->dwFlags & FLAG_SHIFT_PRESSED) + C1_InvertButton(hMemDC, C1K_SHIFT); + + pC1->dwFlags = 0; + + SelectObject(hMemDC, hbmOld); + DeleteObject(SelectObject(hMemDC, hFontOld)); + + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + + GlobalUnlock(hGlobal); + return TRUE; +} + +static void +C1_DrawDragBorder( + _In_ HWND hWnd, + _In_ LPPOINT ppt1, + _Inout_ LPPOINT ppt2) +{ + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + INT x, y; + RECT rc, rcWork; + INT cxBorder = GetSystemMetrics(SM_CXBORDER), cyBorder = GetSystemMetrics(SM_CYBORDER); + HDC hDisplayDC; + + Imm32GetAllMonitorSize(&rcWork); + hDisplayDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL); + + SelectObject(hDisplayDC, hGrayBrush); + x = ppt1->x - ppt2->x; + y = ppt1->y - ppt2->y; + if (x < rcWork.left) + x = rcWork.left; + if (y < rcWork.top) + y = rcWork.top; + + GetWindowRect(hWnd, &rc); + + if (rc.right - rc.left + x > rcWork.right) + x = rc.left + rcWork.right - rc.right; + if (y + rc.bottom - rc.top > rcWork.bottom) + y = rc.top + rcWork.bottom - rc.bottom; + + ppt2->x = ppt1->x - x; + ppt2->y = ppt1->y - y; + + PatBlt(hDisplayDC, x, y, rc.right - rc.left - cxBorder, cyBorder, PATINVERT); + PatBlt(hDisplayDC, x, y + cyBorder, cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + cxBorder, y + rc.bottom - rc.top, rc.right - rc.left - cxBorder, -cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + rc.right - rc.left, y, -cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + + DeleteDC(hDisplayDC); +} + +static INT +C1_HitTest( + _In_ const POINT *ppt) +{ + INT iKey; + + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + if (Imm32PtInRect(ppt, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28)) + return iKey; + } + + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28)) + return C1K_BACKSPACE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28)) + return C1K_TAB; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28)) + return C1K_CAPS; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28)) + return C1K_ENTER; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28)) + return C1K_SHIFT; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y, 38, 24)) + return C1K_ESCAPE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24)) + return C1K_SPACE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24)) + return C1K_INSERT; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24)) + return C1K_DELETE; + + return -1; +} + +static void +C1_OnButtonDown( + _In_ HWND hWnd, + _Inout_ PC1WINDOW pC1) +{ + INT iPressedKey; + HDC hMemDC; + WCHAR wch = 0xFF; + HGDIOBJ hbmOld; + HDC hDC; + + SetCapture(hWnd); + + iPressedKey = pC1->iPressedKey; + if (iPressedKey == -1) + { + pC1->dwFlags |= FLAG_DRAGGING; + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + return; + } + + if (iPressedKey < C1K_BACKSPACE) + { + wch = pC1->Data[!(pC1->dwFlags & 1)][iPressedKey]; + if (!wch) + { + MessageBeep(0xFFFFFFFF); + pC1->iPressedKey = -1; + return; + } + } + + if ((iPressedKey != C1K_SHIFT) || !(pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + C1_InvertButton(hDC, pC1->iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + } + + pC1->dwFlags |= FLAG_PRESSED; +} + +static BOOL +C1_OnSetCursor( + _In_ HWND hWnd, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HCURSOR hCursor; + INT iKey; + POINT pt1, pt2; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + if (pC1->dwFlags & FLAG_DRAGGING) + { + hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL); + SetCursor(hCursor); + GlobalUnlock(hGlobal); + return TRUE; + } + + GetCursorPos(&pt1); + pt2 = pt1; + ScreenToClient(hWnd, &pt2); + + iKey = C1_HitTest(&pt2); + if (iKey == -1) + hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL); + else + hCursor = LoadCursorW(0, (LPCWSTR)IDC_HAND); + SetCursor(hCursor); + + if (HIWORD(lParam) == WM_LBUTTONDOWN) + { + pC1->pt1 = pt1; + pC1->pt2 = pt2; + pC1->iPressedKey = iKey; + C1_OnButtonDown(hWnd, pC1); + } + + GlobalUnlock(hGlobal); + return TRUE; +} + +static BOOL +C1_OnMouseMove( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hMemDC; + DWORD dwFlags; + INT iPressedKey; + POINT pt; + HGDIOBJ hbmOld; + HDC hDC; + INT iKey; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + if (pC1->dwFlags & FLAG_DRAGGING) + { + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + GetCursorPos(&pC1->pt1); + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + GlobalUnlock(hGlobal); + return TRUE; + } + + if (pC1->iPressedKey != -1) + { + GetCursorPos(&pt); + ScreenToClient(hWnd, &pt); + iKey = C1_HitTest(&pt); + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + dwFlags = pC1->dwFlags; + + iPressedKey = pC1->iPressedKey; + if (!!(dwFlags & FLAG_PRESSED) == (iKey != iPressedKey)) + { + if (iPressedKey != C1K_SHIFT || !(dwFlags & FLAG_SHIFT_PRESSED)) + { + C1_InvertButton(hDC, iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + } + + pC1->dwFlags ^= FLAG_PRESSED; + } + + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + } + + GlobalUnlock(hGlobal); + return TRUE; +} + +static BOOL +C1_OnButtonUp( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + BOOL ret = FALSE; + INT x, y, iKey; + HDC hDC, hMemDC; + HGDIOBJ hbmOld; + HIMC hIMC; + HWND hwndOwner; + LPINPUTCONTEXT pIC; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + ReleaseCapture(); + + if (pC1->dwFlags & FLAG_DRAGGING) + { + pC1->dwFlags &= ~FLAG_DRAGGING; + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + x = pC1->pt1.x - pC1->pt2.x; + y = pC1->pt1.y - pC1->pt2.y; + SetWindowPos(hWnd, 0, x, y, 0, 0, 0x15u); + ret = TRUE; + + hwndOwner = GetWindow(hWnd, GW_OWNER); + hIMC = (HIMC)GetWindowLongPtrW(hwndOwner, 0); + if (hIMC) + { + pIC = ImmLockIMC(hIMC); + if (pIC) + { + pIC->fdwInit |= INIT_SOFTKBDPOS; + pIC->ptSoftKbdPos.x = x; + pIC->ptSoftKbdPos.y = y; + ImmUnlockIMC(hIMC); + } + } + + GlobalUnlock(hGlobal); + return ret; + } + + iKey = pC1->iPressedKey; + if (iKey == -1) + return FALSE; + + if (!(pC1->dwFlags & FLAG_PRESSED)) + { + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; + } + + if (iKey == C1K_SHIFT) + { + if (!(pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + pC1->dwFlags |= FLAG_SHIFT_PRESSED; + pC1->dwFlags &= ~FLAG_PRESSED; + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; + } + } + else if (iKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + INT iVK = gC1K2VK[pC1->iPressedKey]; + keybd_event(VK_SHIFT, guScanCode[C1K_SHIFT], 0, 0); + keybd_event(iVK, guScanCode[(BYTE)iVK], 0, 0); + keybd_event(iVK, guScanCode[(BYTE)iVK], KEYEVENTF_KEYUP, 0); + keybd_event(VK_SHIFT, guScanCode[C1K_SHIFT], KEYEVENTF_KEYUP, 0); + } + else + { + INT iVK = gC1K2VK[iKey]; + keybd_event(iVK, guScanCode[iVK], 0, 0); + keybd_event(iVK, guScanCode[iVK], KEYEVENTF_KEYUP, 0); + } + + ret = TRUE; + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + + C1_InvertButton(hDC, pC1->iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + + if (pC1->iPressedKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + C1_InvertButton(hDC, C1K_SHIFT); + C1_InvertButton(hMemDC, C1K_SHIFT); + } + + if (pC1->iPressedKey < C1K_BACKSPACE || pC1->iPressedKey == C1K_SHIFT) + pC1->dwFlags &= ~FLAG_SHIFT_PRESSED; + + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + + pC1->dwFlags &= ~FLAG_PRESSED; + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; +} + +static void +C1_OnDestroy( + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HWND hwndOwner; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return; + + if (pC1->dwFlags & FLAG_DRAGGING) + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + + DeleteObject(pC1->hbmKeyboard); + GlobalUnlock(hGlobal); + GlobalFree(hGlobal); + + hwndOwner = GetWindow(hWnd, GW_OWNER); + if (hwndOwner) + SendMessageW(hwndOwner, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0); +} + +static LRESULT +C1_OnImeControl( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + LOGFONTW lf; + RECT rc; + LRESULT ret = 0; + HDC hDC; + + switch (wParam) + { + case IMC_GETSOFTKBDFONT: + { + TRACE("IMC_GETSOFTKBDFONT: %p\n", lParam); + hDC = GetDC(hWnd); + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONTW), &lf); + ReleaseDC(hWnd, hDC); + *(LPLOGFONTW)lParam = lf; + break; + } + case IMC_SETSOFTKBDFONT: + { + LPLOGFONTW plf = (LPLOGFONTW)lParam; + LOGFONTW lf; + TRACE("IMC_SETSOFTKBDFONT: %p\n", lParam); + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONTW), &lf); + if (lf.lfCharSet == plf->lfCharSet) + return 0; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return 1; + + pC1->CharSet = plf->lfCharSet; + GlobalUnlock(hGlobal); + break; + } + case IMC_GETSOFTKBDPOS: + { + TRACE("IMC_GETSOFTKBDPOS\n"); + GetWindowRect(hWnd, &rc); + return MAKELRESULT(rc.left, rc.top); + } + case IMC_SETSOFTKBDPOS: + { + POINT pt; + POINTSTOPOINT(pt, lParam); + TRACE("IMC_SETSOFTKBDPOS: %d, %d\n", pt.x, pt.y); + SetWindowPos(hWnd, NULL, pt.x, pt.y, 0, 0, + (SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE)); + break; + } + case IMC_GETSOFTKBDSUBTYPE: + case IMC_SETSOFTKBDSUBTYPE: + { + TRACE("IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE: %p, %p\n", wParam, lParam); + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return -1; + ret = pC1->SubType; + if (wParam == IMC_SETSOFTKBDSUBTYPE) + pC1->SubType = lParam; + GlobalUnlock(hGlobal); + break; + } + case IMC_SETSOFTKBDDATA: + { + TRACE("IMC_SETSOFTKBDDATA: %p\n", lParam); + if (C1_SetData(hWnd, (SOFTKBDDATA*)lParam)) + return -1; + + InvalidateRect(hWnd, 0, 0); + } + default: + break; + } + + return ret; +} + static LRESULT CALLBACK C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -1130,10 +1988,47 @@ C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_CREATE: { - FIXME("stub\n"); - return -1; + return C1_OnCreate(hWnd); + } + case WM_DESTROY: + { + C1_OnDestroy(hWnd); + break; + } + case WM_SETCURSOR: + { + if (C1_OnSetCursor(hWnd, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_MOUSEMOVE: + { + if (C1_OnMouseMove(hWnd, wParam, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_LBUTTONUP: + { + if (C1_OnButtonUp(hWnd, wParam, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + C1_OnDraw(hDC, hWnd); + EndPaint(hWnd, &ps); + break; + } + case WM_IME_CONTROL: + { + return C1_OnImeControl(hWnd, wParam, lParam); + } + case WM_MOUSEACTIVATE: + { + return MA_NOACTIVATE; } - default: { return DefWindowProcW(hWnd, uMsg, wParam, lParam); @@ -1218,6 +2113,8 @@ ImmCreateSoftKeyboard( LPCWSTR pszClass; RECT rcWorkArea;
+ TRACE("(%u, %p, %d, %d)\n", uType, hwndParent, x, y); + if ((uType != SOFTKEYBOARD_TYPE_T1) && (uType != SOFTKEYBOARD_TYPE_C1)) { ERR("uType: %u\n", uType);