https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4aa1bcb72b247b41a18b971cecdcb6cc3e785d1c

commit 4aa1bcb72b247b41a18b971cecdcb6cc3e785d1c
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Sat Nov 4 05:58:17 2023 +0900
Commit:     GitHub <nore...@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...@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/ImmCreateSoftKeyboard.html
+ */
+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.html
+ */
+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/ImmDestroySoftKeyboard.html
+ */
+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);

Reply via email to