https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a55345be298e4f7ab452109c77bf8b97e9e3ad18
commit a55345be298e4f7ab452109c77bf8b97e9e3ad18 Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Wed Feb 21 10:36:32 2024 +0900 Commit: GitHub <nore...@github.com> CommitDate: Wed Feb 21 10:36:32 2024 +0900 [MSCTFIME][CICERO] Implement CDefCompFrameWindow (#6512) Supporting TIPs... JIRA issue: CORE-19360 - Add delay link to uxtheme.dll. - Implement CDefCompFrameGripper, CCompFinalizeButton, CCompButtonFrameWindow, and CDefCompFrameWindow classes. --- dll/ime/msctfime/CMakeLists.txt | 2 +- dll/ime/msctfime/msctfime.h | 1 + dll/ime/msctfime/ui.cpp | 322 ++++++++++++++++++++++++++++++++++++++++ dll/ime/msctfime/ui.h | 95 ++++++++++++ sdk/lib/cicero/cicuif.cpp | 8 +- sdk/lib/cicero/cicuif.h | 4 +- 6 files changed, 425 insertions(+), 7 deletions(-) diff --git a/dll/ime/msctfime/CMakeLists.txt b/dll/ime/msctfime/CMakeLists.txt index 288c14afc7f..3a48a7cbabb 100644 --- a/dll/ime/msctfime/CMakeLists.txt +++ b/dll/ime/msctfime/CMakeLists.txt @@ -26,5 +26,5 @@ set_module_type(msctfime win32dll UNICODE) set_target_properties(msctfime PROPERTIES SUFFIX ".ime") target_link_libraries(msctfime wine uuid cicero) add_importlibs(msctfime user32 gdi32 advapi32 msvcrt kernel32 ntdll) -add_delay_importlibs(msctfime comctl32 msctf oleaut32 imm32) +add_delay_importlibs(msctfime uxtheme comctl32 msctf oleaut32 imm32) add_cd_file(TARGET msctfime DESTINATION reactos/system32 FOR all) diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h index f7ada8fbd6e..7b2f2fff822 100644 --- a/dll/ime/msctfime/msctfime.h +++ b/dll/ime/msctfime/msctfime.h @@ -28,6 +28,7 @@ #include <cicarray.h> #include <cicimc.h> #include <cictf.h> +#include <cicreg.h> #include <ciccaret.h> #include <cicuif.h> #include <cicutb.h> diff --git a/dll/ime/msctfime/ui.cpp b/dll/ime/msctfime/ui.cpp index 74a8c733de0..660d20824d6 100644 --- a/dll/ime/msctfime/ui.cpp +++ b/dll/ime/msctfime/ui.cpp @@ -9,6 +9,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); +/***********************************************************************/ + UINT WM_MSIME_SERVICE = 0; UINT WM_MSIME_UIREADY = 0; UINT WM_MSIME_RECONVERTREQUEST = 0; @@ -61,6 +63,326 @@ BOOL RegisterMSIMEMessage(VOID) WM_MSIME_KEYMAP); } +/***********************************************************************/ + +/// @implemented +CDefCompFrameGripper::CDefCompFrameGripper( + CDefCompFrameWindow *pDefCompFrameWindow, + LPCRECT prc, + DWORD style) : CUIFGripper(pDefCompFrameWindow, prc, style) +{ + m_pDefCompFrameWindow = pDefCompFrameWindow; +} + +/***********************************************************************/ + +/// @implemented +CCompFinalizeButton::CCompFinalizeButton( + CCompFrameWindow *pParent, + DWORD nObjectID, + LPCRECT prc, + DWORD style, + DWORD dwButtonFlags, + LPCWSTR pszText) + : CUIFToolbarButton(pParent, nObjectID, prc, style, dwButtonFlags, pszText) +{ + m_pCompFrameWindow = pParent; +} + +/// @implemented +CCompFinalizeButton::~CCompFinalizeButton() +{ + HICON hIcon = CUIFToolbarButton::GetIcon(); + if (hIcon) + { + ::DestroyIcon(hIcon); + CUIFToolbarButton::SetIcon(NULL); + } +} + +/// @implemented +void CCompFinalizeButton::OnLeftClick() +{ + HIMC hIMC = m_pCompFrameWindow->m_hIMC; + if (hIMC) + ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); +} + +/***********************************************************************/ + +/// @implemented +CCompFrameWindow::CCompFrameWindow(HIMC hIMC, DWORD style) + : CUIFWindow(g_hInst, style) +{ + m_hIMC = hIMC; +} + +/***********************************************************************/ + +/// @implemented +CCompButtonFrameWindow::CCompButtonFrameWindow(HIMC hIMC, DWORD style) + : CCompFrameWindow(hIMC, style) +{ +} + +/// @implemented +void CCompButtonFrameWindow::Init() +{ + if (m_pFinalizeButton) + return; + + RECT rc = { 0, 0, 0, 0 }; + m_pFinalizeButton = new(cicNoThrow) CCompFinalizeButton(this, 0, &rc, 0, 0x10000, NULL); + + m_pFinalizeButton->Initialize(); + m_pFinalizeButton->Init(); + + HICON hIcon = (HICON)::LoadImageW(g_hInst, MAKEINTRESOURCEW(IDI_DOWN), IMAGE_ICON, 16, 16, 0); + m_pFinalizeButton->SetIcon(hIcon); + + WCHAR szText[256]; + LoadStringW(g_hInst, IDS_FINALIZE_STRING, szText, _countof(szText)); + m_pFinalizeButton->SetToolTip(szText); + + AddUIObj(m_pFinalizeButton); +} + +/// @implemented +void CCompButtonFrameWindow::MoveShow(LONG x, LONG y, BOOL bShow) +{ + INT nWidth = m_Margins.cxRightWidth + m_Margins.cxLeftWidth + 18; + INT nHeight = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 18; + Move(x, y, nWidth + 4, nHeight + 4); + + if (m_pFinalizeButton) + { + RECT rc = { 1, 1, nWidth + 1, nHeight + 1 }; + m_pFinalizeButton->SetRect(&rc); + } + + Show(bShow); +} + +/// @implemented +STDMETHODIMP_(void) CCompButtonFrameWindow::OnCreate(HWND hWnd) +{ + ::SetWindowTheme(hWnd, L"TOOLBAR", NULL); + + ZeroMemory(&m_Margins, sizeof(m_Margins)); + + CUIFTheme theme; + theme.m_hTheme = NULL; + theme.m_iPartId = 1; + theme.m_iStateId = 0; + theme.m_pszClassList = L"TOOLBAR"; + if (SUCCEEDED(theme.InternalOpenThemeData(hWnd))) + theme.GetThemeMargins(NULL, 1, 3602, NULL, &m_Margins); +} + +/***********************************************************************/ + +/// @implemented +CDefCompFrameWindow::CDefCompFrameWindow(HIMC hIMC, DWORD style) + : CCompFrameWindow(hIMC, style) +{ + LoadPosition(); + m_iPartId = 1; + m_iStateId = 1; + m_pszClassList = L"TASKBAR"; +} + +/// @implemented +CDefCompFrameWindow::~CDefCompFrameWindow() +{ + SavePosition(); +} + +/// @implemented +void CDefCompFrameWindow::Init() +{ + RECT rc; + + if (!m_pGripper) + { + ZeroMemory(&rc, sizeof(rc)); + m_pGripper = new(cicNoThrow) CDefCompFrameGripper(this, &rc, 0); + m_pGripper->Initialize(); + AddUIObj(m_pGripper); + } + + if (!m_pFinalizeButton) + { + ZeroMemory(&rc, sizeof(rc)); + m_pFinalizeButton = new(cicNoThrow) CCompFinalizeButton(this, 0, &rc, 0, 0x10000, NULL); + m_pFinalizeButton->Initialize(); + m_pFinalizeButton->Init(); + + HICON hIcon = (HICON)LoadImageW(g_hInst, MAKEINTRESOURCEW(IDI_DOWN), IMAGE_ICON, 16, 16, 0); + m_pFinalizeButton->SetIcon(hIcon); + + WCHAR szText[256]; + ::LoadStringW(g_hInst, IDS_FINALIZE_STRING, szText, _countof(szText)); + SetToolTip(szText); + + AddUIObj(m_pFinalizeButton); + } +} + +/// @implemented +INT CDefCompFrameWindow::GetGripperWidth() +{ + if (!m_pGripper || FAILED(m_pGripper->EnsureThemeData(m_hWnd))) + return 5; + + INT ret = -1; + HDC hDC = ::GetDC(m_hWnd); + SIZE partSize; + if (SUCCEEDED(m_pGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE, &partSize))) + ret = partSize.cx + 4; + + ::ReleaseDC(m_hWnd, hDC); + + return ((ret < 0) ? 5 : ret); +} + +/// @implemented +void CDefCompFrameWindow::MyScreenToClient(LPPOINT ppt, LPRECT prc) +{ + if (ppt) + ::ScreenToClient(m_hWnd, ppt); + + if (prc) + { + ::ScreenToClient(m_hWnd, (LPPOINT)prc); + ::ScreenToClient(m_hWnd, (LPPOINT)&prc->right); + } +} + +/// @implemented +void CDefCompFrameWindow::SetCompStrRect(INT nWidth, INT nHeight, BOOL bShow) +{ + INT GripperWidth = GetGripperWidth(); + + RECT rc; + ::GetWindowRect(m_hWnd, &rc); + + Move(rc.left, rc.top, GripperWidth + nWidth + 24, nHeight + 10); + + if (m_pGripper) + { + rc = { 2, 3, GripperWidth + 2, nHeight + 7 }; + m_pGripper->SetRect(&rc); + } + + if (m_pFinalizeButton) + { + rc = { + GripperWidth + nWidth + 4, + 3, + m_Margins.cxLeftWidth + m_Margins.cxRightWidth + GripperWidth + nWidth + 22, + m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 21 + }; + m_pFinalizeButton->SetRect(&rc); + } + + Show(bShow); + + ::MoveWindow(m_hwndDefCompFrame, GripperWidth + 2, 7, nWidth, nHeight, TRUE); + ::ShowWindow(m_hwndDefCompFrame, (bShow ? SW_SHOWNOACTIVATE : SW_HIDE)); +} + +/// @implemented +void CDefCompFrameWindow::LoadPosition() +{ + DWORD x = 0, y = 0; + + LSTATUS error; + CicRegKey regKey; + error = regKey.Open(HKEY_CURRENT_USER, + TEXT("SOFTWARE\\Microsoft\\CTF\\CUAS\\DefaultCompositionWindow")); + if (error == ERROR_SUCCESS) + { + regKey.QueryDword(TEXT("Left"), &x); + regKey.QueryDword(TEXT("Top"), &y); + } + + Move(x, y, 0, 0); +} + +/// @implemented +void CDefCompFrameWindow::SavePosition() +{ + LSTATUS error; + CicRegKey regKey; + error = regKey.Create(HKEY_CURRENT_USER, + TEXT("SOFTWARE\\Microsoft\\CTF\\CUAS\\DefaultCompositionWindow")); + if (error == ERROR_SUCCESS) + { + regKey.SetDword(TEXT("Left"), m_nLeft); + regKey.SetDword(TEXT("Top"), m_nTop); + } +} + +/// @implemented +STDMETHODIMP_(void) CDefCompFrameWindow::OnCreate(HWND hWnd) +{ + ::SetWindowTheme(hWnd, L"TASKBAR", NULL); + + ZeroMemory(&m_Margins, sizeof(m_Margins)); + + CUIFTheme theme; + theme.m_hTheme = NULL; + theme.m_iPartId = 1; + theme.m_iStateId = 0; + theme.m_pszClassList = L"TOOLBAR"; + if (SUCCEEDED(theme.InternalOpenThemeData(hWnd))) + GetThemeMargins(NULL, 1, 3602, NULL, &m_Margins); +} + +/// @implemented +STDMETHODIMP_(BOOL) CDefCompFrameWindow::OnSetCursor(UINT uMsg, LONG x, LONG y) +{ + if (!::IsWindow(m_hwndDefCompFrame)) + return FALSE; + + RECT rc; + ::GetWindowRect(m_hwndDefCompFrame, &rc); + MyScreenToClient(NULL, &rc); + POINT pt = { x, y }; + return ::PtInRect(&rc, pt); +} + +/// @implemented +STDMETHODIMP_(LRESULT) +CDefCompFrameWindow::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CicIMCLock imcLock(m_hIMC); + if (!imcLock) + imcLock.m_hr = E_FAIL; + if (SUCCEEDED(imcLock.m_hr)) + ::SendMessage(imcLock.get().hWnd, WM_IME_NOTIFY, 0xF, (LPARAM)m_hIMC); + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +/// @implemented +STDMETHODIMP_(void) CDefCompFrameWindow::HandleMouseMsg(UINT uMsg, LONG x, LONG y) +{ + if (::IsWindow(m_hwndDefCompFrame)) + { + RECT rc; + ::GetWindowRect(m_hwndDefCompFrame, &rc); + MyScreenToClient(NULL, &rc); + + POINT pt = { x, y }; + if (::PtInRect(&rc, pt)) + ::SendMessage(m_hwndDefCompFrame, 0x7E8, 0, 0); + } + + CUIFWindow::HandleMouseMsg(uMsg, x, y); +} + +/***********************************************************************/ + // For GetWindowLongPtr/SetWindowLongPtr #define UIGWLP_HIMC 0 #define UIGWLP_UI sizeof(HIMC) diff --git a/dll/ime/msctfime/ui.h b/dll/ime/msctfime/ui.h index e9433fc734c..71b32ebb40d 100644 --- a/dll/ime/msctfime/ui.h +++ b/dll/ime/msctfime/ui.h @@ -7,6 +7,15 @@ #pragma once +class CUIFGripper; + class CDefCompFrameGripper; +class CUIFToolbarButton; + class CCompFinalizeButton; +class CUIFWindow; + class CCompFrameWindow; + class CCompButtonFrameWindow; + class CDefCompFrameWindow; + /***********************************************************************/ extern UINT WM_MSIME_SERVICE; @@ -25,6 +34,92 @@ BOOL RegisterMSIMEMessage(VOID); /***********************************************************************/ +class CDefCompFrameGripper : public CUIFGripper +{ +public: + CDefCompFrameWindow *m_pDefCompFrameWindow; + + CDefCompFrameGripper(CDefCompFrameWindow *pDefCompFrameWindow, LPCRECT prc, DWORD style); +}; + +/***********************************************************************/ + +class CCompFrameWindow; + +class CCompFinalizeButton : public CUIFToolbarButton +{ +public: + CCompFrameWindow *m_pCompFrameWindow; + + CCompFinalizeButton( + CCompFrameWindow *pParent, + DWORD nObjectID, + LPCRECT prc, + DWORD style, + DWORD dwButtonFlags, + LPCWSTR pszText); + ~CCompFinalizeButton() override; + + STDMETHOD_(void, OnLeftClick)() override; +}; + +/***********************************************************************/ + +class CCompFrameWindow : public CUIFWindow +{ +public: + HIMC m_hIMC; + + CCompFrameWindow(HIMC hIMC, DWORD style); +}; + +/***********************************************************************/ + +class CCompButtonFrameWindow : public CCompFrameWindow +{ +public: + MARGINS m_Margins; + CCompFinalizeButton *m_pFinalizeButton; + + CCompButtonFrameWindow(HIMC hIMC, DWORD style); + + void Init(); + void MoveShow(LONG x, LONG y, BOOL bShow); + + STDMETHOD_(void, OnCreate)(HWND hWnd) override; +}; + +/***********************************************************************/ + +class CDefCompFrameWindow : public CCompFrameWindow +{ +public: + HWND m_hwndDefCompFrame; + CDefCompFrameGripper *m_pGripper; + CCompFinalizeButton *m_pFinalizeButton; + MARGINS m_Margins; + +public: + CDefCompFrameWindow(HIMC hIMC, DWORD style); + ~CDefCompFrameWindow() override; + + void Init(); + INT GetGripperWidth(); + void MyScreenToClient(LPPOINT ppt, LPRECT prc); + void SetCompStrRect(INT nWidth, INT nHeight, BOOL bShow); + + void LoadPosition(); + void SavePosition(); + + STDMETHOD_(void, OnCreate)(HWND hWnd) override; + STDMETHOD_(BOOL, OnSetCursor)(UINT uMsg, LONG x, LONG y) override; + STDMETHOD_(LRESULT, OnWindowPosChanged)(HWND hWnd, UINT uMsg, WPARAM wParam, + LPARAM lParam) override; + STDMETHOD_(void, HandleMouseMsg)(UINT uMsg, LONG x, LONG y) override; +}; + +/***********************************************************************/ + struct UIComposition { void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd); diff --git a/sdk/lib/cicero/cicuif.cpp b/sdk/lib/cicero/cicuif.cpp index 322058e1ad3..3ef832053a9 100644 --- a/sdk/lib/cicero/cicuif.cpp +++ b/sdk/lib/cicero/cicuif.cpp @@ -3409,7 +3409,7 @@ STDMETHODIMP_(void) CUIFToolbarMenuButton::OnLButtonUp(LONG x, LONG y) { CUIFButton::OnLButtonUp(x, y); - m_pToolbarButton->OnUnknownMouse2(x, y); + m_pToolbarButton->OnUnknownMouse0(); } STDMETHODIMP_(BOOL) @@ -3444,16 +3444,16 @@ CUIFToolbarButtonElement::OnLButtonUp(LONG x, LONG y) { CUIFButton::OnLButtonUp(x, y); if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) == 0x20000) - m_pToolbarButton->OnUnknownMouse2(x, y); + m_pToolbarButton->OnUnknownMouse0(); else - m_pToolbarButton->OnUnknownMouse1(x, y); + m_pToolbarButton->OnLeftClick(); } STDMETHODIMP_(void) CUIFToolbarButtonElement::OnRButtonUp(LONG x, LONG y) { if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) != 0x20000) - m_pToolbarButton->OnUnknownMouse0(); + m_pToolbarButton->OnRightClick(); } ///////////////////////////////////////////////////////////////////////////// diff --git a/sdk/lib/cicero/cicuif.h b/sdk/lib/cicero/cicuif.h index e01518cb05d..6ec4f1deeb3 100644 --- a/sdk/lib/cicero/cicuif.h +++ b/sdk/lib/cicero/cicuif.h @@ -928,8 +928,8 @@ public: STDMETHOD_(void, SetToolTip)(LPCWSTR pszToolTip) override; STDMETHOD_(void, OnUnknownMouse0)() { } - STDMETHOD_(void, OnUnknownMouse1)(LONG x, LONG y) { } - STDMETHOD_(void, OnUnknownMouse2)(LONG x, LONG y) { } + STDMETHOD_(void, OnLeftClick)() { } + STDMETHOD_(void, OnRightClick)() { } }; /////////////////////////////////////////////////////////////////////////////