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

commit 1001b59a06ae73f39a5dc779e8ba81c06bd2389d
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Mon Jan 29 18:38:59 2024 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Mon Jan 29 18:38:59 2024 +0900

    [MSUTB][SDK] Add CUTBMenuWnd and CUTBMenuItem (#6420)
    
    Supporting Language Bar...
    JIRA issue: CORE-19363
    - Implement CUTBMenuWnd and
      CUTBMenuItem classes.
    - Add IDS_MENUWND and
      IDS_LEFTCLICK resource strings.
---
 dll/win32/msutb/lang/en-US.rc       |   2 +
 dll/win32/msutb/msutb.cpp           | 294 +++++++++++++++++++++++++++++++++++-
 dll/win32/msutb/precomp.h           |   4 +-
 dll/win32/msutb/resource.h          |   2 +
 sdk/include/reactos/cicero/cicuif.h |  48 +++---
 5 files changed, 317 insertions(+), 33 deletions(-)

diff --git a/dll/win32/msutb/lang/en-US.rc b/dll/win32/msutb/lang/en-US.rc
index 646ca61f2c1..c45c6e28438 100644
--- a/dll/win32/msutb/lang/en-US.rc
+++ b/dll/win32/msutb/lang/en-US.rc
@@ -16,4 +16,6 @@ BEGIN
     IDS_IGNORE           "&Ignore"
     IDS_YES              "&Yes"
     IDS_NO               "&No"
+    IDS_MENUWND          "Menu Window"
+    IDS_LEFTCLICK        "Left Click"
 END
diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp
index 6ab8eb45b21..615e7c47450 100644
--- a/dll/win32/msutb/msutb.cpp
+++ b/dll/win32/msutb/msutb.cpp
@@ -33,6 +33,7 @@ CMsUtbModule gModule;
 
 class CCicLibMenuItem;
 class CTipbarAccItem;
+class CUTBMenuItem;
 
 /***********************************************************************/
 
@@ -100,6 +101,7 @@ protected:
     BOOL m_bInitialized;
     CicArray<CTipbarAccItem*> m_AccItems;
     LONG m_cSelection;
+    friend class CUTBMenuWnd;
 
 public:
     CTipbarAccessible(CTipbarAccItem *pItem);
@@ -206,9 +208,9 @@ public:
     {
         return NULL;
     }
-    STDMETHOD(DoAccDefaultAction)()
+    STDMETHOD_(BOOL, DoAccDefaultAction)()
     {
-        return S_OK;
+        return FALSE;
     }
     STDMETHOD_(BOOL, DoAccDefaultActionReal)()
     {
@@ -218,6 +220,96 @@ public:
 
 /***********************************************************************/
 
+class CTipbarCoInitialize
+{
+public:
+    BOOL m_bCoInit;
+
+    CTipbarCoInitialize() : m_bCoInit(FALSE) { }
+    ~CTipbarCoInitialize() { CoUninit(); }
+
+    HRESULT EnsureCoInit()
+    {
+        if (m_bCoInit)
+            return S_OK;
+        HRESULT hr = ::CoInitialize(NULL);
+        if (FAILED(hr))
+            return hr;
+        m_bCoInit = TRUE;
+        return S_OK;
+    }
+
+    void CoUninit()
+    {
+        if (m_bCoInit)
+        {
+            ::CoUninitialize();
+            m_bCoInit = FALSE;
+        }
+    }
+};
+
+/***********************************************************************/
+
+class CUTBMenuWnd : public CTipbarAccItem, public CUIFMenu
+{
+protected:
+    CTipbarCoInitialize m_coInit;
+    CTipbarAccessible *m_pAccessible;
+    UINT m_nMenuWndID;
+    friend class CUTBMenuItem;
+
+public:
+    CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14);
+
+    BOOL StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget);
+
+    CTipbarAccItem* GetAccItem()
+    {
+        return static_cast<CTipbarAccItem*>(this);
+    }
+    CUIFMenu* GetMenu()
+    {
+        return static_cast<CUIFMenu*>(this);
+    }
+
+    STDMETHOD_(BSTR, GetAccName)() override;
+    STDMETHOD_(INT, GetAccRole)() override;
+    STDMETHOD_(void, Initialize)() override;
+    STDMETHOD_(void, OnCreate)(HWND hWnd) override;
+    STDMETHOD_(void, OnDestroy)(HWND hWnd) override;
+    STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam) override;
+    STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam) override;
+    STDMETHOD_(void, OnTimer)(WPARAM wParam) override;
+};
+
+/***********************************************************************/
+
+class CUTBMenuItem : public CTipbarAccItem, public CUIFMenuItem
+{
+protected:
+    CUTBMenuWnd *m_pMenuWnd;
+    friend class CUTBMenuWnd;
+
+public:
+    CUTBMenuItem(CUTBMenuWnd *pMenuWnd);
+    ~CUTBMenuItem() override;
+
+    CUIFMenuItem* GetMenuItem()
+    {
+        return static_cast<CUIFMenuItem*>(this);
+    }
+
+    STDMETHOD_(BOOL, DoAccDefaultAction)() override;
+    STDMETHOD_(BOOL, DoAccDefaultActionReal)() override;
+    STDMETHOD_(BSTR, GetAccDefaultAction)() override;
+    STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override;
+    STDMETHOD_(BSTR, GetAccName)() override;
+    STDMETHOD_(INT, GetAccRole)() override;
+};
+
+/***********************************************************************/
+
 class CTrayIconWnd
 {
 public:
@@ -954,7 +1046,7 @@ STDMETHODIMP CTipbarAccessible::accDoDefaultAction(VARIANT 
varID)
     CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
     if (!pItem)
         return DISP_E_MEMBERNOTFOUND;
-    return pItem->DoAccDefaultAction() == 0;
+    return (pItem->DoAccDefaultAction() ? S_OK : S_FALSE);
 }
 
 STDMETHODIMP CTipbarAccessible::put_accName(VARIANT varID, BSTR name)
@@ -967,6 +1059,202 @@ STDMETHODIMP CTipbarAccessible::put_accValue(VARIANT 
varID, BSTR value)
     return S_FALSE;
 }
 
+/***********************************************************************
+ * CUTBMenuWnd
+ */
+
+CUTBMenuWnd::CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14)
+    : CUIFMenu(hInst, style, dwUnknown14)
+{
+}
+
+BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget)
+{
+    if (!m_pAccessible)
+        return FALSE;
+
+    m_nMenuWndID = m_pAccessible->GetIDOfItem(pTarget);
+    if (!m_nMenuWndID || m_nMenuWndID == (UINT)-1)
+        return FALSE;
+
+    if (::IsWindow(m_hWnd))
+    {
+        ::KillTimer(m_hWnd, 11);
+        ::SetTimer(m_hWnd, 11, 200, NULL);
+    }
+
+    return TRUE;
+}
+
+STDMETHODIMP_(BSTR) CUTBMenuWnd::GetAccName()
+{
+    WCHAR szText[64];
+    LoadStringW(g_hInst, IDS_MENUWND, szText, _countof(szText));
+    return ::SysAllocString(szText);
+}
+
+STDMETHODIMP_(INT) CUTBMenuWnd::GetAccRole()
+{
+    return 9;
+}
+
+STDMETHODIMP_(void) CUTBMenuWnd::Initialize()
+{
+    CTipbarAccessible *pAccessible = new(cicNoThrow) 
CTipbarAccessible(GetAccItem());
+    if (pAccessible)
+        m_pAccessible = pAccessible;
+
+    return CUIFObject::Initialize();
+}
+
+STDMETHODIMP_(void) CUTBMenuWnd::OnCreate(HWND hWnd)
+{
+    if (m_pAccessible)
+        m_pAccessible->SetWindow(hWnd);
+}
+
+STDMETHODIMP_(void) CUTBMenuWnd::OnDestroy(HWND hWnd)
+{
+    if (m_pAccessible)
+    {
+        m_pAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem());
+        m_pAccessible->ClearAccItems();
+        m_pAccessible->Release();
+        m_pAccessible = NULL;
+    }
+    m_coInit.CoUninit();
+}
+
+STDMETHODIMP_(HRESULT)
+CUTBMenuWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    if (lParam != -4)
+        return S_OK;
+
+    if (!m_pAccessible)
+        return E_OUTOFMEMORY;
+
+    if (m_pAccessible->m_bInitialized)
+        return m_pAccessible->CreateRefToAccObj(wParam);
+
+    if (SUCCEEDED(m_coInit.EnsureCoInit()))
+    {
+        HRESULT hr = m_pAccessible->Initialize();
+        if (FAILED(hr))
+        {
+            m_pAccessible->Release();
+            m_pAccessible = NULL;
+            return hr;
+        }
+
+        m_pAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem());
+        return m_pAccessible->CreateRefToAccObj(wParam);
+    }
+
+    return S_OK;
+}
+
+STDMETHODIMP_(LRESULT)
+CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    if (m_pAccessible)
+    {
+        if (wParam)
+        {
+            m_pAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem());
+            m_pAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem());
+        }
+        else
+        {
+            m_pAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem());
+        }
+    }
+
+    return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam)
+{
+    if (wParam == 11)
+    {
+        ::KillTimer(m_hWnd, 11);
+        if (m_pAccessible && m_nMenuWndID)
+        {
+            m_pAccessible->DoDefaultActionReal(m_nMenuWndID);
+            m_nMenuWndID = 0;
+        }
+    }
+}
+
+/***********************************************************************
+ * CUTBMenuItem
+ */
+
+CUTBMenuItem::CUTBMenuItem(CUTBMenuWnd *pMenuWnd)
+    : CUIFMenuItem(pMenuWnd ? pMenuWnd->GetMenu() : NULL)
+{
+    m_pMenuWnd = pMenuWnd;
+}
+
+CUTBMenuItem::~CUTBMenuItem()
+{
+    if (m_hbmColor)
+    {
+        ::DeleteObject(m_hbmColor);
+        m_hbmColor = NULL;
+    }
+    if (m_hbmMask)
+    {
+        ::DeleteObject(m_hbmMask);
+        m_hbmMask = NULL;
+    }
+}
+
+STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultAction()
+{
+    if (!m_pMenuWnd)
+        return FALSE;
+
+    m_pMenuWnd->StartDoAccDefaultActionTimer(this);
+    return TRUE;
+}
+
+STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultActionReal()
+{
+    if (!m_pSubMenu)
+        OnLButtonUp(0, 0);
+    else
+        ShowSubPopup();
+    return TRUE;
+}
+
+STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccDefaultAction()
+{
+    WCHAR szText[64];
+    ::LoadStringW(g_hInst, IDS_LEFTCLICK, szText, _countof(szText));
+    return ::SysAllocString(szText);
+}
+
+STDMETHODIMP_(void) CUTBMenuItem::GetAccLocation(LPRECT lprc)
+{
+    GetRect(lprc);
+    ::ClientToScreen(m_pMenuWnd->m_hWnd, (LPPOINT)lprc);
+    ::ClientToScreen(m_pMenuWnd->m_hWnd, (LPPOINT)&lprc->right);
+}
+
+STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccName()
+{
+    return ::SysAllocString(m_pszMenuItemLeft);
+}
+
+/// @unimplemented
+STDMETHODIMP_(INT) CUTBMenuItem::GetAccRole()
+{
+    if (FALSE) //FIXME
+        return 21;
+    return 12;
+}
+
 /***********************************************************************
  * CTrayIconItem
  */
diff --git a/dll/win32/msutb/precomp.h b/dll/win32/msutb/precomp.h
index 7e880a30d57..2f3ca726f7b 100644
--- a/dll/win32/msutb/precomp.h
+++ b/dll/win32/msutb/precomp.h
@@ -25,8 +25,8 @@
 #include <atlcom.h>
 #include <strsafe.h>
 #undef STATUS_NO_MEMORY
+
+#include "resource.h"
 #include <cicero/cicuif.h>
 
 #include <wine/debug.h>
-
-#include "resource.h"
diff --git a/dll/win32/msutb/resource.h b/dll/win32/msutb/resource.h
index c91662cb293..65532689e47 100644
--- a/dll/win32/msutb/resource.h
+++ b/dll/win32/msutb/resource.h
@@ -7,3 +7,5 @@
 #define IDS_IGNORE          104
 #define IDS_YES             105
 #define IDS_NO              106
+#define IDS_MENUWND         322
+#define IDS_LEFTCLICK       323
diff --git a/sdk/include/reactos/cicero/cicuif.h 
b/sdk/include/reactos/cicero/cicuif.h
index b4715f93263..218587d3296 100644
--- a/sdk/include/reactos/cicero/cicuif.h
+++ b/sdk/include/reactos/cicero/cicuif.h
@@ -617,8 +617,8 @@ public:
     STDMETHOD_(LRESULT, OnSettingChange)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam);
     STDMETHOD_(LRESULT, OnDisplayChange)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam)
         { return 0; }
-    STDMETHOD_(LRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam)
-        { return 0; }
+    STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam)
+        { return S_OK; }
     STDMETHOD_(LRESULT, WindowProc)(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam);
     STDMETHOD_(BOOL, OnEraseBkGnd)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam)
         { return FALSE; }
@@ -786,7 +786,7 @@ protected:
     void DrawUnderline(HDC hDC, INT xText, INT yText, HBRUSH hbr);
 
 public:
-    CUIFMenuItem(CUIFMenu *pMenu, BOOL bDisabled);
+    CUIFMenuItem(CUIFMenu *pMenu, BOOL bDisabled = FALSE);
     ~CUIFMenuItem() override;
 
     BOOL Init(UINT nMenuItemID, LPCWSTR pszText);
@@ -2484,7 +2484,6 @@ inline BOOL cicGetIconBitmaps(HICON hIcon, HBITMAP *hbm1, 
HBITMAP *hbm2, const S
     if (!CUIFBitmapDC::s_fInitBitmapDCs)
         return NULL;
 
-    LONG cx, cy;
     SIZE size;
     if (pSize)
     {
@@ -2496,8 +2495,8 @@ inline BOOL cicGetIconBitmaps(HICON hIcon, HBITMAP *hbm1, 
HBITMAP *hbm2, const S
             return FALSE;
     }
 
-    CUIFBitmapDC::s_phdcSrc->SetDIB(cx, cy, 1, 32);
-    CUIFBitmapDC::s_phdcMask->SetBitmap(cx, cy, 1, 1);
+    CUIFBitmapDC::s_phdcSrc->SetDIB(size.cx, size.cy, 1, 32);
+    CUIFBitmapDC::s_phdcMask->SetBitmap(size.cx, size.cy, 1, 1);
 
     RECT rc = { 0, 0, size.cx, size.cy };
     ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, 
(HBRUSH)GetStockObject(BLACK_BRUSH));
@@ -5177,31 +5176,24 @@ CUIFBalloonWindow::AddButton(UINT nCommandId)
     pButton->Initialize();
     pButton->m_nCommandID = nCommandId;
 
-    LPCWSTR pszText; // FIXME: Use resource strings
+    LPCWSTR pszText;
+#ifdef IDS_OK
+    extern HINSTANCE g_hInst;
+    WCHAR szText[64];
+    ::LoadStringW(g_hInst, IDS_OK + nCommandId, szText, _countof(szText));
+    pszText = szText;
+#else
     switch (nCommandId)
     {
-        case IDOK:
-            pszText = L"OK";
-            break;
-        case IDCANCEL:
-            pszText = L"Cancel";
-            break;
-        case IDABORT:
-            pszText = L"&Abort";
-            break;
-        case IDRETRY:
-            pszText = L"&Retry";
-            break;
-        case IDIGNORE:
-            pszText = L"&Ignore";
-            break;
-        case IDYES:
-            pszText = L"&Yes";
-            break;
-        default:
-            pszText = L"&No";
-            break;
+        case IDOK:      pszText = L"OK";      break;
+        case IDCANCEL:  pszText = L"Cancel";  break;
+        case IDABORT:   pszText = L"&Abort";  break;
+        case IDRETRY:   pszText = L"&Retry";  break;
+        case IDIGNORE:  pszText = L"&Ignore"; break;
+        case IDYES:     pszText = L"&Yes";    break;
+        default:        pszText = L"&No";     break;
     }
+#endif
 
     pButton->SetText(pszText);
 

Reply via email to