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);