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

commit c6ceae3440679c664b0936fbb81a20f1c15fbc7c
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Sat Feb 10 13:04:37 2024 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Sat Feb 10 13:04:37 2024 +0900

    [MSUTB] Add CTipbarWnd Part 3 (#6467)
    
    Supporting Language Bar...
    JIRA issue: CORE-19363
    - Add implementation to
      CTipbarWnd class.
    - Add delay link to imm32.dll.
---
 dll/win32/msutb/CMakeLists.txt |   2 +-
 dll/win32/msutb/msutb.cpp      | 371 +++++++++++++++++++++++++++++++++++++----
 dll/win32/msutb/precomp.h      |   1 +
 3 files changed, 344 insertions(+), 30 deletions(-)

diff --git a/dll/win32/msutb/CMakeLists.txt b/dll/win32/msutb/CMakeLists.txt
index b425c8d0328..ee8204be2ff 100644
--- a/dll/win32/msutb/CMakeLists.txt
+++ b/dll/win32/msutb/CMakeLists.txt
@@ -15,5 +15,5 @@ set_module_type(msutb win32dll)
 add_dependencies(msutb msctf psdk)
 target_link_libraries(msutb wine uuid atl_classes)
 add_importlibs(msutb user32 gdi32 advapi32 msvcrt kernel32 ntdll)
-add_delay_importlibs(msutb uxtheme comctl32 msctf ole32 oleacc oleaut32 
shell32)
+add_delay_importlibs(msutb uxtheme imm32 comctl32 msctf ole32 oleacc oleaut32 
shell32)
 add_cd_file(TARGET msutb DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp
index cfdfb54d8a7..f1c350035a3 100644
--- a/dll/win32/msutb/msutb.cpp
+++ b/dll/win32/msutb/msutb.cpp
@@ -364,6 +364,24 @@ BOOL IsTransparecyAvailable(void)
     return FALSE;
 }
 
+static INT CALLBACK
+FindEAEnumFontProc(ENUMLOGFONT *pLF, NEWTEXTMETRIC *pTM, INT nFontType, LPARAM 
lParam)
+{
+    if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] != 
'@'))
+        return TRUE;
+    *(BOOL*)lParam = TRUE;
+    return FALSE;
+}
+
+BOOL CheckEAFonts(void)
+{
+    BOOL bHasVertical = FALSE;
+    HDC hDC = ::GetDC(NULL);
+    ::EnumFonts(hDC, NULL, (FONTENUMPROC)FindEAEnumFontProc, 
(LPARAM)&bHasVertical);
+    ::ReleaseDC(NULL, hDC);
+    return bHasVertical;
+}
+
 BOOL InitFromReg(void)
 {
     DWORD dwValue;
@@ -680,6 +698,7 @@ protected:
     CicArray<CTipbarAccItem*> m_AccItems;
     LONG m_cSelection;
     friend class CUTBMenuWnd;
+    friend class CTipbarWnd;
 
 public:
     CTipbarAccessible(CTipbarAccItem *pItem);
@@ -968,6 +987,7 @@ class CTipbarGripper : public CUIFGripper
 protected:
     CTipbarWnd *m_pTipbarWnd;
     BOOL m_bInDebugMenu;
+    friend class CTipbarWnd;
 
 public:
     CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style);
@@ -1187,7 +1207,8 @@ class CTipbarWnd
     , public CTipbarAccItem
     , public CUIFWindow
 {
-    DWORD m_dwUnknown19[2];
+    CTipbarCoInitialize m_coInit;
+    DWORD m_dwSinkCookie;
     CModalMenu *m_pModalMenu;
     CTipbarThread *m_pThread;
     CicArray<GUID*> m_TipbarGUIDArray;
@@ -1239,6 +1260,11 @@ public:
         return static_cast<CUIFWindow*>(this);
     }
 
+    CTipbarAccItem *GetAccItem()
+    {
+        return static_cast<CTipbarAccItem*>(this);
+    }
+
     void Init(BOOL bFlag, CDeskBand *pDeskBand);
     void InitHighContrast();
     void InitMetrics();
@@ -1286,7 +1312,7 @@ public:
     void MyClientToScreen(LPPOINT lpPoint, LPRECT prc);
     void SavePosition();
     void SetAlpha(BYTE bAlpha, BOOL bFlag);
-    BOOL SetLangBand(BOOL bFlag1, BOOL bFlag2);
+    BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2);
     void SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight);
     void SetShowText(BOOL bShow);
     void SetShowTrayIcon(BOOL bShow);
@@ -3627,8 +3653,6 @@ STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT 
uMsg, LONG x, LONG y)
 CTipbarWnd::CTipbarWnd(DWORD style)
     : CUIFWindow(g_hInst, style)
 {
-    m_dwUnknown19[0] = 0;
-
     m_dwUnknown23_1[4] = 0;
     m_dwUnknown23_1[5] = 0;
     m_dwUnknown23_1[6] = 0;
@@ -3813,9 +3837,11 @@ void CTipbarWnd::MoveToStub(BOOL bFlag)
 {
 }
 
-/// @unimplemented
 void CTipbarWnd::RestoreFromStub()
 {
+    m_dwTipbarWndFlags &= 0x3F;
+    KillTimer(1);
+    KillTimer(2);
 }
 
 /// @unimplemented
@@ -3824,16 +3850,38 @@ INT CTipbarWnd::GetCtrlButtonWidth()
     return 0;
 }
 
-/// @unimplemented
 INT CTipbarWnd::GetGripperWidth()
 {
-    return 0;
+    if (m_dwTipbarWndFlags & 2)
+        return 0;
+
+    if (!m_pTipbarGripper || FAILED(m_pTipbarGripper->EnsureThemeData(m_hWnd)))
+        return 5;
+
+    INT width = -1;
+    SIZE partSize;
+    HDC hDC = ::GetDC(m_hWnd);
+    if (SUCCEEDED(m_pTipbarGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE, 
&partSize)))
+    {
+        INT cx = partSize.cx;
+        if (m_dwTipbarWndFlags & 4)
+            cx = partSize.cy;
+        width = cx + 4;
+    }
+    ::ReleaseDC(m_hWnd, hDC);
+
+    return ((width < 0) ? 5 : width);
 }
 
-/// @unimplemented
 INT CTipbarWnd::GetTipbarHeight()
 {
-    return 0;
+    SIZE size = { 0, 0 };
+    if (m_pWndFrame)
+        m_pWndFrame->GetFrameSize(&size);
+    INT cy = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 2;
+    if (cy < 6)
+        cy = 6;
+    return m_cySmallIcon + cy + (2 * size.cy);
 }
 
 /// @unimplemented
@@ -3853,19 +3901,93 @@ void CTipbarWnd::LocateCtrlButtons()
 {
 }
 
-/// @unimplemented
 void CTipbarWnd::AdjustPosOnDisplayChange()
 {
+    RECT rcWorkArea;
+    RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight };
+    if (!GetWorkArea(&rc, &rcWorkArea))
+        return;
+
+    INT x = m_nLeft, y = m_nTop;
+    if (m_dwTipbarWndFlags & 0x200000)
+        x = rcWorkArea.left;
+    if (m_dwTipbarWndFlags & 0x40000)
+        y = rcWorkArea.top;
+    if (m_dwTipbarWndFlags & 0x100000)
+        x = rcWorkArea.right - m_nWidth;
+    if (m_dwTipbarWndFlags & 0x80000)
+        y = rcWorkArea.bottom - m_nHeight;
+    if (x != m_nLeft || y != m_nTop)
+        Move(x, y, m_nWidth, m_nHeight);
 }
 
-/// @unimplemented
 void CTipbarWnd::SetVertical(BOOL bVertical)
 {
+    if (bVertical)
+        m_dwTipbarWndFlags |= 0x4;
+    else
+        m_dwTipbarWndFlags &= ~0x4;
+
+    if (m_pTipbarGripper)
+    {
+        DWORD style = m_pTipbarGripper->m_style;
+        if (bVertical)
+            style |= 0x1;
+        else
+            style &= 0x1;
+        m_pTipbarGripper->SetStyle(style);
+    }
+
+    if (g_fTaskbarTheme)
+        SetActiveTheme(L"TASKBAR", !!(m_dwTipbarWndFlags & 0x4), 1);
+
+    if (!(m_dwTipbarWndFlags & 2))
+    {
+        if (m_dwTipbarWndFlags & 4)
+        {
+            Move(m_nLeft, m_nTop, GetTipbarHeight(), 0);
+        }
+        else
+        {
+            Move(m_nLeft, m_nTop, 0, GetTipbarHeight());
+        }
+    }
+
+    if (m_hWnd)
+    {
+        KillTimer(7);
+        SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
+    }
 }
 
-/// @unimplemented
 void CTipbarWnd::UpdatePosFlags()
 {
+    if (m_dwTipbarWndFlags & 0x2)
+        return;
+
+    RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }, 
rcWorkArea;
+    if (!GetWorkArea(&rc, &rcWorkArea))
+        return;
+
+    if (m_nLeft > rcWorkArea.left + 2)
+        m_dwTipbarWndFlags &= ~0x200000;
+    else
+        m_dwTipbarWndFlags |= 0x200000;
+
+    if ( m_nTop> rcWorkArea.top + 2 )
+        m_dwTipbarWndFlags &= ~0x40000;
+    else
+        m_dwTipbarWndFlags |= 0x40000;
+
+    if (m_nLeft + m_nWidth < rcWorkArea.right - 2)
+        m_dwTipbarWndFlags &= ~0x100000;
+    else
+        m_dwTipbarWndFlags |= 0x100000;
+
+    if (m_nTop + m_nHeight < rcWorkArea.bottom - 2)
+        m_dwTipbarWndFlags &= ~0x80000;
+    else
+        m_dwTipbarWndFlags |= 0x80000;
 }
 
 /// @unimplemented
@@ -3873,10 +3995,9 @@ void CTipbarWnd::CancelMenu()
 {
 }
 
-/// @unimplemented
 BOOL CTipbarWnd::CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2)
 {
-    return FALSE;
+    return (prc1->top < prc2->top + 5) && (prc2->right <= prc1->right + (5 * 
m_ButtonWidth));
 }
 
 /// @unimplemented
@@ -3884,10 +4005,35 @@ void CTipbarWnd::ClearLBItemList()
 {
 }
 
-/// @unimplemented
 HFONT CTipbarWnd::CreateVerticalFont()
 {
-    return NULL;
+    if (!m_hWnd)
+        return NULL;
+
+    CUIFTheme theme;
+    theme.m_iPartId = 1;
+    theme.m_iStateId = 0;
+    theme.m_pszClassList = L"TOOLBAR";
+
+    LOGFONTW lf;
+    if (FAILED(theme.InternalOpenThemeData(m_hWnd)) ||
+        FAILED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, 
&lf)))
+    {
+        ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
+    }
+
+    lf.lfEscapement = lf.lfOrientation = 2700;
+    lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
+
+    if (CheckEAFonts())
+    {
+        WCHAR szText[LF_FACESIZE];
+        szText[0] = L'@';
+        StringCchCopyW(&szText[1], _countof(szText) - 1, lf.lfFaceName);
+        StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), szText);
+    }
+
+    return ::CreateFontIndirectW(&lf);
 }
 
 void CTipbarWnd::UpdateVerticalFont()
@@ -3991,15 +4137,85 @@ void CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL bFlag)
 {
 }
 
-/// @unimplemented
-BOOL CTipbarWnd::SetLangBand(BOOL bFlag1, BOOL bFlag2)
+BOOL CTipbarWnd::SetLangBand(BOOL bDeskBand, BOOL bFlag2)
 {
-    return FALSE;
+    if (bDeskBand == !!(m_dwShowType & TF_SFT_DESKBAND))
+        return TRUE;
+
+    BOOL ret = TRUE;
+    HWND hwndTray = m_ShellWndThread.GetWndTray();
+    if (bFlag2 && hwndTray)
+    {
+        DWORD_PTR dwResult;
+        HWND hImeWnd = ::ImmGetDefaultIMEWnd(hwndTray);
+        if (hImeWnd)
+            ::SendMessageTimeout(hImeWnd, WM_IME_SYSTEM, 0x24 - bDeskBand, 
(LPARAM)hwndTray,
+                                 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, 
&dwResult);
+        else
+            ::SendMessageTimeout(hwndTray, 0x505, 0, bDeskBand,
+                                 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, 
&dwResult);
+    }
+    else
+    {
+        ret = FALSE;
+    }
+
+    if (!(m_dwTipbarWndFlags & 2))
+    {
+        if (bDeskBand)
+        {
+            KillTimer(7);
+            SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
+        }
+    }
+
+    return ret;
 }
 
-/// @unimplemented
 void CTipbarWnd::SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight)
 {
+    if (m_dwTipbarWndFlags & 0x2)
+    {
+        m_nWidth = nWidth;
+        m_nHeight = nHeight;
+        return;
+    }
+
+    ++m_bInCallOn;
+
+    m_dwTipbarWndFlags |= 0x400;
+
+    m_X = X;
+    m_Y = Y;
+    m_CX = nWidth;
+    m_CY = nHeight;
+
+    RECT rc;
+    SIZE size = { 0, 0 };
+    if (m_pWndFrame)
+    {
+        ::SetRect(&rc, 0, 0, nWidth - m_cxDlgFrameX2, nHeight - 
m_cyDlgFrameX2);
+        m_pWndFrame->SetRect(&rc);
+        m_pWndFrame->GetFrameSize(&size);
+    }
+
+    if (m_pTipbarGripper)
+    {
+        if (m_dwTipbarWndFlags & 4)
+        {
+            INT GripperWidth = GetGripperWidth();
+            ::SetRect(&rc, size.cx, size.cy, nWidth - m_cxDlgFrameX2 - 
size.cx, size.cy + GripperWidth);
+        }
+        else
+        {
+            INT GripperWidth = GetGripperWidth();
+            INT y1 = nHeight - m_cyDlgFrameX2 - size.cy;
+            ::SetRect(&rc, size.cx, size.cy, size.cx + GripperWidth, y1);
+        }
+        m_pTipbarGripper->SetRect(&rc);
+    }
+
+    --m_bInCallOn;
 }
 
 /// @unimplemented
@@ -4209,10 +4425,54 @@ STDMETHODIMP CTipbarWnd::OnThreadItemChange(DWORD 
dwThreadId)
     return E_NOTIMPL;
 }
 
-/// @unimplemented
 STDMETHODIMP CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM 
wParam, LPARAM lParam)
 {
-    return E_NOTIMPL;
+    switch (uMsg)
+    {
+        case WM_NCLBUTTONDOWN:
+        case WM_NCRBUTTONDOWN:
+        case WM_NCMBUTTONDOWN:
+        case WM_LBUTTONUP:
+        case WM_RBUTTONUP:
+        case WM_MBUTTONUP:
+            break;
+
+        case WM_NCLBUTTONUP:
+        case WM_NCRBUTTONUP:
+        case WM_NCMBUTTONUP:
+            if (m_pThread)
+            {
+                CUTBMenuWnd *pMenuUI = m_pModalMenu->m_pMenuUI;
+                if (pMenuUI)
+                {
+                    HWND hWnd = *pMenuUI;
+                    if (hWnd)
+                    {
+                        POINT pt = { (SHORT)LOWORD(lParam), 
(SHORT)HIWORD(lParam) };
+                        ::ScreenToClient(hWnd, &pt);
+                        uMsg += WM_LBUTTONUP - WM_NCLBUTTONUP;
+                        ::PostMessage(m_hWnd, uMsg, wParam, MAKELPARAM(pt.x, 
pt.y));
+                    }
+                }
+            }
+            break;
+
+        default:
+        {
+            if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP)
+            {
+                if (m_pThread)
+                    m_pModalMenu->PostKey(uMsg == WM_KEYUP, wParam, lParam);
+            }
+            else
+            {
+                CancelMenu();
+            }
+            break;
+        }
+    }
+
+    return 0;
 }
 
 /// @unimplemented
@@ -4236,7 +4496,7 @@ STDMETHODIMP CTipbarWnd::OnLangBarUpdate(TfLBIClick 
click, BOOL bFlag)
 STDMETHODIMP_(BSTR) CTipbarWnd::GetAccName()
 {
     WCHAR szText[256];
-    ::LoadStringW(g_hInst,  IDS_LANGUAGEBAR, szText, _countof(szText));
+    ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText));
     return ::SysAllocString(szText);
 }
 
@@ -4272,9 +4532,25 @@ STDMETHODIMP_(void) CTipbarWnd::OnCreate(HWND hWnd)
 {
 }
 
-/// @unimplemented
 STDMETHODIMP_(void) CTipbarWnd::OnDestroy(HWND hWnd)
 {
+    CancelMenu();
+
+    if (m_pTipbarAccessible)
+        m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, 
GetAccItem());
+
+    OnTerminateToolbar();
+    if (m_pTipbarAccessible)
+    {
+        m_pTipbarAccessible->ClearAccItems();
+        m_pTipbarAccessible->Release();
+        m_pTipbarAccessible = NULL;
+    }
+
+    m_coInit.CoUninit();
+
+    if (m_pLangBarMgr)
+        m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie);
 }
 
 /// @unimplemented
@@ -4288,9 +4564,13 @@ STDMETHODIMP_(void) CTipbarWnd::OnSysColorChange()
     SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
 }
 
-/// @unimplemented
 void CTipbarWnd::OnTerminateToolbar()
 {
+    m_dwTipbarWndFlags |= 0x10000;
+    DestroyOverScreenSizeBalloon();
+    TerminateAllThreads(TRUE);
+    if (!(m_dwTipbarWndFlags & 0x2))
+        SavePosition();
 }
 
 STDMETHODIMP_(void) CTipbarWnd::OnEndSession(HWND hWnd, WPARAM wParam, LPARAM 
lParam)
@@ -4349,11 +4629,22 @@ CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, 
WPARAM wParam, LPARAM lPar
     return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
 }
 
-/// @unimplemented
 STDMETHODIMP_(LRESULT)
 CTipbarWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    return 0;
+    if (m_pTipbarAccessible)
+    {
+        if (wParam) // Show?
+        {
+            m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, 
GetAccItem());
+            m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, 
GetAccItem());
+        }
+        else
+        {
+            m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, 
GetAccItem());
+        }
+    }
+    return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
 }
 
 STDMETHODIMP_(LRESULT)
@@ -4378,11 +4669,33 @@ CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam)
     return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
 }
 
-/// @unimplemented
 STDMETHODIMP_(HRESULT)
 CTipbarWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    return E_NOTIMPL;
+    if (lParam != -4)
+        return S_OK;
+    if (!m_pTipbarAccessible)
+        return E_OUTOFMEMORY;
+
+    if (m_pTipbarAccessible->m_bInitialized)
+        return m_pTipbarAccessible->CreateRefToAccObj(wParam);
+
+    HRESULT hr = S_OK;
+    if (SUCCEEDED(m_coInit.EnsureCoInit()))
+    {
+        hr = m_pTipbarAccessible->Initialize();
+        if (FAILED(hr))
+        {
+            m_pTipbarAccessible->Release();
+            m_pTipbarAccessible = NULL;
+            return hr;
+        }
+
+        m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem());
+        return m_pTipbarAccessible->CreateRefToAccObj(wParam);
+    }
+
+    return hr;
 }
 
 STDMETHODIMP_(BOOL) CTipbarWnd::OnEraseBkGnd(HWND hWnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam)
diff --git a/dll/win32/msutb/precomp.h b/dll/win32/msutb/precomp.h
index 05b2a826e27..08b64cdd9fb 100644
--- a/dll/win32/msutb/precomp.h
+++ b/dll/win32/msutb/precomp.h
@@ -17,6 +17,7 @@
 #include <oleacc.h>
 #include <imm.h>
 #include <ddk/immdev.h>
+#include <undocuser.h>
 #include <cguid.h>
 #include <msctf.h>
 #include <ctffunc.h>

Reply via email to