https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1001b59a06ae73f39a5dc…
commit 1001b59a06ae73f39a5dc779e8ba81c06bd2389d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Jan 29 18:38:59 2024 +0900
Commit: GitHub <noreply(a)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);