https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d6caac30567dfee433d1c…
commit d6caac30567dfee433d1c5ef8dce182b4106e97f
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Jan 27 14:06:25 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Jan 27 14:06:25 2024 +0900
[MSUTB] Add CCicLibMenu and CCicLibMenuItem (#6414)
Supporting Language Bar...
JIRA issue: CORE-19363
- Implement CCicLibMenu and
CCicLibMenuItem classes.
---
dll/win32/msutb/msutb.cpp | 253 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 253 insertions(+)
diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp
index ec7e1ea24cb..1283165d078 100644
--- a/dll/win32/msutb/msutb.cpp
+++ b/dll/win32/msutb/msutb.cpp
@@ -30,6 +30,62 @@ END_OBJECT_MAP()
CMsUtbModule gModule;
+class CCicLibMenuItem;
+
+/***********************************************************************/
+
+class CCicLibMenu : public ITfMenu
+{
+public:
+ CicArray<CCicLibMenuItem*> m_MenuItems;
+ LONG m_cRefs;
+
+public:
+ CCicLibMenu();
+ virtual ~CCicLibMenu();
+
+ STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj) override;
+ STDMETHOD_(ULONG, AddRef)() override;
+ STDMETHOD_(ULONG, Release)() override;
+ STDMETHOD(AddMenuItem)(
+ UINT uId,
+ DWORD dwFlags,
+ HBITMAP hbmp,
+ HBITMAP hbmpMask,
+ const WCHAR *pch,
+ ULONG cch,
+ ITfMenu **ppSubMenu) override;
+ STDMETHOD_(CCicLibMenu*, CreateSubMenu)();
+ STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)();
+};
+
+/***********************************************************************/
+
+class CCicLibMenuItem
+{
+public:
+ DWORD m_uId;
+ DWORD m_dwFlags;
+ HBITMAP m_hbmp;
+ HBITMAP m_hbmpMask;
+ BSTR m_bstrText;
+ ITfMenu *m_pMenu;
+
+public:
+ CCicLibMenuItem();
+ virtual ~CCicLibMenuItem();
+
+ BOOL Init(
+ UINT uId,
+ DWORD dwFlags,
+ HBITMAP hbmp,
+ HBITMAP hbmpMask,
+ const WCHAR *pch,
+ ULONG cch,
+ ITfMenu *pMenu);
+ HBITMAP CreateBitmap(HANDLE hBitmap);
+};
+
/***********************************************************************/
class CTrayIconWnd
@@ -66,6 +122,203 @@ protected:
STDMETHOD_(LRESULT, OnDelayMsg)(LPARAM lParam) { return 0; };
};
+/***********************************************************************
+ * CCicLibMenu
+ */
+
+CCicLibMenu::CCicLibMenu() : m_cRefs(1)
+{
+}
+
+CCicLibMenu::~CCicLibMenu()
+{
+ for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem)
+ {
+ delete m_MenuItems[iItem];
+ m_MenuItems[iItem] = NULL;
+ }
+}
+
+STDMETHODIMP CCicLibMenu::QueryInterface(REFIID riid, LPVOID *ppvObj)
+{
+ if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfMenu))
+ {
+ *ppvObj = this;
+ AddRef();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) CCicLibMenu::AddRef()
+{
+ return ++m_cRefs;
+}
+
+STDMETHODIMP_(ULONG) CCicLibMenu::Release()
+{
+ if (--m_cRefs == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return m_cRefs;
+}
+
+STDMETHODIMP_(CCicLibMenu*) CCicLibMenu::CreateSubMenu()
+{
+ return new(cicNoThrow) CCicLibMenu();
+}
+
+STDMETHODIMP_(CCicLibMenuItem*) CCicLibMenu::CreateMenuItem()
+{
+ return new(cicNoThrow) CCicLibMenuItem();
+}
+
+STDMETHODIMP CCicLibMenu::AddMenuItem(
+ UINT uId,
+ DWORD dwFlags,
+ HBITMAP hbmp,
+ HBITMAP hbmpMask,
+ const WCHAR *pch,
+ ULONG cch,
+ ITfMenu **ppSubMenu)
+{
+ if (ppSubMenu)
+ *ppSubMenu = NULL;
+
+ CCicLibMenu *pSubMenu = NULL;
+ if (dwFlags & TF_LBMENUF_SUBMENU)
+ {
+ if (!ppSubMenu)
+ return E_INVALIDARG;
+ pSubMenu = CreateSubMenu();
+ }
+
+ CCicLibMenuItem *pMenuItem = CreateMenuItem();
+ if (!pMenuItem)
+ return E_OUTOFMEMORY;
+
+ if (!pMenuItem->Init(uId, dwFlags, hbmp, hbmpMask, pch, cch, pSubMenu))
+ return E_FAIL;
+
+ if (ppSubMenu && pSubMenu)
+ {
+ *ppSubMenu = pSubMenu;
+ pSubMenu->AddRef();
+ }
+
+ *m_MenuItems.Append(1) = pMenuItem;
+ return S_OK;
+}
+
+/***********************************************************************
+ * CCicLibMenuItem
+ */
+
+CCicLibMenuItem::CCicLibMenuItem()
+{
+ m_uId = 0;
+ m_dwFlags = 0;
+ m_hbmp = NULL;
+ m_hbmpMask = NULL;
+ m_bstrText = NULL;
+ m_pMenu = NULL;
+}
+
+CCicLibMenuItem::~CCicLibMenuItem()
+{
+ if (m_pMenu)
+ {
+ m_pMenu->Release();
+ m_pMenu = NULL;
+ }
+
+ if (m_hbmp)
+ {
+ ::DeleteObject(m_hbmp);
+ m_hbmp = NULL;
+ }
+
+ if (m_hbmpMask)
+ {
+ ::DeleteObject(m_hbmpMask);
+ m_hbmpMask = NULL;
+ }
+
+ ::SysFreeString(m_bstrText);
+ m_bstrText = NULL;
+}
+
+BOOL CCicLibMenuItem::Init(
+ UINT uId,
+ DWORD dwFlags,
+ HBITMAP hbmp,
+ HBITMAP hbmpMask,
+ const WCHAR *pch,
+ ULONG cch,
+ ITfMenu *pMenu)
+{
+ m_uId = uId;
+ m_dwFlags = dwFlags;
+ m_bstrText = ::SysAllocStringLen(pch, cch);
+ if (!m_bstrText && cch)
+ return FALSE;
+
+ m_pMenu = pMenu;
+ m_hbmp = CreateBitmap(hbmp);
+ m_hbmpMask = CreateBitmap(hbmpMask);
+ if (hbmp)
+ ::DeleteObject(hbmp);
+ if (hbmpMask)
+ ::DeleteObject(hbmpMask);
+
+ return TRUE;
+}
+
+HBITMAP CCicLibMenuItem::CreateBitmap(HANDLE hBitmap)
+{
+ if (!hBitmap)
+ return NULL;
+
+ HDC hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+ if (!hDC)
+ return NULL;
+
+ HBITMAP hbmMem = NULL;
+
+ BITMAP bm;
+ ::GetObject(hBitmap, sizeof(bm), &bm);
+
+ HGDIOBJ hbmOld1 = NULL;
+ HDC hdcMem1 = ::CreateCompatibleDC(hDC);
+ if (hdcMem1)
+ hbmOld1 = ::SelectObject(hdcMem1, hBitmap);
+
+ HGDIOBJ hbmOld2 = NULL;
+ HDC hdcMem2 = ::CreateCompatibleDC(hDC);
+ if (hdcMem2)
+ {
+ hbmMem = ::CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight);
+ hbmOld2 = ::SelectObject(hdcMem2, hbmMem);
+ }
+
+ ::BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
+
+ if (hbmOld1)
+ ::SelectObject(hdcMem1, hbmOld1);
+ if (hbmOld2)
+ ::SelectObject(hdcMem2, hbmOld2);
+
+ ::DeleteDC(hDC);
+ if (hdcMem1)
+ ::DeleteDC(hdcMem1);
+ if (hdcMem2)
+ ::DeleteDC(hdcMem2);
+
+ return hbmMem;
+}
+
/***********************************************************************
* CTrayIconItem
*/