https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4aa1bcb72b247b41a18b9…
commit 4aa1bcb72b247b41a18b971cecdcb6cc3e785d1c
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Nov 4 05:58:17 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Nov 4 05:58:17 2023 +0900
[IMM32][SDK] Implement software keyboard, Part 1 (#5865)
- Add dll/win32/imm32/softkbd.c source file.
- Half-implement ImmCreateSoftKeyboard function.
- Move ImmShowSoftKeyboard, and ImmDestroySoftKeyboard functions.
- Modify ImmCreateSoftKeyboard prototype.
CORE-19268
---
dll/win32/imm32/CMakeLists.txt | 1 +
dll/win32/imm32/imm.c | 30 -----
dll/win32/imm32/imm32.spec | 2 +-
dll/win32/imm32/softkbd.c | 298 +++++++++++++++++++++++++++++++++++++++++
sdk/include/psdk/imm.h | 19 ++-
5 files changed, 316 insertions(+), 34 deletions(-)
diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt
index ba1f56641c4..d5b2ea12af4 100644
--- a/dll/win32/imm32/CMakeLists.txt
+++ b/dll/win32/imm32/CMakeLists.txt
@@ -16,6 +16,7 @@ list(APPEND SOURCE
imm.c
keymsg.c
regword.c
+ softkbd.c
utils.c
win3.c
${CMAKE_CURRENT_BINARY_DIR}/imm32_stubs.c
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 40f686e44f0..39d4cd3b1ef 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -1103,36 +1103,6 @@ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
return TRUE; // Do nothing. This is correct.
}
-/***********************************************************************
- * ImmCreateSoftKeyboard(IMM32.@)
- */
-HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
-{
- FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * ImmDestroySoftKeyboard(IMM32.@)
- */
-BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
-{
- TRACE("(%p)\n", hSoftWnd);
- return DestroyWindow(hSoftWnd);
-}
-
-/***********************************************************************
- * ImmShowSoftKeyboard(IMM32.@)
- */
-BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
-{
- TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
- if (hSoftWnd)
- return ShowWindow(hSoftWnd, nCmdShow);
- return FALSE;
-}
-
/***********************************************************************
* ImmDisableTextFrameService(IMM32.@)
*/
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index 3a706be14b4..eee84f6487e 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -19,7 +19,7 @@
@ stdcall ImmConfigureIMEW(ptr ptr long ptr)
@ stdcall ImmCreateContext()
@ stdcall ImmCreateIMCC(long)
-@ stdcall ImmCreateSoftKeyboard(long long long long)
+@ stdcall ImmCreateSoftKeyboard(long ptr long long)
@ stdcall ImmDestroyContext(ptr)
@ stdcall ImmDestroyIMCC(ptr)
@ stdcall ImmDestroySoftKeyboard(ptr)
diff --git a/dll/win32/imm32/softkbd.c b/dll/win32/imm32/softkbd.c
new file mode 100644
index 00000000000..551331ffe40
--- /dev/null
+++ b/dll/win32/imm32/softkbd.c
@@ -0,0 +1,298 @@
+/*
+ * PROJECT: ReactOS IMM32
+ * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE: Implementing IMM Software Keyboard
+ * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ
<katayama.hirofumi.mz(a)gmail.com>
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(imm);
+
+static UINT s_uScanCode[256];
+static RECT s_rcWorkArea;
+static POINT s_ptRaiseEdge;
+static LOGFONTW s_lfSKT1Font;
+static BOOL s_bWannaInitSoftKBD = TRUE;
+
+static VOID
+Imm32GetAllMonitorSize(_Out_ LPRECT prcWork)
+{
+ if (GetSystemMetrics(SM_CMONITORS) == 1)
+ {
+ SystemParametersInfoW(SPI_GETWORKAREA, 0, prcWork, 0);
+ return;
+ }
+
+ prcWork->left = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ prcWork->top = GetSystemMetrics(SM_YVIRTUALSCREEN);
+ prcWork->right = prcWork->left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ prcWork->bottom = prcWork->top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
+}
+
+static BOOL
+Imm32GetNearestMonitorSize(
+ _In_ HWND hwnd,
+ _Out_ LPRECT prcWork)
+{
+ HMONITOR hMonitor;
+ MONITORINFO mi;
+
+ if (GetSystemMetrics(SM_CMONITORS) == 1)
+ {
+ Imm32GetAllMonitorSize(prcWork);
+ return TRUE;
+ }
+
+ hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+ if (!hMonitor)
+ return FALSE;
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfoW(hMonitor, &mi);
+
+ *prcWork = mi.rcWork;
+ return TRUE;
+}
+
+/* Software keyboard window procedure (Traditional Chinese) */
+static LRESULT CALLBACK
+SKWndProcT1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_CREATE:
+ {
+ FIXME("stub\n");
+ return -1;
+ }
+
+ default:
+ {
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+ }
+ }
+ return 0;
+}
+
+/* Software keyboard window procedure (Simplified Chinese) */
+static LRESULT CALLBACK
+SKWndProcC1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_CREATE:
+ {
+ FIXME("stub\n");
+ return -1;
+ }
+
+ default:
+ {
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+ }
+ }
+ return 0;
+}
+
+static BOOL
+Imm32RegisterSoftKeyboard(_In_ UINT uType)
+{
+ LPCWSTR pszClass;
+ WNDCLASSEXW wcx;
+
+ if (uType == 1)
+ pszClass = L"SoftKBDClsT1";
+ else if (uType == 2)
+ pszClass = L"SoftKBDClsC1";
+ else
+ return FALSE;
+
+ if (GetClassInfoExW(ghImm32Inst, pszClass, &wcx))
+ return TRUE;
+
+ ZeroMemory(&wcx, sizeof(wcx));
+ wcx.cbSize = sizeof(wcx);
+ wcx.style = CS_IME;
+ wcx.cbWndExtra = sizeof(LONG_PTR);
+ wcx.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+ wcx.hInstance = ghImm32Inst;
+ wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL);
+ wcx.lpszClassName = pszClass;
+
+ if (uType == 1)
+ {
+ wcx.lpfnWndProc = SKWndProcT1;
+ wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+ }
+ else
+ {
+ wcx.lpfnWndProc = SKWndProcC1;
+ wcx.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ }
+
+ return !!RegisterClassExW(&wcx);
+}
+
+static VOID
+Imm32GetSKT1TextMetric(_Out_ LPTEXTMETRICW lptm)
+{
+ HDC hDC;
+ HFONT hFont;
+ SIZE size;
+ HGDIOBJ hFontOld;
+ WCHAR szText[2] = { 0x894E, 0 };
+
+ hDC = GetDC(NULL);
+
+ ZeroMemory(&s_lfSKT1Font, sizeof(s_lfSKT1Font));
+ s_lfSKT1Font.lfHeight = -12;
+ s_lfSKT1Font.lfWeight = FW_NORMAL;
+ s_lfSKT1Font.lfCharSet = CHINESEBIG5_CHARSET;
+ s_lfSKT1Font.lfOutPrecision = OUT_TT_ONLY_PRECIS;
+ s_lfSKT1Font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ s_lfSKT1Font.lfQuality = PROOF_QUALITY;
+ s_lfSKT1Font.lfPitchAndFamily = 49;
+ hFont = CreateFontIndirectW(&s_lfSKT1Font);
+
+ hFontOld = SelectObject(hDC, hFont);
+
+ GetTextMetricsW(hDC, lptm);
+
+ if (GetTextExtentPoint32W(hDC, szText, 1, &size) &&
lptm->tmMaxCharWidth < size.cx )
+ lptm->tmMaxCharWidth = size.cx;
+
+ DeleteObject(SelectObject(hDC, hFontOld));
+ ReleaseDC(NULL, hDC);
+}
+
+static VOID
+Imm32GetSoftKeyboardDimension(
+ _In_ UINT uType,
+ _Out_ LPINT pcx,
+ _Out_ LPINT pcy)
+{
+ INT cxEdge, cyEdge;
+ TEXTMETRICW tm;
+
+ if (uType == 1)
+ {
+ Imm32GetSKT1TextMetric(&tm);
+ *pcx = 15 * tm.tmMaxCharWidth + 2 * s_ptRaiseEdge.x + 139;
+ *pcy = 5 * tm.tmHeight + 2 * s_ptRaiseEdge.y + 58;
+ }
+ else
+ {
+ cxEdge = GetSystemMetrics(SM_CXEDGE);
+ cyEdge = GetSystemMetrics(SM_CYEDGE);
+ *pcx = 2 * (GetSystemMetrics(SM_CXBORDER) + cxEdge) + 348;
+ *pcy = 2 * (GetSystemMetrics(SM_CYBORDER) + cyEdge) + 136;
+ }
+}
+
+/***********************************************************************
+ * ImmCreateSoftKeyboard (IMM32.@)
+ *
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmCreateSoftKeyboar…
+ */
+HWND WINAPI
+ImmCreateSoftKeyboard(
+ _In_ UINT uType,
+ _In_ HWND hwndParent,
+ _In_ INT x,
+ _In_ INT y)
+{
+ HKL hKL;
+ PIMEDPI pImeDpi;
+ DWORD dwUICaps, style = (WS_POPUP | WS_DISABLED);
+ UINT i;
+ INT xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD;
+ HWND hwndSoftKBD;
+
+ TRACE("(%u, %p, %d, %d)\n", uType, hwndParent, x, y);
+
+ if (uType != 1 && uType != 2)
+ return 0;
+
+ hKL = GetKeyboardLayout(0);
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (!pImeDpi)
+ return NULL;
+
+ dwUICaps = pImeDpi->ImeInfo.fdwUICaps;
+ ImmUnlockImeDpi(pImeDpi);
+
+ if (!(dwUICaps & UI_CAP_SOFTKBD))
+ return NULL;
+
+ if (s_bWannaInitSoftKBD)
+ {
+ if (!Imm32GetNearestMonitorSize(hwndParent, &s_rcWorkArea))
+ return NULL;
+
+ for (i = 0; i < 0xFF; ++i)
+ s_uScanCode[i] = MapVirtualKeyW(i, 0);
+
+ s_ptRaiseEdge.x = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE);
+ s_ptRaiseEdge.y = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE);
+
+ s_bWannaInitSoftKBD = FALSE;
+ }
+
+ if (!Imm32RegisterSoftKeyboard(uType))
+ return NULL;
+
+ Imm32GetSoftKeyboardDimension(uType, &cxSoftKBD, &cySoftKBD);
+
+ xSoftKBD = max(s_rcWorkArea.left, min(x, s_rcWorkArea.right - cxSoftKBD));
+ ySoftKBD = max(s_rcWorkArea.top, min(y, s_rcWorkArea.bottom - cySoftKBD));
+
+ if (uType == 1) /* Traditional Chinese */
+ {
+ hwndSoftKBD = CreateWindowExW(0,
+ L"SoftKBDClsT1", NULL, style,
+ xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD,
+ hwndParent, NULL, ghImm32Inst, NULL);
+ }
+ else /* Simplified Chinese (uType == 2) */
+ {
+ style |= WS_BORDER;
+ hwndSoftKBD = CreateWindowExW(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME,
+ L"SoftKBDClsC1", NULL, style,
+ xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD,
+ hwndParent, NULL, ghImm32Inst, NULL);
+ }
+
+ ShowWindow(hwndSoftKBD, SW_HIDE);
+ UpdateWindow(hwndSoftKBD);
+
+ return hwndSoftKBD;
+}
+
+/***********************************************************************
+ * ImmShowSoftKeyboard (IMM32.@)
+ *
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmShowSoftKeyboard.…
+ */
+BOOL WINAPI
+ImmShowSoftKeyboard(
+ _In_ HWND hwndSoftKBD,
+ _In_ INT nCmdShow)
+{
+ TRACE("(%p, %d)\n", hwndSoftKBD, nCmdShow);
+ return hwndSoftKBD && ShowWindow(hwndSoftKBD, nCmdShow);
+}
+
+/***********************************************************************
+ * ImmDestroySoftKeyboard (IMM32.@)
+ *
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImmDestroySoftKeyboa…
+ */
+BOOL WINAPI
+ImmDestroySoftKeyboard(
+ _In_ HWND hwndSoftKBD)
+{
+ TRACE("(%p)\n", hwndSoftKBD);
+ return DestroyWindow(hwndSoftKBD);
+}
diff --git a/sdk/include/psdk/imm.h b/sdk/include/psdk/imm.h
index 95ac099d2e3..9ec9e3cfb18 100644
--- a/sdk/include/psdk/imm.h
+++ b/sdk/include/psdk/imm.h
@@ -253,9 +253,22 @@ LRESULT WINAPI ImmRequestMessageA(HIMC, WPARAM, LPARAM);
LRESULT WINAPI ImmRequestMessageW(HIMC, WPARAM, LPARAM);
#define ImmRequestMessage WINELIB_NAME_AW(ImmRequestMessage);
BOOL WINAPI ImmTranslateMessage(HWND, UINT, WPARAM, LPARAM);
-HWND WINAPI ImmCreateSoftKeyboard(UINT, UINT, int, int);
-BOOL WINAPI ImmDestroySoftKeyboard(HWND);
-BOOL WINAPI ImmShowSoftKeyboard(HWND, int);
+
+HWND WINAPI
+ImmCreateSoftKeyboard(
+ _In_ UINT uType,
+ _In_ HWND hwndParent,
+ _In_ INT x,
+ _In_ INT y);
+
+BOOL WINAPI
+ImmShowSoftKeyboard(
+ _In_ HWND hwndSoftKBD,
+ _In_ INT nCmdShow);
+
+BOOL WINAPI
+ImmDestroySoftKeyboard(
+ _In_ HWND hwndSoftKBD);
BOOL WINAPI ImeInquire(LPIMEINFO, LPWSTR, LPCWSTR lpszOptions);
BOOL WINAPI ImeConfigure (HKL, HWND, DWORD, LPVOID);