Author: gadamopoulos
Date: Mon Apr 17 09:02:49 2017
New Revision: 74345
URL:
http://svn.reactos.org/svn/reactos?rev=74345&view=rev
Log:
[BROWSEUI] -CBandSiteMenu: Add preliminary support for adding and removing bands in the
taskbar. If a class was registered in the CATID_DeskBand category it will be shown in the
menu and selecting it can add it or remove it from the taskbar. Showing the two built in
ones (quick launch and desktop) is not implemented yet.
Modified:
trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.cpp
trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.h
Modified: trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/shellba…
==============================================================================
--- trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.cpp [iso-8859-1] Mon Apr 17
09:02:49 2017
@@ -20,58 +20,189 @@
*/
#include "shellbars.h"
-
-CBandSiteMenu::CBandSiteMenu()
+#include <strsafe.h>
+
+#define IDM_DESKBAND_BEGINCUSTOM 0x10
+#define IDM_DESKBAND_ENDCUSTOM 0x25
+
+CBandSiteMenu::CBandSiteMenu():
+ m_menuDsa(NULL),
+ m_hmenu(NULL)
{
}
CBandSiteMenu::~CBandSiteMenu()
{
+ if (m_hmenu)
+ DestroyMenu(m_hmenu);
+
+ if (m_menuDsa)
+ DSA_Destroy(m_menuDsa);
+
+ m_BandSite = NULL;
+}
+
+
+HRESULT CBandSiteMenu::CreateMenuPart()
+{
+ WCHAR wszBandName[MAX_PATH];
+ WCHAR wszBandGUID[MAX_PATH];
+ WCHAR wRegKey[MAX_PATH];
+ UINT cBands;
+ DWORD dwDataSize;
+ CATID category = CATID_DeskBand;
+ HMENU hmenuToolbars;
+ DWORD dwRead;
+ CComPtr<IEnumGUID> pEnumGUID;
+ HRESULT hr;
+
+ if (m_hmenu)
+ DestroyMenu(m_hmenu);
+
+ if (m_menuDsa)
+ DSA_Destroy(m_menuDsa);
+
+ /* Load the template we will fill in */
+ m_hmenu = LoadMenuW(GetModuleHandleW(L"browseui.dll"),
MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS));
+ if (!m_hmenu)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ m_menuDsa = DSA_Create(sizeof(GUID), 5);
+ if (!m_menuDsa)
+ return E_OUTOFMEMORY;
+
+ /* Get the handle of the submenu where the available items will be shown */
+ hmenuToolbars = GetSubMenu(m_hmenu, 0);
+
+ /* Create the category enumerator */
+ hr = SHEnumClassesOfCategories(1, &category, 0, NULL, &pEnumGUID);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* Enumerate the classes in the CATID_DeskBand category */
+ cBands = 0;
+ do
+ {
+ GUID iter;
+ pEnumGUID->Next(1, &iter, &dwRead);
+ if (!dwRead)
+ continue;
+
+ if (!StringFromGUID2(iter, wszBandGUID, MAX_PATH))
+ continue;
+
+ /* Get the band name */
+ StringCchPrintfW(wRegKey, MAX_PATH, L"CLSID\\%s", wszBandGUID);
+ dwDataSize = MAX_PATH;
+ SHGetValue(HKEY_CLASSES_ROOT, wRegKey, NULL, NULL, wszBandName,
&dwDataSize);
+
+ /* Insert it */
+ InsertMenu(hmenuToolbars, cBands, MF_BYPOSITION, DSA_GetItemCount(m_menuDsa),
wszBandName);
+ DSA_AppendItem(m_menuDsa, &iter);
+ cBands++;
+ }
+ while (dwRead > 0);
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CBandSiteMenu::SetOwner(IUnknown *pOwner)
{
TRACE("CBandSiteMenu::SetOwner(%p, %p)\n", this, pOwner);
- m_Owner = pOwner;
- return S_OK;
+
+ /* Cache the menu that will be merged every time QueryContextMenu is called */
+ CreateMenuPart();
+
+ return pOwner->QueryInterface(IID_PPV_ARG(IBandSite, &m_BandSite));
}
HRESULT STDMETHODCALLTYPE CBandSiteMenu::QueryContextMenu(
HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
- BOOL ret;
- WCHAR buffer[100];
+ CComPtr<IPersist> pBand;
+ CLSID BandCLSID;
+ DWORD dwBandID;
+ UINT uBand = 0;
TRACE("CBandSiteMenu::QueryContextMenu(%p, %p, %u, %u, %u, 0x%x)\n", this,
hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
- HMENU hm = LoadMenuW(_AtlBaseModule.GetResourceInstance(),
MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS));
- if (!hm)
- return HRESULT_FROM_WIN32(GetLastError());
-
- MENUITEMINFOW mii = { 0 };
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU;
- ret = GetMenuItemInfoW(hm, 0, TRUE, &mii);
- if (!hm)
- return HRESULT_FROM_WIN32(GetLastError());
-
- mii.dwTypeData = buffer;
- mii.cch = mii.cch + 1;
-
- ret = GetMenuItemInfoW(hm, 0, TRUE, &mii);
- if (!hm)
- return HRESULT_FROM_WIN32(GetLastError());
-
- ret = InsertMenuItemW(hmenu, 0, TRUE, &mii);
-
- RemoveMenu(hm, 0, MF_BYPOSITION);
-
- return E_NOTIMPL;
+ /* First Merge the menu with the available bands */
+ Shell_MergeMenus(hmenu, m_hmenu, indexMenu, idCmdFirst, idCmdLast, MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS);
+
+ HMENU hmenuToolbars = GetSubMenu(hmenu, indexMenu);
+
+ /* Enumerate all present bands and mark them as checked in the menu */
+ while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
+ {
+ if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist,
&pBand))))
+ continue;
+
+ if (FAILED(pBand->GetClassID(&BandCLSID)))
+ continue;
+
+ /* Try to find the clsid of the band in the dsa */
+ UINT count = DSA_GetItemCount(m_menuDsa);
+ for (UINT i = 0; i < count; i++)
+ {
+ GUID* pdsaGUID = (GUID*)DSA_GetItemPtr(m_menuDsa, i);
+ if (memcmp(pdsaGUID, &BandCLSID, sizeof(GUID)) == 0)
+ {
+ /* The index in the dsa is also the index in the menu */
+ CheckMenuItem(hmenuToolbars, i, MF_CHECKED | MF_BYPOSITION);
+ }
+ }
+
+ uBand++;
+ }
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
- FIXME("CBandSiteMenu::InvokeCommand is UNIMPLEMENTED (%p, %p)\n", this,
lpici);
+ /* FIXME: do we need to handle this and how? */
+ if (HIWORD(lpici->lpVerb) != NULL)
+ return E_FAIL;
+
+ /* Get the GUID of the item that was clicked */
+ UINT uID = LOWORD(lpici->lpVerb);
+ GUID *pguidToolbar = (GUID *)DSA_GetItemPtr(m_menuDsa, uID);
+ if (!pguidToolbar)
+ return E_FAIL;
+
+ /* Try to find if a band with a guid is present. If it is remove it and return */
+ CComPtr<IPersist> pBand;
+ CLSID BandCLSID;
+ DWORD dwBandID;
+ UINT uBand = 0;
+ while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
+ {
+ if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist,
&pBand))))
+ continue;
+
+ if (FAILED(pBand->GetClassID(&BandCLSID)))
+ continue;
+
+ if (memcmp(pguidToolbar, &BandCLSID, sizeof(GUID)) == 0)
+ {
+ /* We found it, remove it */
+ m_BandSite->RemoveBand(dwBandID);
+ return S_OK;
+ }
+
+ uBand++;
+ }
+
+ /* It is not present. Add it. */
+ CComPtr<IDeskBand> pDeskBand;
+ HRESULT hRet = CoCreateInstance(*pguidToolbar, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IDeskBand, &pDeskBand));
+ if (FAILED(hRet))
+ return hRet;
+
+ hRet = m_BandSite->AddBand(pDeskBand);
+ if (FAILED_UNEXPECTEDLY(hRet))
+ return hRet;
+
return S_OK;
}
Modified: trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/shellba…
==============================================================================
--- trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/browseui/shellbars/CBandSiteMenu.h [iso-8859-1] Mon Apr 17
09:02:49 2017
@@ -28,7 +28,12 @@
public IContextMenu3,
public IShellService
{
- CComPtr<IUnknown> m_Owner;
+ CComPtr<IBandSite> m_BandSite;
+ HDSA m_menuDsa;
+ HMENU m_hmenu;
+
+ HRESULT CreateMenuPart();
+
public:
CBandSiteMenu();
~CBandSiteMenu();